apccapi 0.0.1__tar.gz → 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,84 +1,96 @@
1
- Metadata-Version: 2.1
2
- Name: apccapi
3
- Version: 0.0.1
4
- Summary: APCC Climate Information toolKit API package
5
- Home-page: https://www.apcc21.org
6
- Author: APEC Climate Center
7
- Author-email: joohyung@apcc21.org
8
- Project-URL: CLIK, https://cliks.apcc21.org
9
- Keywords: APCC,apcc,Climate,Climate Information,Climate API
10
- Classifier: Programming Language :: Python :: 3
11
- Classifier: License :: OSI Approved :: MIT License
12
- Classifier: Operating System :: OS Independent
13
- Requires-Python: >=3.6
14
- Description-Content-Type: text/markdown
15
- License-File: LICENSE
16
- Requires-Dist: requests
17
- Requires-Dist: urllib3
18
-
19
- ## Installation
20
-
21
- Install via pip with:
22
-
23
- ```bash
24
- $ pip install apccapi
25
- ```
26
-
27
- ## Configure (Linux)
28
-
29
- Obtain your API key from the CLIK (Climate Information toolKit) at https://cliks.apcc21.org and enter it into the apccapi.properties file, formatting it as follows:
30
-
31
- ```
32
- $ vi ~/.apccapi.properties
33
-
34
- key={your API key}
35
- request_url=https://request.apcc21.org/apccdata
36
- status_url=https://request.apcc21.org/status
37
- ```
38
-
39
- ## Configure (Windows)
40
-
41
- Obtain your API key from the CLIK (Climate Information toolKit) at https://cliks.apcc21.org, and create the apccapi.properties file in your Windows Home directory (typically C:\Users\YourUserName) with the following format:
42
-
43
- ```
44
- key={your API key}
45
- request_url=https://request.apcc21.org/apccdata
46
- status_url=https://request.apcc21.org/status
47
- ```
48
-
49
- ## Test
50
-
51
- Perform a small test retrieve of MME data:
52
- ```
53
- $ python
54
- >>> import apccapi
55
- >>> c = apccapi.Client()
56
- >>> c.retrieve(
57
- {
58
- 'jobtype': 'MME',
59
- 'dataset': 'MME_3MONTH',
60
- 'type': 'FORECAST',
61
- 'method': 'SCM',
62
- 'variable': ['prec', 't2m'],
63
- 'period': ['Monthly mean'],
64
- 'yearmonth': ['201909']
65
- },
66
- 'mme3.zip'
67
- )
68
- >>>
69
-
70
- ```
71
-
72
- ## License
73
-
74
- MIT License
75
-
76
- Copyright (c) 2019 - 2024, APEC Climate Center
77
-
78
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
79
- copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
80
-
81
- The above copyright notice and this permission notice shall be included in all
82
- copies or substantial portions of the Software.
83
-
84
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1
+ Metadata-Version: 2.4
2
+ Name: apccapi
3
+ Version: 0.1.0
4
+ Summary: APCC Climate Information toolKit API package
5
+ Home-page: https://www.apcc21.org
6
+ Author: APEC Climate Center
7
+ Author-email: joohyung@apcc21.org
8
+ Project-URL: CLIK, https://apcc21.org/clik/
9
+ Keywords: APCC,apcc,Climate,Climate Information,Climate API
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Operating System :: OS Independent
13
+ Requires-Python: >=3.6
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE
16
+ Requires-Dist: requests
17
+ Requires-Dist: urllib3<2
18
+ Dynamic: author
19
+ Dynamic: author-email
20
+ Dynamic: classifier
21
+ Dynamic: description
22
+ Dynamic: description-content-type
23
+ Dynamic: home-page
24
+ Dynamic: keywords
25
+ Dynamic: license-file
26
+ Dynamic: project-url
27
+ Dynamic: requires-dist
28
+ Dynamic: requires-python
29
+ Dynamic: summary
30
+
31
+ ## Installation
32
+
33
+ Install via pip with:
34
+
35
+ ```bash
36
+ $ pip install apccapi
37
+ ```
38
+
39
+ ## Configure (Linux)
40
+
41
+ Obtain your API key from the CLIK (Climate Information toolKit) at https://apcc21.org/clik/ and enter it into the apccapi.properties file, formatting it as follows:
42
+
43
+ ```
44
+ $ vi ~/apccapi.properties
45
+
46
+ key={your API key}
47
+ request_url=https://apcc21.org/clikapi/request/apccdata
48
+ status_url=https://apcc21.org/clikapi/request/status
49
+ ```
50
+
51
+ ## Configure (Windows)
52
+
53
+ Obtain your API key from the CLIK (Climate Information toolKit) at https://apcc21.org/clik/, and create the apccapi.properties file in your Windows Home directory (typically C:\Users\YourUserName) with the following format:
54
+
55
+ ```
56
+ key={your API key}
57
+ request_url=https://apcc21.org/clikapi/request/apccdata
58
+ status_url=https://apcc21.org/clikapi/request/status
59
+ ```
60
+
61
+ ## Test
62
+
63
+ Perform a small test retrieve of MME data:
64
+ ```
65
+ $ python
66
+ >>> import apccapi
67
+ >>> c = apccapi.Client()
68
+ >>> c.retrieve(
69
+ {
70
+ 'jobtype': 'MME',
71
+ 'dataset': 'MME_3MONTH',
72
+ 'type': 'FORECAST',
73
+ 'method': 'SCM',
74
+ 'variable': ['prec', 't2m'],
75
+ 'period': ['Monthly mean'],
76
+ 'yearmonth': ['201909']
77
+ },
78
+ 'mme3.zip'
79
+ )
80
+ >>>
81
+
82
+ ```
83
+
84
+ ## License
85
+
86
+ MIT License
87
+
88
+ Copyright (c) 2019 - 2024, APEC Climate Center
89
+
90
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
91
+ copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
92
+
93
+ The above copyright notice and this permission notice shall be included in all
94
+ copies or substantial portions of the Software.
95
+
96
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -8,24 +8,24 @@ $ pip install apccapi
8
8
 
