cloudnet-api-client 0.3.0__tar.gz → 0.4.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,11 @@ 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.4.0 – 2025-04-03
9
+
10
+ - Move download function to APIClient class
11
+ - Add status parameter
12
+
8
13
  ## 0.3.0 – 2025-04-02
9
14
 
10
15
  - Move `filename_prefix` and `filename_suffix` parameters
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cloudnet-api-client
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: Cloudnet API client
5
5
  Author-email: Simo Tukiainen <simo.tukiainen@fmi.fi>
6
6
  License-File: LICENSE
@@ -49,10 +49,10 @@ sites = client.sites(type="cloudnet")
49
49
  products = client.products()
50
50
 
51
51
  metadata = client.metadata("hyytiala", "2021-01-01", product=["mwr", "radar"])
52
- cac.download(metadata, "data/")
52
+ client.download(metadata, "data/")
53
53
 
54
54
  raw_metadata = client.raw_metadata("granada", date="2024-01", instrument_id="parsivel")
55
- cac.download(raw_metadata, "data_raw/")
55
+ client.download(raw_metadata, "data_raw/")
56
56
  ```
57
57
 
58
58
  ## Documentation
@@ -78,6 +78,7 @@ Parameters:
78
78
  | show_legacy\* | `bool` | `False` | |
79
79
  | filename_prefix\*\* | `str` or `list[str]` | `None` | "stare" |
80
80
  | filename_suffix\*\* | `str` or `list[str]` | `None` | ".lv1" |
81
+ | status\*\* | `str` or `list[str]` | `None` | "created", "uploaded", "processed" or "invalid" |
81
82
 
82
83
  \* = only in `metadata()`
83
84
 
@@ -142,7 +143,7 @@ Parameters:
142
143
 
143
144
  Fetch cloudnet instruments.
144
145
 
145
- ### `cloudnet_api_client.download(list[Metadata])` &rarr; `list[Path]`
146
+ ### `APIClient().download(list[Metadata])` &rarr; `list[Path]`
146
147
 
147
148
  Download files from the fetched metadata.
148
149
 
@@ -22,10 +22,10 @@ sites = client.sites(type="cloudnet")
22
22
  products = client.products()
23
23
 
24
24
  metadata = client.metadata("hyytiala", "2021-01-01", product=["mwr", "radar"])
25
- cac.download(metadata, "data/")
25
+ client.download(metadata, "data/")
26
26
 
27
27
  raw_metadata = client.raw_metadata("granada", date="2024-01", instrument_id="parsivel")
28
- cac.download(raw_metadata, "data_raw/")
28
+ client.download(raw_metadata, "data_raw/")
29
29
  ```
30
30
 
31
31
  ## Documentation
@@ -51,6 +51,7 @@ Parameters:
51
51
  | show_legacy\* | `bool` | `False` | |
52
52
  | filename_prefix\*\* | `str` or `list[str]` | `None` | "stare" |
53
53
  | filename_suffix\*\* | `str` or `list[str]` | `None` | ".lv1" |
54
+ | status\*\* | `str` or `list[str]` | `None` | "created", "uploaded", "processed" or "invalid" |
54
55
 
55
56
  \* = only in `metadata()`
56
57
 
@@ -115,7 +116,7 @@ Parameters:
115
116
 
116
117
  Fetch cloudnet instruments.
117
118
 
118
- ### `cloudnet_api_client.download(list[Metadata])` &rarr; `list[Path]`
119
+ ### `APIClient().download(list[Metadata])` &rarr; `list[Path]`
119
120
 
120
121
  Download files from the fetched metadata.
121
122
 
@@ -0,0 +1 @@
1
+ from .client import APIClient as APIClient
@@ -1,7 +1,11 @@
1
+ import asyncio
1
2
  import calendar
2
3
  import datetime
4
+ import os
3
5
  import re
4
6
  from dataclasses import fields, is_dataclass
7
+ from os import PathLike
8
+ from pathlib import Path
5
9
  from typing import TypeVar, cast
6
10
  from urllib.parse import urljoin
7
11
 
@@ -12,6 +16,7 @@ from urllib3.util.retry import Retry
12
16
  from cloudnet_api_client.containers import (
13
17
  PRODUCT_TYPE,
14
18
  SITE_TYPE,
19
+ STATUS,
15
20
  Instrument,
16
21
  Metadata,
17
22
  Product,
@@ -19,11 +24,13 @@ from cloudnet_api_client.containers import (
19
24
  RawMetadata,
20
25
  Site,
21
26
  )
27
+ from cloudnet_api_client.dl import download_files
22
28
 
23
29
  T = TypeVar("T")
24
30
  DateParam = str | datetime.date | None
25
31
  DateTimeParam = str | datetime.datetime | datetime.date | None
26
32
  QueryParam = str | list[str] | None
33
+ MetadataList = list[ProductMetadata] | list[RawMetadata]
27
34
 
28
35
 
29
36
  class APIClient:
@@ -124,6 +131,7 @@ class APIClient:
124
131
  instrument_pid: QueryParam = None,
125
132
  filename_prefix: QueryParam = None,
126
133
  filename_suffix: QueryParam = None,
134
+ status: STATUS | list[STATUS] | None = None,
127
135
  ) -> list[RawMetadata]:
