Created
June 19, 2017 11:17
-
-
Save shibacow/416c3685f7db41cdeb105e4c89c54fdc to your computer and use it in GitHub Desktop.
get aws ec2 spot instance price
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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