9
9
  ## Configure (Linux)
10
10
 
11
- Obtain your API key from the CLIK (Climate Information toolKit) at https://cliks.apcc21.org and enter it into the apccapi.properties file, formatting it as follows:
11
+ Obtain your API key from the CLIK (Climate Information toolKit) at https://apcc21.org/clik/ and enter it into the apccapi.properties file, formatting it as follows:
12
12
 
13
13
  ```
14
- $ vi ~/.apccapi.properties
14
+ $ vi ~/apccapi.properties
15
15
 
16
16
  key={your API key}
17
- request_url=https://request.apcc21.org/apccdata
18
- status_url=https://request.apcc21.org/status
17
+ request_url=https://apcc21.org/clikapi/request/apccdata
18
+ status_url=https://apcc21.org/clikapi/request/status
19
19
  ```
20
20
 
21
21
  ## Configure (Windows)
22
22
 
23
- Obtain your API key from the CLIK (Climate Information toolKit) at https://cliks.apcc21.org, and create the apccapi.properties file in your Windows Home directory (typically C:\Users\YourUserName) with the following format:
23
+ Obtain your API key from the CLIK (Climate Information toolKit) at https://apcc21.org/clik/, and create the apccapi.properties file in your Windows Home directory (typically C:\Users\YourUserName) with the following format:
24
24
 
25
25
  ```
26
26
  key={your API key}
27
- request_url=https://request.apcc21.org/apccdata
28
- status_url=https://request.apcc21.org/status
27
+ request_url=https://apcc21.org/clikapi/request/apccdata
28
+ status_url=https://apcc21.org/clikapi/request/status
29
29
  ```
30
30
 
31
31
  ## Test
@@ -0,0 +1,16 @@
1
+ from .client import (
2
+ Client,
3
+ ClikApiError,
4
+ download_MME_3MONTH,
5
+ download_MME_6MONTH,
6
+ download_MME_MODEL,
7
+ download_CMIP5,
8
+ download_ERA5,
9
+ download_NCEP1,
10
+ download_NCEP2,
11
+ )
12
+ from .clipping import ClippingClient
13
+ from . import clipping
14
+
15
+ __version__ = '0.1.0'
16
+ __author__ = 'APEC Climate Center'
@@ -3,21 +3,23 @@ import time
3
3
  import os
