cloudnet-api-client 0.7.0__tar.gz → 0.8.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.
@@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## 0.8.0 – 2025-05-14
9
+
10
+ - Add site to metadata responses
11
+
8
12
  ## 0.7.0 – 2025-05-06
9
13
 
10
14
  - Validate checksum optionally
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cloudnet-api-client
3
- Version: 0.7.0
3
+ Version: 0.8.0
4
4
  Summary: Cloudnet API client
5
5
  Author-email: Simo Tukiainen <simo.tukiainen@fmi.fi>
6
6
  License-File: LICENSE
@@ -161,7 +161,7 @@ class APIClient:
161
161
 
162
162
  def raw_model_metadata(
163
163
  self,
164
- site_id: str,
164
+ site_id: QueryParam = None,
165
165
  model_id: QueryParam = None,
166
166
  date: DateParam = None,
167
167
  date_from: DateParam = None,
@@ -396,7 +396,7 @@ def _build_meta_objects(res: list[dict]) -> list[ProductMetadata]:
396
396
  field_names = (
397
397
  {f.name for f in fields(ProductMetadata)}
398
398
  - CONVERTED
399
- - {"product", "instrument", "model"}
399
+ - {"product", "instrument", "model", "site"}
400
400
  )
401
401
  return [
402
402
  ProductMetadata(
@@ -407,30 +407,10 @@ def _build_meta_objects(res: list[dict]) -> list[ProductMetadata]:
407
407
  type=obj["product"]["type"],
408
408
  experimental=obj["product"]["experimental"],
409
409
  ),
410
- instrument=Instrument(
411
- instrument_id=obj["instrument"]["instrumentId"],
412
- model=obj["instrument"]["model"],
413
- type=obj["instrument"]["type"],
414
- uuid=uuid.UUID(obj["instrument"]["uuid"]),
415
- pid=obj["instrument"]["pid"],
416
- owners=obj["instrument"]["owners"],
417
- serial_number=obj["instrument"]["serialNumber"],
418
- name=obj["instrument"]["name"],
419
- )
410
+ instrument=_create_instrument_object(obj["instrument"])
420
411
  if "instrument" in obj and obj["instrument"] is not None
421
412
  else None,
422
- model=Model(
423
- model_id=obj["model"]["id"],
424
- name=obj["model"]["humanReadableName"],
425
- optimum_order=obj["model"]["optimumOrder"],
426
- source_model_id=obj["model"]["sourceModelId"],
427
- forecast_start=obj["model"]["forecastStart"]
428
- if obj["model"]["forecastStart"] is not None
429
- else None,
430
- forecast_end=obj["model"]["forecastEnd"]
431
- if obj["model"]["forecastEnd"] is not None
432
- else None,
433
- )
413
+ model=_create_model_object(obj["model"])
434
414
  if "model" in obj and obj["model"] is not None
435
415
  else None,
436
416
  measurement_date=datetime.date.fromisoformat(obj["measurementDate"]),
@@ -438,63 +418,96 @@ def _build_meta_objects(res: list[dict]) -> list[ProductMetadata]:
438
418
  updated_at=_parse_datetime(obj["updatedAt"]),
439
419
  size=int(obj["size"]),
440
420
  uuid=uuid.UUID(obj["uuid"]),
421
+ site=_create_site_object(obj["site"]),
441
422
  )
442
423
  for obj in res
443
424
  ]
444
425
 
445
426
 
446
427
  def _build_raw_meta_objects(res: list[dict]) -> list[RawMetadata]:
447
- field_names = {f.name for f in fields(RawMetadata)} - CONVERTED - {"instrument"}
428
+ field_names = (
429
+ {f.name for f in fields(RawMetadata)} - CONVERTED - {"instrument", "site"}
430
+ )
448
431
  return [
449
432
  RawMetadata(
450
433
  **{_to_snake(k): v for k, v in obj.items() if _to_snake(k) in field_names},
451
- instrument=Instrument(
452
- instrument_id=obj["instrumentInfo"]["instrumentId"],
453
- model=obj["instrumentInfo"]["model"],
454
- type=obj["instrumentInfo"]["type"],
455
- uuid=uuid.UUID(obj["instrumentInfo"]["uuid"]),
456
- pid=obj["instrumentInfo"]["pid"],
457
- owners=obj["instrumentInfo"]["owners"],
458
- serial_number=obj["instrumentInfo"]["serialNumber"],
459
- name=obj["instrumentInfo"]["name"],
460
- ),
434
+ instrument=_create_instrument_object(obj["instrumentInfo"]),
461
435
  measurement_date=datetime.date.fromisoformat(obj["measurementDate"]),
462
436
  created_at=_parse_datetime(obj["createdAt"]),
463
437
  updated_at=_parse_datetime(obj["updatedAt"]),
464
438
  size=int(obj["size"]),
465
439
  uuid=uuid.UUID(obj["uuid"]),
440
+ site=_create_site_object(obj["site"]),
466
441
  )
467
442
  for obj in res
468
443
  ]
