|
18 | 18 | from flask import current_app as app |
19 | 19 | import os |
20 | 20 | import simplejson as json |
| 21 | +from datetime import datetime, timezone |
| 22 | +import decimal |
21 | 23 | from .querier import ArchiveQuerier, Cursor, InvalidCursor, \ |
22 | 24 | DEFAULT_LOOKBACK_DAYS |
23 | 25 | from .fetcher import ArchiveFileFetcher |
|
29 | 31 |
|
30 | 32 | _archive_querier = None |
31 | 33 |
|
| 34 | + |
| 35 | +def epoch_to_utc_iso(epoch): |
| 36 | + if epoch is None: |
| 37 | + return epoch |
| 38 | + epoch_to_iso = epoch |
| 39 | + if isinstance(epoch_to_iso, decimal.Decimal): |
| 40 | + epoch_to_iso = float(epoch_to_iso) |
| 41 | + iso = datetime.fromtimestamp( |
| 42 | + epoch_to_iso / 1000.0, tz=timezone.utc |
| 43 | + ).isoformat(timespec='milliseconds').replace('+00:00', 'Z') |
| 44 | + return iso |
| 45 | + |
| 46 | + |
| 47 | +def add_utc_metadata(metadata): |
| 48 | + """Add ISO-8601 UTC timestamp fields to metadata dict |
| 49 | +
|
| 50 | + This function takes a metadata dict and adds start_iso and end_iso fields based on existing start and end epoch timestamps |
| 51 | + iso precision is set to milliseconds |
| 52 | + Can be expanded to add any api-level metadata |
| 53 | + """ |
| 54 | + if not metadata: |
| 55 | + return metadata |
| 56 | + |
| 57 | + start_iso = epoch_to_utc_iso(metadata['start']) |
| 58 | + end_iso = epoch_to_utc_iso(metadata['end']) |
| 59 | + |
| 60 | + metadata['start_iso'] = start_iso |
| 61 | + metadata['end_iso'] = end_iso |
| 62 | + return metadata |
| 63 | + |
| 64 | + |
32 | 65 | def _get_aws_kwargs(): |
33 | 66 | kwargs = dict( |
34 | 67 | region_name=app.config.get('AWS_REGION'), |
@@ -305,6 +338,14 @@ def files_get(): |
305 | 338 | type: string |
306 | 339 | description: 16-byte blake2 hash of the file |
307 | 340 | content |
| 341 | + start_iso: |
| 342 | + type: string |
| 343 | + description: the start time of the file in ISO |
| 344 | + format UTC iso timezone |
| 345 | + end_iso: |
| 346 | + type: string |
| 347 | + description: the end time of the file in ISO |
| 348 | + format UTC iso timezone |
308 | 349 |
|
309 | 350 | next: |
310 | 351 | type: string |
@@ -349,7 +390,10 @@ def files_get(): |
349 | 390 | where=params.get('where'), |
350 | 391 | cursor=params.get('cursor')) |
351 | 392 |
|
352 | | - [r.update(http_url=_get_canonical_http_url(r)) for r in results] |
| 393 | + for r in results: |
| 394 | + r.update(http_url=_get_canonical_http_url(r)) |
| 395 | + r['metadata'] = add_utc_metadata(r['metadata']) |
| 396 | + |
353 | 397 | response = { |
354 | 398 | 'records': results, |
355 | 399 | 'next': _get_next_url(flask.request, results), |
@@ -476,6 +520,7 @@ def file_get_metadata(file_id): |
476 | 520 | id: DatalakeAPIError |
477 | 521 | ''' |
478 | 522 | f = _get_file(file_id) |
| 523 | + f.metadata = add_utc_metadata(f.metadata) |
479 | 524 | return Response(json.dumps(f.metadata), content_type='application/json') |
480 | 525 |
|
481 | 526 |
|
@@ -542,6 +587,7 @@ def latest_get(what, where): |
542 | 587 | params = _validate_latest_params(params) |
543 | 588 | f = _get_latest(what, where, params.get('lookback', DEFAULT_LOOKBACK_DAYS)) |
544 | 589 | f.update(http_url=_get_canonical_http_url(f)) |
| 590 | + f['metadata'] = add_utc_metadata(f['metadata']) |
545 | 591 | return Response(json.dumps(f), content_type='application/json') |
546 | 592 |
|
547 | 593 |
|
|
0 commit comments