4
4
  import requests
5
5
  import logging
6
- import urllib3
6
+
7
+ class ClikApiError(Exception):
8
+ pass
7
9
 
8
10
  def read_config(path):
9
11
  config = {}
10
12
  with open(path) as f:
11
13
  for l in f.readlines():
12
14
  if '=' in l:
13
- k, v = l.strip().split('=')
15
+ k, v = l.strip().split('=', 1)
14
16
  if k in ('request_url', 'key', 'status_url'):
15
17
  config[k] = v.strip()
16
18
  return config
17
19
 
18
20
  def download_MME_3MONTH(request, output_zipfile_name):
19
21
  client = Client()
20
- client.retrieve(
22
+ return client.retrieve(
21
23
  {
22
24
  'jobtype': 'MME',
23
25
  'dataset': 'MME_3MONTH',
@@ -29,11 +31,10 @@ def download_MME_3MONTH(request, output_zipfile_name):
29
31
  },
30
32
  output_zipfile_name
31
33
  )
32
- return output_zipfile_name
33
34
 
34
35
  def download_MME_6MONTH(request, output_zipfile_name):
35
36
  client = Client()
36
- client.retrieve(
37
+ return client.retrieve(
37
38
  {
38
39
  'jobtype': 'MME',
39
40
  'dataset': 'MME_6MONTH',
@@ -45,11 +46,10 @@ def download_MME_6MONTH(request, output_zipfile_name):
45
46
  },
46
47
  output_zipfile_name
47
48
  )
48
- return output_zipfile_name
49
49
 
50
50
  def download_MME_MODEL(request, output_zipfile_name):
51
51
  client = Client()
52
- client.retrieve(
52
+ return client.retrieve(
53
53
  {
54
54
  'jobtype': 'MODEL',
55
55
  'dataset': 'MODEL',
@@ -61,11 +61,10 @@ def download_MME_MODEL(request, output_zipfile_name):
61
61
  },
62
62
  output_zipfile_name
63
63
  )
64
- return output_zipfile_name
65
64
 
66
65
  def download_CMIP5(request, output_zipfile_name):
67
66
  client = Client()
68
- client.retrieve(
67
+ return client.retrieve(
69
68
  {
70
69
  'jobtype': 'CMIP5',
71
70
  'dataset': 'CMIP5',
@@ -73,7 +72,50 @@ def download_CMIP5(request, output_zipfile_name):
73
72
  },
74
73
  output_zipfile_name
75
74
  )
76
- return output_zipfile_name
75
+
76
+ def download_ERA5(request, output_zipfile_name):
77
+ # request: timestep ('DAILY'|'MONTHLY'|'HOURLY'), level ('pressure'|'single'),
78
+ # variable, year (YYYY), month (MM) - required for DAILY/HOURLY, omitted for MONTHLY
79
+ client = Client()
80
+ payload = {
81
+ 'jobtype': 'ERA5',
82
+ 'dataset': 'ERA5',
83
+ 'timestep': request['timestep'],
84
+ 'level': request['level'],
85
+ 'variable': request['variable'],
86
+ 'year': request['year']
87
+ }
88
+ if request['timestep'] != 'MONTHLY':
89
+ payload['month'] = request['month']
90
+ return client.retrieve(payload, output_zipfile_name)
91
+
92
+ def download_NCEP1(request, output_zipfile_name):
93
+ # request: timestep ('DAILY'|'MONTHLY'), level, variable, year (YYYY) - required for DAILY only
94
+ client = Client()
95
+ payload = {
96
+ 'jobtype': 'NCEP1',
97
+ 'dataset': 'NCEP1',
98
+ 'timestep': request['timestep'],
99
+ 'level': request['level'],
100
+ 'variable': request['variable']
101
+ }
102
+ if request['timestep'] == 'DAILY':
103
+ payload['year'] = request['year']
104
+ return client.retrieve(payload, output_zipfile_name)
105
+
106
+ def download_NCEP2(request, output_zipfile_name):
107
+ # request: timestep ('DAILY'|'MONTHLY'), level, variable, year (YYYY) - required for DAILY only
108
+ client = Client()
109
+ payload = {
110
+ 'jobtype': 'NCEP2',
111
+ 'dataset': 'NCEP2',
112
+ 'timestep': request['timestep'],
113
+ 'level': request['level'],
114
+ 'variable': request['variable']
115
+ }
116
+ if request['timestep'] == 'DAILY':
117
+ payload['year'] = request['year']
118
+ return client.retrieve(payload, output_zipfile_name)
77
119
 
78
120
  class Client(object):
79
121
  logger = logging.getLogger('apccapi')
@@ -98,25 +140,22 @@ class Client(object):
98
140
  logging.basicConfig(level=level,
99
141
  format='[%(asctime)s] [%(levelname)s] %(message)s')
100
142
 
101
- self.requesturl = None
143
+ self.request_url = None
102
144
  self.key = None
103
- self.statusurl = None
145
+ self.status_url = None
104
146
 
105
- urllib3.disable_warnings()
106
-
107
- propertyFile = os.path.join(os.path.expanduser('~'), 'apccapi.properties')
108
- self.debug(propertyFile)
147
+ property_file = os.path.join(os.path.expanduser('~'), 'apccapi.properties')
148
+ self.debug(property_file)
109
149
 
110
- if self.requesturl is None or self.key is None or self.statusurl is None:
111
- if os.path.exists(propertyFile):
112
- config = read_config(propertyFile)
150
+ if os.path.exists(property_file):
151
+ config = read_config(property_file)
113
152
 
114
- self.key = config.get('key')
115
- self.requesturl = config.get('request_url')
116
- self.statusurl = config.get('status_url')
153
+ self.key = config.get('key')
154
+ self.request_url = config.get('request_url')
155
+ self.status_url = config.get('status_url')
117
156
 
118
- if self.requesturl is None or self.key is None or self.statusurl is None:
119
- raise Exception('Missing/incomplete properties file: %s' % (propertyFile))
157
+ if self.request_url is None or self.key is None or self.status_url is None:
158
+ raise ClikApiError('Missing/incomplete properties file: %s' % (property_file))
120
159
 
121
160
 
122
161
  def retrieve(self, details, target):
@@ -127,20 +166,17 @@ class Client(object):
127
166
 
128
167
  self.target = target
129
168
 
130
- try:
131
- response = self.post_api(self.requesturl, request)
132
- print(response)
133
- reply = response.json()
134
- status_code = reply['status']
135
- message = reply['message']
136
- except Exception:
137
- # self.debug(response.text)
138
- raise
139
-
169
+ response = self.post_api(self.request_url, request)
170
+ if response is None:
171
+ raise ClikApiError('Failed to submit request after %s attempts' % self.retry_max)
172
+
173
+ reply = response.json()
174
+ status_code = reply['status']
175
+ message = reply['message']
176
+
140
177
  if status_code > 202:
141
178
  info = reply['data']['info']
142
- self.error(message + "-" + info)
143
- return None
179
+ raise ClikApiError(message + ": " + info)
144
180
 
145
181
  sleep = 0
146
182
  jobid = None
@@ -163,34 +199,33 @@ class Client(object):
163
199
  self.debug("Done")
164
200
  result = self.download(reply['data']['download_url'], self.target)
165
201
  if result is False:
166
- self.error('Failed to download result file.')
202
+ raise ClikApiError('Failed to download result file: %s' % self.target)
167
203
 
168
- return
204
+ return self.target
169
205
 
170
206
  if reply['data']['status'] == 'Queued' or reply['data']['status'] == 'Running':
171
207
  self.debug("Request ID is %s, sleep %s", jobid, sleep)
172
208
  time.sleep(3)
173
- sleep += 3;
209
+ sleep += 3
174
210
 
175
211
  if sleep > self.sleep_max:
176
212
  sleep = self.sleep_max
177
213
 
178
- status_url = '%s/%s' % (self.statusurl, jobid)
214
+ status_url = '%s/%s' % (self.status_url, jobid)
179
215
  self.debug("GET %s", status_url)
180
216
 
181
- try:
182
- response = self.get_api(status_url)
183
- reply = response.json()
184
- except Exception:
185
- self.debug("Failed to get response. Retrying");
217
+ response = self.get_api(status_url)
218
+ if response is None:
219
+ raise ClikApiError('Failed to get job status after %s attempts' % self.retry_max)
220
+
221
+ reply = response.json()
186
222
 
187
223
  continue
188
224
 
189
225
  if reply['data']['status'] == "Failed":
190
- print(reply['data']['message'])
191
- return
226
+ raise ClikApiError(reply['data']['message'])
192
227
 
193
- raise Exception('Unknown API state [%s]' % reply['data']['status'])
228
+ raise ClikApiError('Unknown API state [%s]' % reply['data']['status'])
194
229
 
195
230
  def download(self, url, target):
196
231
  self.info('Start to save file - ' + target)
@@ -199,11 +234,12 @@ class Client(object):
199
234
 
200
235
  while tries < self.retry_max:
201
236
  try:
202
- response = requests.get(url, verify=False, allow_redirects=True)
203
- open(target, 'wb').write(response.content)
204
- except requests.exceptions.ConnectionError as e:
205
- self.warning("Recovering from connection error [%s], attemps %s of %s",
206
- response.status_code, response.reason, tries, self.retry_max)
237
+ response = requests.get(url, allow_redirects=True, timeout=self.timeout)
238
+ with open(target, 'wb') as f:
239
+ f.write(response.content)
240
+ except requests.exceptions.RequestException as e:
241
+ self.warning("Recovering from connection error [%s], attempt %s of %s",
242
+ e, tries, self.retry_max)
207
243
 
208
244
  if os.path.exists(target):
209
245
  self.info('Done')
@@ -223,18 +259,21 @@ class Client(object):
223
259
 
224
260
  while tries < self.retry_max:
225
261
  try:
226
- response = requests.get(url, verify=False)
227
- except requests.exceptions.ConnectionError as e:
262
+ response = requests.get(url, timeout=self.timeout)
263
+ except requests.exceptions.RequestException as e:
228
264
  response = None
229
- self.warning("Recovering from connection error [%s], attemps %s of %s",
230
- response.status_code, response.reason, tries, self.retry_max)
265
+ self.warning("Recovering from connection error [%s], attempt %s of %s",
266
+ e, tries, self.retry_max)
231
267
 
232
- if response is not None:
268
+ if response is not None:
233
269
  if response.status_code == 202 or response.status_code == 200:
234
270
  return response
235
271
  else:
236
272
  self.error('Failed to get status of the job.')
237
- self.error(response['data']['info'])
273
+ try:
274
+ self.error(response.json()['data']['info'])
275
+ except ValueError:
276
+ self.error(response.text)
238
277
 
239
278
  tries += 1
240
279
 
@@ -251,15 +290,15 @@ class Client(object):
251
290
 
252
291
  while tries < self.retry_max:
253
292
  try:
254
- response = requests.post(url, verify=False, headers=headers, data=json.dumps(request))
255
- except requests.exceptions.ConnectionError as e:
293
+ response = requests.post(url, headers=headers, data=json.dumps(request), timeout=self.timeout)
294
+ except requests.exceptions.RequestException as e:
256
295
  response = None
257
- self.warning("Recovering from connection error [%s], attemps %s of %s",
296
+ self.warning("Recovering from connection error [%s], attempt %s of %s",
258
297
  e, tries, self.retry_max)
259
298
 
260
- if response is not None:
299
+ if response is not None:
261
300
  if response.status_code > 202:
262
- self.warning("Recovering from HTTP error [%s %s], attemps %s of %s",
301
+ self.warning("Recovering from HTTP error [%s %s], attempt %s of %s",
263
302
  response.status_code, response.reason, tries, self.retry_max)
264
303
  else:
265
304
  return response
@@ -0,0 +1,130 @@
1
+ import json
2
+ import requests
3
+ import logging
4
+ import os
5
+ import math
6
+
7
+ class ClippingClient(object):
8
+ logger = logging.getLogger('clipsapi')
9
+ api_server_url = 'https://processingapi.apcc21.org'
10
+ result_server_url = 'https://processingresult.apcc21.org'
11
+
12
+ def __init__(self, debug=False, retry_max=500, timeout=60):
13
+ self.retry_max = retry_max
14
+ self.timeout = timeout
15
+ self.last_status = None
16
+ self.target = None
17
+ if debug:
18
+ level = logging.DEBUG
19
+ else:
20
+ level = logging.INFO
21
+
22
+ logging.basicConfig(level=level, format='[%(asctime)s] [%(levelname)s] %(message)s')
23
+
24
+ def clip(self, detail):
25
+
26
+ headers = {'Content-Type': 'application/json; charset-utf-8'}
27
+ return_type = detail['return_type']
28
+ output_file_name = self.generate_file_name(detail)
29
+
30
+ if return_type == 'png':
31
+ api_url = self.api_server_url + '/clip-mme'
32
+ output_file_name = output_file_name + '.png'
33
+ elif return_type == 'nc':
34
+ api_url = self.api_server_url + '/clip-mme-to-nc'
35
+ output_file_name = output_file_name + '.zip'
36
+ else:
37
+ print("Error : Invalid File Extension")
38
+ return False
39
+
40
+ json_data = json.dumps(detail)
41
+
42
+ self.print_clipping_detail(detail, output_file_name)
43
+
44
+ tries = 0
45
+
46
+ while tries < self.retry_max:
47
+ try:
48
+ response = requests.post(api_url, data=json_data, headers=headers, timeout=self.timeout)
49
+ if response.status_code == 200:
50
+ json_result = json.loads(response.content)
51
+ print(json_result)
52
+ else:
53
+ print("Error: ", response.status_code)
54
+ return False
55
+
56
+ try:
57
+ if isinstance(json_result, list):
58
+ file_urls = json_result
59
+ else:
60
+ file_urls = json.loads(json_result)
61
+ except json.JSONDecodeError:
62
+ file_urls = []
63
+ file_urls.append(self.result_server_url + "/" + json_result)
64
+
65
+ for file_url in file_urls:
66
+ response = requests.get(file_url, allow_redirects=True, timeout=self.timeout)
67
+ filename = file_url.split("/")[-1]
68
+
69
+ with open(filename, 'wb') as f:
70
+ f.write(response.content)
71
+ if os.path.exists(filename):
72
+ print(filename + " download complete!")
73
+
74
+ return True
75
+
76
+ except requests.exceptions.RequestException as e:
77
+ self.warning("Recovering from connection error [%s], attempt %s of %s",
78
+ e, tries, self.retry_max)
79
+
80
+ tries += 1
81
+
82
+ return False
83
+
84
+ def info(self, *args, **kwargs):
85
+ self.logger.info(*args, **kwargs)
86
+
87
+ def warning(self, *args, **kwargs):
88
+ self.logger.warning(*args, **kwargs)
89
+
90
+ def error(self, *args, **kwargs):
91
+ self.logger.error(*args, **kwargs)
92
+
93
+ def debug(self, *args, **kwargs):
94
+ self.logger.debug(*args, **kwargs)
95
+
96
+ def generate_file_name(self, detail):
97
+ variable = detail['variable']
98
+ lead_month = detail['lead_month']
99
+ method = detail['method']
100
+ period = detail['period'].strip().replace(' mean', '')
101
+ year = detail['iyear']
102
+ month = detail['imonth']
103
+ south = detail['cosouth']
104
+ north = detail['conorth']
105
+ west = detail['cowest']
106
+ east = detail['coeast']
107
+
108
+ file_name = "clipped_APCC_MME_" + lead_month + "_" + variable + "_" + method + "_" + year + "_" + month + "_" + south + "_" + north + "_" + west + "_" + east + "_" + period
109
+
110
+ return file_name
111
+
112
+ def print_clipping_detail(self, detail, file_name):
113
+ print('Start to save file - ' + file_name)
114
+ print()
115
+ print("Model")
116
+ print("Lead Month : " + detail['lead_month'])
117
+ print("Variable : " + detail['variable'])
118
+ print("Method : " + detail['method'])
119
+ print("Period : " + detail['period'])
120
+ print("Issued Year : " + detail['iyear'])
121
+ print("Issued Month : " + detail['imonth'])
122
+ print()
123
+ print("Coordinate")
124
+ print("Min Latitude : " + detail['cosouth'])
125
+ print("Max Latitude : " + detail['conorth'])
126
+ print("Min longitude : " + detail['cowest'])
127
+ print("Max longitude : " + detail['coeast'])
128
+ print()
129
+
130
+ return True
@@ -1,84 +1,96 @@
1
- Metadata-Version: 2.1
2
- Name: apccapi
3
- Version: 0.0.1
4
- Summary: APCC Climate Information toolKit API package
5
- Home-page: https://www.apcc21.org
6
- Author: APEC Climate Center
7
- Author-email: joohyung@apcc21.org
8
- Project-URL: CLIK, https://cliks.apcc21.org
9
- Keywords: APCC,apcc,Climate,Climate Information,Climate API
10
- Classifier: Programming Language :: Python :: 3
11
- Classifier: License :: OSI Approved :: MIT License
12
- Classifier: Operating System :: OS Independent
13
- Requires-Python: >=3.6
14
- Description-Content-Type: text/markdown
15
- License-File: LICENSE
16
- Requires-Dist: requests
17
- Requires-Dist: urllib3
18
-
19
- ## Installation
20
-
21
- Install via pip with:
22
-
23
- ```bash
24
- $ pip install apccapi
25
- ```
26
-
27
- ## Configure (Linux)
28
-
29
- Obtain your API key from the CLIK (Climate Information toolKit) at https://cliks.apcc21.org and enter it into the apccapi.properties file, formatting it as follows:
30
-
31
- ```
32
- $ vi ~/.apccapi.properties
33
-
34
- key={your API key}
35
- request_url=https://request.apcc21.org/apccdata
36
- status_url=https://request.apcc21.org/status
37
- ```
38
-
39
- ## Configure (Windows)
40
-
41
- Obtain your API key from the CLIK (Climate Information toolKit) at https://cliks.apcc21.org, and create the apccapi.properties file in your Windows Home directory (typically C:\Users\YourUserName) with the following format:
42
-
43
- ```
44
- key={your API key}
45
- request_url=https://request.apcc21.org/apccdata
46
- status_url=https://request.apcc21.org/status
47
- ```
48
-
49
- ## Test
50
-
51
- Perform a small test retrieve of MME data:
52
- ```
53
- $ python
54
- >>> import apccapi
55
- >>> c = apccapi.Client()
56
- >>> c.retrieve(
57
- {
58
- 'jobtype': 'MME',
59
- 'dataset': 'MME_3MONTH',
60
- 'type': 'FORECAST',
61
- 'method': 'SCM',
62
- 'variable': ['prec', 't2m'],
63
- 'period': ['Monthly mean'],
64
- 'yearmonth': ['201909']
65
- },
66
- 'mme3.zip'
67
- )
68
- >>>
69
-
70
- ```
71
-
72
- ## License
73
-
74
- MIT License
75
-
76
- Copyright (c) 2019 - 2024, APEC Climate Center
77
-
78
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
79
- copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
80
-
81
- The above copyright notice and this permission notice shall be included in all
82
- copies or substantial portions of the Software.
83
-
84
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1
+ Metadata-Version: 2.4
2
+ Name: apccapi
3
+ Version: 0.1.0
4
+ Summary: APCC Climate Information toolKit API package
5
+ Home-page: https://www.apcc21.org
6
+ Author: APEC Climate Center
7
+ Author-email: joohyung@apcc21.org
8
+ Project-URL: CLIK, https://apcc21.org/clik/
9
+ Keywords: APCC,apcc,Climate,Climate Information,Climate API
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Operating System :: OS Independent
13
+ Requires-Python: >=3.6
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE
16
+ Requires-Dist: requests
17
+ Requires-Dist: urllib3<2
18
+ Dynamic: author
19
+ Dynamic: author-email
20
+ Dynamic: classifier
21
+ Dynamic: description
22
+ Dynamic: description-content-type
23
+ Dynamic: home-page
24
+ Dynamic: keywords
25
+ Dynamic: license-file
26
+ Dynamic: project-url
27
+ Dynamic: requires-dist
28
+ Dynamic: requires-python
29
+ Dynamic: summary
30
+
31
+ ## Installation
32
+
33
+ Install via pip with:
34
+
35
+ ```bash
36
+ $ pip install apccapi
37
+ ```
38
+
39
+ ## Configure (Linux)
40
+
41
+ Obtain your API key from the CLIK (Climate Information toolKit) at https://apcc21.org/clik/ and enter it into the apccapi.properties file, formatting it as follows:
42
+
43
+ ```
44
+ $ vi ~/apccapi.properties
45
+
46
+ key={your API key}
47
+ request_url=https://apcc21.org/clikapi/request/apccdata
48
+ status_url=https://apcc21.org/clikapi/request/status
49
+ ```
50
+
51
+ ## Configure (Windows)
52
+
53
+ Obtain your API key from the CLIK (Climate Information toolKit) at https://apcc21.org/clik/, and create the apccapi.properties file in your Windows Home directory (typically C:\Users\YourUserName) with the following format:
54
+
55
+ ```
56
+ key={your API key}
57
+ request_url=https://apcc21.org/clikapi/request/apccdata
58
+ status_url=https://apcc21.org/clikapi/request/status
59
+ ```
60
+
61
+ ## Test
62
+
63
+ Perform a small test retrieve of MME data:
64
+ ```
65
+ $ python
66
+ >>> import apccapi
67
+ >>> c = apccapi.Client()
68
+ >>> c.retrieve(
69
+ {
70
+ 'jobtype': 'MME',
71
+ 'dataset': 'MME_3MONTH',
72
+ 'type': 'FORECAST',
73
+ 'method': 'SCM',
74
+ 'variable': ['prec', 't2m'],
75
+ 'period': ['Monthly mean'],
76
+ 'yearmonth': ['201909']
77
+ },
78
+ 'mme3.zip'
79
+ )
80
+ >>>
81
+
82
+ ```
83
+
84
+ ## License
85
+
86
+ MIT License
87
+
88
+ Copyright (c) 2019 - 2024, APEC Climate Center
89
+
90
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
91
+ copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
92
+
93
+ The above copyright notice and this permission notice shall be included in all
94
+ copies or substantial portions of the Software.
95
+
96
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -2,7 +2,8 @@ LICENSE
2
2
  README.md
3
3
  setup.py
4
4
  apccapi/__init__.py
5
- apccapi/apccapi.py
5
+ apccapi/client.py
6
+ apccapi/clipping.py
6
7
  apccapi.egg-info/PKG-INFO
7
8
  apccapi.egg-info/SOURCES.txt
8
9
  apccapi.egg-info/dependency_links.txt
@@ -0,0 +1,2 @@
1
+ requests
2
+ urllib3<2
@@ -1,4 +1,4 @@
1
- [egg_info]
2
- tag_build =
3
- tag_date = 0
4
-
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
5
5
 
6
6
  setuptools.setup(
7
7
  name="apccapi",
8
- version="0.0.1",
8
+ version="0.1.0",
9
9
  author="APEC Climate Center",
10
10
  author_email="joohyung@apcc21.org",
11
11
  description="APCC Climate Information toolKit API package",
@@ -24,9 +24,9 @@ setuptools.setup(
24
24
  ],
25
25
  install_requires=[
26
26
  'requests',
27
- 'urllib3',
27
+ 'urllib3<2',
28
28
  ],
29
29
  project_urls={
30
- "CLIK": "https://cliks.apcc21.org",
30
+ "CLIK": "https://apcc21.org/clik/",
31
31
  },
32
32
  )
@@ -1,5 +0,0 @@
1
- import apccapi
2
- Client = apccapi.Client
3
- __version__ = '0.0.1'
4
- __author__ = 'APEC Climate Center'
5
- print(apccapi.__version__)
@@ -1,2 +0,0 @@
1
- requests
2
- urllib3
File without changes