469
444
 
470
445
 
471
446
  def _build_raw_model_meta_objects(res: list[dict]) -> list[RawModelMetadata]:
472
- field_names = {f.name for f in fields(RawModelMetadata)} - CONVERTED - {"model"}
447
+ field_names = (
448
+ {f.name for f in fields(RawModelMetadata)} - CONVERTED - {"model", "site"}
449
+ )
473
450
  return [
474
451
  RawModelMetadata(
475
452
  **{_to_snake(k): v for k, v in obj.items() if _to_snake(k) in field_names},
476
- model=Model(
477
- model_id=obj["model"]["id"],
478
- name=obj["model"]["humanReadableName"],
479
- optimum_order=int(obj["model"]["optimumOrder"]),
480
- source_model_id=obj["model"]["sourceModelId"],
481
- forecast_start=int(obj["model"]["forecastStart"])
482
- if obj["model"]["forecastStart"] is not None
483
- else None,
484
- forecast_end=int(obj["model"]["forecastEnd"])
485
- if obj["model"]["forecastEnd"] is not None
486
- else None,
487
- ),
453
+ model=_create_model_object(obj["model"]),
488
454
  measurement_date=datetime.date.fromisoformat(obj["measurementDate"]),
489
455
  created_at=_parse_datetime(obj["createdAt"]),
490
456
  updated_at=_parse_datetime(obj["updatedAt"]),
491
457
  size=int(obj["size"]),
492
458
  uuid=uuid.UUID(obj["uuid"]),
459
+ site=_create_site_object(obj["site"]),
493
460
  )
494
461
  for obj in res
495
462
  ]
496
463
 
497
464
 
465
+ def _create_model_object(metadata: dict) -> Model:
466
+ return Model(
467
+ model_id=metadata["id"],
468
+ name=metadata["humanReadableName"],
469
+ optimum_order=int(metadata["optimumOrder"]),
470
+ source_model_id=metadata["sourceModelId"],
471
+ forecast_start=int(metadata["forecastStart"])
472
+ if metadata["forecastStart"] is not None
473
+ else None,
474
+ forecast_end=int(metadata["forecastEnd"])
475
+ if metadata["forecastEnd"] is not None
476
+ else None,
477
+ )
478
+
479
+
480
+ def _create_site_object(metadata: dict) -> Site:
481
+ return Site(
482
+ id=metadata["id"],
483
+ human_readable_name=metadata["humanReadableName"],
484
+ station_name=metadata["stationName"],
485
+ latitude=float(metadata["latitude"]),
486
+ longitude=float(metadata["longitude"]),
487
+ altitude=float(metadata["altitude"]),
488
+ dvas_id=metadata["dvasId"],
489
+ actris_id=metadata["actrisId"],
490
+ country=metadata["country"],
491
+ country_code=metadata["countryCode"],
492
+ country_subdivision_code=metadata["countrySubdivisionCode"],
493
+ type=metadata["type"],
494
+ gaw=metadata["gaw"],
495
+ )
496
+
497
+
498
+ def _create_instrument_object(metadata: dict) -> Instrument:
499
+ return Instrument(
500
+ instrument_id=metadata["instrumentId"],
501
+ model=metadata["model"],
502
+ type=metadata["type"],
503
+ uuid=uuid.UUID(metadata["uuid"]),
504
+ pid=metadata["pid"],
505
+ owners=metadata["owners"],
506
+ serial_number=metadata["serialNumber"],
507
+ name=metadata["name"],
508
+ )
509
+
510
+
498
511
  def _to_snake(name: str) -> str:
499
512
  return re.sub(r"(?<!^)(?=[A-Z])", "_", name).lower()
500
513
 
@@ -65,6 +65,7 @@ class Metadata:
65
65
  measurement_date: datetime.date
66
66
  created_at: datetime.datetime
67
67
  updated_at: datetime.datetime
68
+ site: Site
68
69
 
69
70
 
70
71
  @dataclass(frozen=True, slots=True)
@@ -0,0 +1 @@
1
+ __version__ = "0.8.0"
@@ -1 +0,0 @@
1
- __version__ = "0.7.0"