128
136
  params = {
129
137
  "site": site_id,
@@ -131,6 +139,7 @@ class APIClient:
131
139
  "instrumentPid": instrument_pid,
132
140
  "filenamePrefix": filename_prefix,
133
141
  "filenameSuffix": filename_suffix,
142
+ "status": status,
134
143
  }
135
144
  _add_date_params(
136
145
  params, date, date_from, date_to, updated_at, updated_at_from, updated_at_to
@@ -138,6 +147,35 @@ class APIClient:
138
147
  res = self._get_response("raw-files", params)
139
148
  return _build_raw_meta_objects(res)
140
149
 
150
+ def download(
151
+ self,
152
+ metadata: MetadataList,
153
+ output_directory: str | PathLike,
154
+ concurrency_limit: int = 5,
155
+ progress: bool | None = None,
156
+ ) -> list[Path]:
157
+ return asyncio.run(
158
+ self.adownload(metadata, output_directory, concurrency_limit, progress)
159
+ )
160
+
161
+ async def adownload(
162
+ self,
163
+ metadata: MetadataList,
164
+ output_directory: str | PathLike,
165
+ concurrency_limit: int = 5,
166
+ progress: bool | None = None,
167
+ ) -> list[Path]:
168
+ disable_progress = not progress if progress is not None else None
169
+ output_directory = Path(output_directory).resolve()
170
+ os.makedirs(output_directory, exist_ok=True)
171
+ return await download_files(
172
+ self.base_url,
173
+ metadata,
174
+ output_directory,
175
+ concurrency_limit,
176
+ disable_progress,
177
+ )
178
+
141
179
  @staticmethod
142
180
  def filter(
143
181
  metadata: list[Metadata],
@@ -4,6 +4,7 @@ from typing import Literal
4
4
 
5
5
  SITE_TYPE = Literal["cloudnet", "model", "hidden", "campaign"]
6
6
  PRODUCT_TYPE = Literal["instrument", "geophysical", "evaluation", "model"]
7
+ STATUS = Literal["created", "uploaded", "processed", "invalid"]
7
8
 
8
9
 
9
10
  @dataclass(frozen=True, slots=True)
@@ -58,7 +59,7 @@ class Metadata:
58
59
 
59
60
  @dataclass(frozen=True, slots=True)
60
61
  class RawMetadata(Metadata):
61
- status: Literal["created", "uploaded", "processed", "invalid"]
62
+ status: STATUS
62
63
  instrument: Instrument
63
64
  tags: list[str] | None
64
65
 
@@ -1,7 +1,5 @@
1
1
  import asyncio
2
2
  import logging
3
- import os
4
- from os import PathLike
5
3
  from pathlib import Path
6
4
 
7
5
  import aiohttp
@@ -11,36 +9,10 @@ from tqdm.asyncio import tqdm_asyncio
11
9
  from cloudnet_api_client import utils
12
10
  from cloudnet_api_client.containers import ProductMetadata, RawMetadata
13
11
 
14
- MetadataList = list[ProductMetadata] | list[RawMetadata]
15
12
 
16
-
17
- def download(
18
- metadata: MetadataList,
19
- output_directory: str | PathLike,
20
- concurrency_limit: int = 5,
21
- progress: bool | None = None,
22
- ) -> list[Path]:
23
- return asyncio.run(
24
- adownload(metadata, output_directory, concurrency_limit, progress)
25
- )
26
-
27
-
28
- async def adownload(
29
- metadata: MetadataList,
30
- output_directory: str | PathLike,
31
- concurrency_limit: int = 5,
32
- progress: bool | None = None,
33
- ) -> list[Path]:
34
- disable_progress = not progress if progress is not None else None
35
- output_directory = Path(output_directory).resolve()
36
- os.makedirs(output_directory, exist_ok=True)
37
- return await _download_files(
38
- metadata, output_directory, concurrency_limit, disable_progress
39
- )
40
-
41
-
42
- async def _download_files(
43
- metadata: MetadataList,
13
+ async def download_files(
14
+ base_url: str,
15
+ metadata: list[ProductMetadata] | list[RawMetadata],
44
16
  output_path: Path,
45
17
  concurrency_limit: int,
46
18
  disable_progress: bool | None,
@@ -50,6 +22,7 @@ async def _download_files(
50
22
  async with aiohttp.ClientSession() as session:
51
23
  tasks = []
52
24
  for meta in metadata:
25
+ download_url = f"{base_url}{meta.download_url.split('/api/')[-1]}"
53
26
  destination = output_path / meta.download_url.split("/")[-1]
54
27
  full_paths.append(destination)
55
28
  if destination.exists() and _file_checksum_matches(meta, destination):
@@ -57,7 +30,7 @@ async def _download_files(
57
30
  continue
58
31
  task = asyncio.create_task(
59
32
  _download_file_with_retries(
60
- session, meta.download_url, destination, semaphore, disable_progress
33
+ session, download_url, destination, semaphore, disable_progress
61
34
  )
62
35
  )
63
36
  tasks.append(task)
@@ -0,0 +1 @@
1
+ __version__ = "0.4.0"
@@ -1,3 +0,0 @@
1
- from .client import APIClient as APIClient
2
- from .dl import adownload as adownload
3
- from .dl import download as download
@@ -1 +0,0 @@
1
- __version__ = "0.3.0"