-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathecmwf.py
100 lines (78 loc) · 2.82 KB
/
ecmwf.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import urllib
import urllib2
import time
import datetime
class ECMWFDataServer:
def __init__(self,portal,token,email):
self.version = '0.3'
self.portal = portal
self.token = token
self.email = email
def _call(self,action,args):
params = {'_token' : self.token,
'_email' : self.email,
'_action' : action,
'_version' : self.version}
params.update(args)
data = urllib.urlencode(params)
req = urllib2.Request(self.portal, data)
response = urllib2.urlopen(req)
json = response.read();
undef = None;
json = eval(json)
if json != None:
if 'error' in json:
raise RuntimeError(json['error'])
if 'message' in json:
self.put(json['message'])
return json
def put(self,*args):
print (datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')),
for a in args:
print (a),
print ( )
def retrieve(self,args):
self.put("ECMWF data server batch tool version",self.version);
user = self._call("user_info",{});
self.put("Welcome to",user['name'], "from" , user['organisation']);
r = self._call('retrieve',args)
rid = r['request']
last = ''
sleep = 0
while r['status'] != 'complete' and r['status'] != 'aborted':
text = r['status'] + '.'
if 'info' in r and r['info'] != None:
text = text + ' ' + r['info']
if text != last:
self.put("Request",text)
last = text
time.sleep(sleep)
r = self._call('status',{'request':rid})
if sleep < 60:
sleep = sleep + 1
if r['status'] != last:
self.put("Request",r['status'])
if 'reason' in r:
for m in r['reason']:
self.put(m)
if 'result' in r:
size = long(r['size'])
self.put("Downloading",self._bytename(size))
done = self._transfer(r['result'],args['target'])
self.put("Done")
if done != size:
raise RuntimeError("Size mismatch: " + str(done) + " and " + str(size))
self._call('delete',{'request':rid})
if r['status'] == 'aborted':
raise RuntimeError("Request aborted")
def _transfer(self,url,path):
result = urllib.urlretrieve(url,path)
return long(result[1]['content-length'])
def _bytename(self,size):
next = {'':'K','K':'M','M':'G','G':'T','T':'P'}
l = ''
size = size*1.0
while 1024 < size:
l = next[l]
size = size / 1024
return "%g %sbyte%s" % (size,l,'s')