Skip to content

Instantly share code, notes, and snippets.

@shibacow
Created June 19, 2017 11:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shibacow/416c3685f7db41cdeb105e4c89c54fdc to your computer and use it in GitHub Desktop.
Save shibacow/416c3685f7db41cdeb105e4c89c54fdc to your computer and use it in GitHub Desktop.
get aws ec2 spot instance price
#!/usr/bin/env python
# -coding:utf-8 -*-
import requests
import re
import json
from pprint import pprint
import subprocess
import sys
import os
from datetime import datetime
import logging
logging.basicConfig(level=logging.INFO)
split=["t1.micro","t2.nano","t2.micro","t2.small","t2.medium","t2.large","t2.xlarge","t2.2xlarge","m1.small","m1.medium","m1.large","m1.xlarge","\
m3.medium","m3.large","m3.xlarge","m3.2xlarge","m4.large","m4.xlarge","m4.2xlarge","m4.4xlarge","m4.10xlarge","m4.16xlarge","m2.xlarge","m2.2xlar\
ge","m2.4xlarge","cr1.8xlarge","r3.large","r3.xlarge","r3.2xlarge","r3.4xlarge","r3.8xlarge","r4.large","r4.xlarge","r4.2xlarge","r4.4xlarge","r4\
.8xlarge","r4.16xlarge","x1.16xlarge","x1.32xlarge","i2.xlarge","i2.2xlarge","i2.4xlarge","i2.8xlarge","i3.large","i3.xlarge","i3.2xlarge","i3.4x\
large","i3.8xlarge","i3.16xlarge","hi1.4xlarge","hs1.8xlarge","c1.medium","c1.xlarge","c3.large","c3.xlarge","c3.2xlarge","c3.4xlarge","c3.8xlarg\
e","c4.large","c4.xlarge","c4.2xlarge","c4.4xlarge","c4.8xlarge","cc1.4xlarge","cc2.8xlarge","g2.2xlarge","g2.8xlarge","cg1.4xlarge","p2.xlarge",\
"p2.8xlarge","p2.16xlarge","d2.xlarge","d2.2xlarge","d2.4xlarge","d2.8xlarge","f1.2xlarge","f1.16xlarge"]
regionlist=["us-east-1","us-east-2","us-west-1","us-west-2","ca-central-1","eu-west-1","eu-central-1","eu-west-2","ap-northeast-1","ap-northeast-\
2","ap-southeast-1","ap-southeast-2","ap-south-1","sa-east-1"]
def get_json(url):
j = requests.get(url).content
if 'callback(' in j:
j = j.split('callback(')[1][:-2]
j = re.sub(r"{\s*(\w)", r'{"\1', j)
j = re.sub(r",\s*(\w)", r',"\1', j)
j = re.sub(r"(\w):", r'\1":', j)
return json.loads(j)
class MPResion(object):
def __get_price(self,p):
assert(len(p)==1)
return float(p[0]['prices']['USD'])
def __parseItype(self,l):
for c in l:
for s in c['sizes']:
p=self.__get_price(s['valueColumns'])
self.dkt[s['size']]=p
def __init__(self,d):
self.region=d['region']
self.dkt={}
self.__parseItype(d['instanceTypes'])
def __str__(self):
return "resgion={} price={}".format(self.region,str(self.dkt))
def build(d,pdict):
c=d['config']
mplist=[]
for r in c['regions']:
mp=MPResion(r)
mplist.append(mp)
for m in mplist:
for k,v in m.dkt.items():
pdict.setdefault(k,{})
pdict[k][m.region]=v
class SpElm(object):
def __init__(self,s,op,itype):
self.itype=itype
self.tm=s['Timestamp'].split('.')[0]
self.sp=float(s['SpotPrice'])
self.av=s['AvailabilityZone']
self.op=op
def to_csv(self):
rate=self.sp/self.op
return ",".join([self.itype,self.av,str(self.op),str(self.sp),str(rate)])
def __repr__(self):
rate=self.sp/self.op
rate="{0:.3f}".format(rate)
return "\titype={} time={} av={} op={} sp={} rate={}".format(self.itype,self.tm,self.av,self.op,self.sp,rate)
class InstanceType(object):
def __cmd(self,k,z):
my_env=os.environ.copy()
my_env['AWS_DEFAULT_REGION']=z
pd="Linux/UNIX"
pd2="Linux/UNIX (Amazon VPC)"
cmd='aws ec2 describe-spot-price-history --instance-types {} --product-descriptions "{}" --start-time="2017-06-15T00:00:00Z" --end-time="2017-06-19T00:00:00Z"'.format(k,pd2)
#logging.info(cmd)
out=subprocess.check_output(cmd,shell=True,env=my_env)
#logging.info(out)
return json.loads(out)
def __parse(self,d,op,itype):
tst={}
for t in d['SpotPriceHistory']:
sp=SpElm(t,op,itype)
tst.setdefault(sp.av,[])
tst[sp.av].append(sp)
tout={}
for k,v in tst.items():
tt=sorted(v,key=lambda x:x.tm,reverse=True)
if tt:
tout[k]=tt[0]
return tout
def __init__(self,k,pdict,regionlist):
self.itype=k
for z0 in regionlist:
logging.debug(z0)
d=self.__cmd(self.itype,z0)
#print(pdict)
op=pdict.get(z0,0)
tout=self.__parse(d,op,self.itype)
for k,v in tout.items():
#print(k)
#logging.info(v.to_csv())
print(v.to_csv())
def result(pdict):
kd=r'^p2|^g2'
kd=r'^t2'
kd=r'^m4'
kd=r'^c4'
for k in sorted(pdict.keys()):
if not re.search(kd,k):
continue
if k in split:
logging.debug(k)
v=pdict[k]
i=InstanceType(k,v,regionlist)
#print(k)
#for r,v in sorted(pdict[k].items(),key=lambda x:x[1]):
# print "\t\t resion={},price={}".format(r,v)
def avaivalzone():
zl=[]
for r in regionlist[:3]:
cmd="aws ec2 describe-availability-zones --region {}".format(r)
out=subprocess.check_output(cmd,shell=True)
d=json.loads(out)
for z in d['AvailabilityZones']:
if z['State']=='available':
zl.append(z['ZoneName'])
return zl
def parse():
pdict={}
src='http://a0.awsstatic.com/pricing/1/ec2/linux-od.min.js'
d=get_json(src)
build(d,pdict)
src='https://a0.awsstatic.com/pricing/1/ec2/previous-generation/linux-od.min.js'
d=get_json(src)
build(d,pdict)
return pdict
#result(pdict)
def main():
#zone=avaivalzone()
pdict=parse()
result(pdict)
if __name__=='__main__':main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment