hapiclient 0.2.8__tar.gz → 0.2.9__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.
Files changed (31) hide show
  1. {hapiclient-0.2.8 → hapiclient-0.2.9}/CHANGES.txt +4 -0
  2. {hapiclient-0.2.8/hapiclient.egg-info → hapiclient-0.2.9}/PKG-INFO +1 -1
  3. {hapiclient-0.2.8 → hapiclient-0.2.9}/hapiclient/__init__.py +1 -1
  4. {hapiclient-0.2.8 → hapiclient-0.2.9}/hapiclient/cache.py +1 -1
  5. {hapiclient-0.2.8 → hapiclient-0.2.9}/hapiclient/get.py +11 -9
  6. {hapiclient-0.2.8 → hapiclient-0.2.9}/hapiclient/hapi.py +1 -1
  7. {hapiclient-0.2.8 → hapiclient-0.2.9}/hapiclient/hapitime.py +2 -1
  8. {hapiclient-0.2.8 → hapiclient-0.2.9}/hapiclient/log.py +14 -6
  9. {hapiclient-0.2.8 → hapiclient-0.2.9/hapiclient.egg-info}/PKG-INFO +1 -1
  10. {hapiclient-0.2.8 → hapiclient-0.2.9}/setup.py +1 -1
  11. {hapiclient-0.2.8 → hapiclient-0.2.9}/test/test_chunking.py +1 -1
  12. {hapiclient-0.2.8 → hapiclient-0.2.9}/test/test_hapi_data_requests.py +30 -0
  13. {hapiclient-0.2.8 → hapiclient-0.2.9}/LICENSE.txt +0 -0
  14. {hapiclient-0.2.8 → hapiclient-0.2.9}/MANIFEST.in +0 -0
  15. {hapiclient-0.2.8 → hapiclient-0.2.9}/README.md +0 -0
  16. {hapiclient-0.2.8 → hapiclient-0.2.9}/hapiclient/capabilities.py +0 -0
  17. {hapiclient-0.2.8 → hapiclient-0.2.9}/hapiclient/catalog.py +0 -0
  18. {hapiclient-0.2.8 → hapiclient-0.2.9}/hapiclient/data.py +0 -0
  19. {hapiclient-0.2.8 → hapiclient-0.2.9}/hapiclient/info.py +0 -0
  20. {hapiclient-0.2.8 → hapiclient-0.2.9}/hapiclient/servers.py +0 -0
  21. {hapiclient-0.2.8 → hapiclient-0.2.9}/hapiclient/util.py +0 -0
  22. {hapiclient-0.2.8 → hapiclient-0.2.9}/hapiclient.egg-info/SOURCES.txt +0 -0
  23. {hapiclient-0.2.8 → hapiclient-0.2.9}/hapiclient.egg-info/dependency_links.txt +0 -0
  24. {hapiclient-0.2.8 → hapiclient-0.2.9}/hapiclient.egg-info/requires.txt +0 -0
  25. {hapiclient-0.2.8 → hapiclient-0.2.9}/hapiclient.egg-info/top_level.txt +0 -0
  26. {hapiclient-0.2.8 → hapiclient-0.2.9}/setup.cfg +0 -0
  27. {hapiclient-0.2.8 → hapiclient-0.2.9}/test/test_datetime2hapitime.py +0 -0
  28. {hapiclient-0.2.8 → hapiclient-0.2.9}/test/test_hapi_metadata_requests.py +0 -0
  29. {hapiclient-0.2.8 → hapiclient-0.2.9}/test/test_hapitime2datetime.py +0 -0
  30. {hapiclient-0.2.8 → hapiclient-0.2.9}/test/test_hapitime_reformat.py +0 -0
  31. {hapiclient-0.2.8 → hapiclient-0.2.9}/test/test_logging.py +0 -0
@@ -120,3 +120,7 @@ v0.2.8b2:
120
120
  2026-05-20 -- Refactor
121
121
  v0.2.8:
122
122
  2026-06-04 -- Compat. fixes for hapiplot package.
123
+ v0.2.8b0:
124
+ 2026-06-08 -- Show time parsing error message
125
+ v0.2.9:
126
+ 2026-06-08 -- 93-occasional-crashes-due-to-undefined-variable-dt-in-get_csv-hapiclient-version-028
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hapiclient
3
- Version: 0.2.8
3
+ Version: 0.2.9
4
4
  Summary: Interface to Heliophysics data server API
5
5
  Home-page: http://pypi.python.org/pypi/hapiclient/
6
6
  Author: Bob Weigel
@@ -13,7 +13,7 @@ from hapiclient.hapitime import datetime2hapitime
13
13
  # Allow "from hapiclient import HAPIError"
14
14
  from hapiclient.util import HAPIError
15
15
 
16
- __version__ = '0.2.8'
16
+ __version__ = '0.2.9'
17
17
 
18
18
  import sys
19
19
  import platform
@@ -171,7 +171,7 @@ def data_cache_read_metax(SERVER, DATASET, PARAMETERS, START, STOP, opts):
171
171
  from hapiclient.log import log
172
172
 
173
173
  if not opts["usecache"]:
174
- log('Not checking data cache because usecache is False.')
174
+ log('Not checking subsetted metadata cache because usecache is False.')
175
175
  return None
176
176
 
177
177
  fnamepklx = data_cache_paths(SERVER, DATASET, PARAMETERS, START, STOP, opts['cachedir'])['pkl']
@@ -174,12 +174,9 @@ def get_csv(meta, SERVER, DATASET, PARAMETERS, START, STOP, opts):
174
174
  if opts["cache"]:
175
175
  tic0 = time.time()
176
176
  urlretrieve(urlcsv, fnamecsv)
177
- toc0 = time.time() - tic0
178
177
  log('Reading and parsing %s' % os.path.basename(fnamecsv))
179
- tic = time.time()
180
178
  if os.path.getsize(fnamecsv) == 0:
181
179
  file_empty = True
182
- data = np.array([], dtype=dt)
183
180
  else:
184
181
  from io import StringIO
185
182
  log('Writing %s to buffer' % urlcsv)
@@ -188,22 +185,27 @@ def get_csv(meta, SERVER, DATASET, PARAMETERS, START, STOP, opts):
188
185
  fnamecsv.seek(0, os.SEEK_END)
189
186
  if fnamecsv.tell() == 0:
190
187
  file_empty = True
191
- data = np.array([], dtype=dt)
192
188
  else:
193
189
  fnamecsv.seek(0)
194
- toc0 = time.time() - tic0
195
190
  log('Parsing StringIO buffer.')
196
- tic = time.time()
197
191
 
198
- if not file_empty:
192
+ toc0 = time.time() - tic0
193
+
194
+ tic1 = time.time()
195
+
196
+ if file_empty:
197
+ log("Response is empty. Returning empty data array.")
198
+ dt, _, _, _, _ = _compute_dt(meta, opts)
199
+ data = np.array([], dtype=dt)
200
+ else:
199
201
  if missing_length(meta, opts):
200
202
  data = _parse_csv_missing_length(fnamecsv, meta, opts, urlcsv)
201
203
  else:
202
204
  data = _parse_csv(fnamecsv, meta, opts, urlcsv)
203
205
 
204
- toc = time.time() - tic
206
+ toc1 = time.time() - tic1
205
207
 
206
- return data, toc0, toc
208
+ return data, toc0, toc1
207
209
 
208
210
 
209
211
  def _parse_csv(fnamecsv, meta, opts, urlcsv):
@@ -45,7 +45,7 @@ def hapiopts():
45
45
  def hapi(*args, **kwargs):
46
46
  """Request data from a HAPI server.
47
47
 
48
- Version: 0.2.8
48
+ Version: 0.2.9
49
49
 
50
50
 
51
51
  Examples
@@ -274,7 +274,8 @@ def hapitime2datetime(Time, **kwargs):
274
274
  toc = time.time() - tic
275
275
  log("Pandas processing time = %.4fs, first time = %s" % (toc, Timeo))
276
276
  return Time
277
- except:
277
+ except Exception as e:
278
+ log("Pandas processing failed with error: " + str(e))
278
279
  log("Pandas processing failed, first time = %s" % Time[0])
279
280
 
280
281
 
@@ -5,6 +5,16 @@ _logger = _logging.getLogger("hapiclient")
5
5
  _INTERNAL_HANDLER_ATTR = "_hapiclient_internal_handler"
6
6
  _INTERNAL_LEVEL_ATTR = "_hapiclient_internal_level"
7
7
 
8
+ # Disable propagation and add NullHandler by default so hapiclient
9
+ # is silent unless explicitly configured by user. This is the standard
10
+ # practice for library loggers.
11
+ _logger.propagate = False
12
+ _logger.setLevel(_logging.NOTSET)
13
+ if not _logger.handlers:
14
+ _null_handler = _logging.NullHandler()
15
+ setattr(_null_handler, _INTERNAL_HANDLER_ATTR, True)
16
+ _logger.addHandler(_null_handler)
17
+
8
18
 
9
19
  def configure_logging(opts):
10
20
  """Configure the hapiclient logger based on opts['logging'].
@@ -31,13 +41,11 @@ def configure_logging(opts):
31
41
  _logger.addHandler(_handler)
32
42
  else:
33
43
  if has_user_level or has_user_handlers:
34
- if has_user_handlers:
35
- log("Ignoring logging=%s because standard Python logger for 'hapiclient' already configured with handlers." % opts['logging'])
36
- else:
37
- log("Ignoring logging=%s because standard Python logger for 'hapiclient' already configured with log_level != NOTSET." % opts['logging'])
44
+ # Don't log when logging is disabled - would cause output during tests
45
+ pass
38
46
  else:
39
- _logger.setLevel(_logging.WARNING)
40
- setattr(_logger, _INTERNAL_LEVEL_ATTR, _logging.WARNING)
47
+ _logger.setLevel(_logging.NOTSET)
48
+ setattr(_logger, _INTERNAL_LEVEL_ATTR, _logging.NOTSET)
41
49
 
42
50
 
43
51
  def log(msg, opts=None):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hapiclient
3
- Version: 0.2.8
3
+ Version: 0.2.9
4
4
  Summary: Interface to Heliophysics data server API
5
5
  Home-page: http://pypi.python.org/pypi/hapiclient/
6
6
  Author: Bob Weigel
@@ -32,7 +32,7 @@ if sys.argv[1] == 'develop':
32
32
  # version is modified by misc/version.py (executed from Makefile). Do not edit.
33
33
  setup(
34
34
  name='hapiclient',
35
- version='0.2.8',
35
+ version='0.2.9',
36
36
  author='Bob Weigel',
37
37
  author_email='rweigel@gmu.edu',
38
38
  packages=find_packages(),
@@ -11,7 +11,7 @@ from util.get_logger import get_logger
11
11
 
12
12
  logger = get_logger(__name__)
13
13
 
14
- hapi_logging = True
14
+ hapi_logging = False
15
15
  if logging.getLevelName(logger.level) == 'DEBUG':
16
16
  hapi_logging = True
17
17
 
@@ -212,8 +212,38 @@ def test_unicode():
212
212
  assert compare.read(server, dataset, parameter, run, opts.copy(), logger=logger)
213
213
  assert compare.cache(server, dataset, parameter, opts.copy(), logger=logger)
214
214
 
215
+ def test_empty_response():
216
+ from hapiclient import hapi
217
+
218
+ server = 'http://hapi-server.org/servers/TestData2.0/hapi'
219
+ dataset = 'dataset1'
220
+
221
+ # Time range with no data.
222
+ start = '1970-01-01T00:00:00.1Z'
223
+ stop = '1970-01-01T00:00:00.2Z'
224
+
225
+ _kwargs = kwargs.copy()
226
+ _kwargs['cache'] = False
227
+ _kwargs['usecache'] = False
228
+ data_csv, meta = hapi(server, dataset, '', start, stop, format='csv', **_kwargs)
229
+ data_bin, meta = hapi(server, dataset, '', start, stop, format='binary', **_kwargs)
230
+
231
+ assert len(data_csv) == 0
232
+ assert compare.equal(data_csv, data_bin)
233
+
234
+ for i in range(2):
235
+ _kwargs = kwargs.copy()
236
+ _kwargs['cache'] = True
237
+ _kwargs['usecache'] = True
238
+ data_csv, meta = hapi(server, dataset, '', start, stop, format='csv', **_kwargs)
239
+ data_bin, meta = hapi(server, dataset, '', start, stop, format='binary', **_kwargs)
240
+
241
+ assert len(data_csv) == 0
242
+ assert compare.equal(data_csv, data_bin)
243
+
215
244
 
216
245
  if __name__ == '__main__':
246
+ test_empty_response()
217
247
  test_subset_short()
218
248
  test_reader_timing_short()
219
249
  test_reader_timing_long()
File without changes
File without changes
File without changes
File without changes