datacosmos 0.0.10__tar.gz → 0.0.12__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.
Potentially problematic release.
This version of datacosmos might be problematic. Click here for more details.
- {datacosmos-0.0.10 → datacosmos-0.0.12}/PKG-INFO +1 -1
- datacosmos-0.0.12/datacosmos/config/models/url.py +54 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/stac/stac_client.py +2 -1
- datacosmos-0.0.12/datacosmos/stac/storage/dataclasses/upload_path.py +42 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/stac/storage/storage_client.py +2 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/stac/storage/uploader.py +42 -13
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos.egg-info/PKG-INFO +1 -1
- {datacosmos-0.0.10 → datacosmos-0.0.12}/pyproject.toml +1 -1
- datacosmos-0.0.10/datacosmos/config/models/url.py +0 -35
- datacosmos-0.0.10/datacosmos/stac/storage/dataclasses/upload_path.py +0 -63
- {datacosmos-0.0.10 → datacosmos-0.0.12}/LICENSE.md +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/README.md +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/__init__.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/config/__init__.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/config/config.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/config/models/__init__.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/config/models/authentication_config.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/config/models/local_user_account_authentication_config.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/config/models/m2m_authentication_config.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/config/models/no_authentication_config.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/datacosmos_client.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/exceptions/__init__.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/exceptions/datacosmos_exception.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/stac/__init__.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/stac/collection/__init__.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/stac/collection/collection_client.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/stac/collection/models/__init__.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/stac/collection/models/collection_update.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/stac/constants/__init__.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/stac/constants/satellite_name_mapping.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/stac/enums/__init__.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/stac/enums/processing_level.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/stac/enums/product_type.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/stac/enums/season.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/stac/item/__init__.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/stac/item/item_client.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/stac/item/models/__init__.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/stac/item/models/asset.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/stac/item/models/catalog_search_parameters.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/stac/item/models/datacosmos_item.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/stac/item/models/eo_band.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/stac/item/models/item_update.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/stac/item/models/raster_band.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/stac/storage/__init__.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/stac/storage/dataclasses/__init__.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/stac/storage/storage_base.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/utils/__init__.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/utils/http_response/__init__.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/utils/http_response/check_api_response.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/utils/http_response/models/__init__.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/utils/http_response/models/datacosmos_error.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/utils/http_response/models/datacosmos_response.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/utils/url.py +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos.egg-info/SOURCES.txt +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos.egg-info/dependency_links.txt +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos.egg-info/requires.txt +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos.egg-info/top_level.txt +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/setup.cfg +0 -0
- {datacosmos-0.0.10 → datacosmos-0.0.12}/tests/test_pass.py +0 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""Structured URL configuration model for the Datacosmos SDK.
|
|
2
|
+
|
|
3
|
+
The model accepts *either* a mapping of fields
|
|
4
|
+
(protocol, host, port, path) **or** a raw URL string such as
|
|
5
|
+
``"https://example.com/api/v1"`` and converts it into a fully featured
|
|
6
|
+
:class:`datacosmos.utils.url.URL` instance via :py:meth:`as_domain_url`.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from urllib.parse import urlparse
|
|
10
|
+
|
|
11
|
+
from pydantic import BaseModel, model_validator
|
|
12
|
+
|
|
13
|
+
from datacosmos.utils.url import URL as DomainURL
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class URL(BaseModel):
|
|
17
|
+
"""Generic configuration model for a URL."""
|
|
18
|
+
|
|
19
|
+
protocol: str
|
|
20
|
+
host: str
|
|
21
|
+
port: int
|
|
22
|
+
path: str
|
|
23
|
+
|
|
24
|
+
@model_validator(mode="before")
|
|
25
|
+
@classmethod
|
|
26
|
+
def _coerce_from_string(cls, data):
|
|
27
|
+
"""Convert a raw URL string into the dict expected by the model."""
|
|
28
|
+
if isinstance(data, cls):
|
|
29
|
+
return data
|
|
30
|
+
|
|
31
|
+
if isinstance(data, str):
|
|
32
|
+
parts = urlparse(data)
|
|
33
|
+
if not parts.scheme or not parts.hostname:
|
|
34
|
+
raise ValueError(f"'{data}' is not a valid absolute URL")
|
|
35
|
+
|
|
36
|
+
default_port = 443 if parts.scheme == "https" else 80
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
"protocol": parts.scheme,
|
|
40
|
+
"host": parts.hostname,
|
|
41
|
+
"port": parts.port or default_port,
|
|
42
|
+
"path": parts.path.rstrip("/"),
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return data
|
|
46
|
+
|
|
47
|
+
def as_domain_url(self) -> DomainURL:
|
|
48
|
+
"""Convert this Pydantic model to the utility `DomainURL` object."""
|
|
49
|
+
return DomainURL(
|
|
50
|
+
protocol=self.protocol,
|
|
51
|
+
host=self.host,
|
|
52
|
+
port=self.port,
|
|
53
|
+
base=self.path,
|
|
54
|
+
)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"""Unified interface for STAC API, combining Item & Collection operations."""
|
|
2
2
|
|
|
3
|
+
from datacosmos.datacosmos_client import DatacosmosClient
|
|
3
4
|
from datacosmos.stac.collection.collection_client import CollectionClient
|
|
4
5
|
from datacosmos.stac.item.item_client import ItemClient
|
|
5
6
|
from datacosmos.stac.storage.storage_client import StorageClient
|
|
@@ -8,7 +9,7 @@ from datacosmos.stac.storage.storage_client import StorageClient
|
|
|
8
9
|
class STACClient(ItemClient, CollectionClient, StorageClient):
|
|
9
10
|
"""Unified interface for STAC API, combining Item & Collection operations."""
|
|
10
11
|
|
|
11
|
-
def __init__(self, client):
|
|
12
|
+
def __init__(self, client: DatacosmosClient):
|
|
12
13
|
"""Initialize the STACClient with a DatacosmosClient."""
|
|
13
14
|
ItemClient.__init__(self, client)
|
|
14
15
|
CollectionClient.__init__(self, client)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""Dataclass for generating the upload key of an asset."""
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
from datacosmos.stac.item.models.datacosmos_item import DatacosmosItem
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@dataclass
|
|
10
|
+
class UploadPath:
|
|
11
|
+
"""Storage key in the form: project/<project-id>/<item-id>/<asset-name>."""
|
|
12
|
+
|
|
13
|
+
project_id: str
|
|
14
|
+
item_id: str
|
|
15
|
+
asset_name: str
|
|
16
|
+
|
|
17
|
+
def __str__(self) -> str:
|
|
18
|
+
"""Path in the form: project/<project-id>/<item-id>/<asset-name>."""
|
|
19
|
+
return f"project/{self.project_id}/{self.item_id}/{self.asset_name}".rstrip("/")
|
|
20
|
+
|
|
21
|
+
@classmethod
|
|
22
|
+
def from_item_path(
|
|
23
|
+
cls,
|
|
24
|
+
item: DatacosmosItem,
|
|
25
|
+
project_id: str,
|
|
26
|
+
asset_name: str,
|
|
27
|
+
) -> "UploadPath":
|
|
28
|
+
"""Create an UploadPath for the given item/asset."""
|
|
29
|
+
return cls(project_id=project_id, item_id=item.id, asset_name=asset_name)
|
|
30
|
+
|
|
31
|
+
@classmethod
|
|
32
|
+
def from_path(cls, path: str) -> "UploadPath":
|
|
33
|
+
"""Reverse-parse a storage key back into its components."""
|
|
34
|
+
parts = Path(path).parts
|
|
35
|
+
if len(parts) < 4 or parts[0] != "project":
|
|
36
|
+
raise ValueError(f"Invalid path: {path}")
|
|
37
|
+
|
|
38
|
+
project_id, item_id, *rest = parts[1:]
|
|
39
|
+
asset_name = "/".join(rest)
|
|
40
|
+
if not asset_name:
|
|
41
|
+
raise ValueError(f"Asset name is missing in path: {path}")
|
|
42
|
+
return cls(project_id=project_id, item_id=item_id, asset_name=asset_name)
|
|
@@ -16,6 +16,7 @@ class StorageClient:
|
|
|
16
16
|
def upload_item(
|
|
17
17
|
self,
|
|
18
18
|
item: DatacosmosItem,
|
|
19
|
+
project_id: str,
|
|
19
20
|
assets_path: str | None = None,
|
|
20
21
|
included_assets: list[str] | bool = True,
|
|
21
22
|
max_workers: int = 4,
|
|
@@ -24,6 +25,7 @@ class StorageClient:
|
|
|
24
25
|
"""Proxy to Uploader.upload_item, without needing to pass client each call."""
|
|
25
26
|
return self.uploader.upload_item(
|
|
26
27
|
item=item,
|
|
28
|
+
project_id=project_id,
|
|
27
29
|
assets_path=assets_path,
|
|
28
30
|
included_assets=included_assets,
|
|
29
31
|
max_workers=max_workers,
|
|
@@ -13,22 +13,37 @@ from datacosmos.stac.storage.storage_base import StorageBase
|
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
class Uploader(StorageBase):
|
|
16
|
-
"""
|
|
16
|
+
"""Upload a STAC item and its assets to Datacosmos storage, then register the item in the STAC API."""
|
|
17
17
|
|
|
18
18
|
def __init__(self, client: DatacosmosClient):
|
|
19
|
-
"""
|
|
19
|
+
"""Initialize the uploader.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
client (DatacosmosClient): Pre-configured DatacosmosClient.
|
|
23
|
+
"""
|
|
20
24
|
super().__init__(client)
|
|
21
25
|
self.item_client = ItemClient(client)
|
|
22
26
|
|
|
23
27
|
def upload_item(
|
|
24
28
|
self,
|
|
25
|
-
item: DatacosmosItem,
|
|
29
|
+
item: DatacosmosItem | str,
|
|
30
|
+
project_id: str,
|
|
26
31
|
assets_path: str | None = None,
|
|
27
32
|
included_assets: list[str] | bool = True,
|
|
28
33
|
max_workers: int = 4,
|
|
29
34
|
time_out: float = 60 * 60 * 1,
|
|
30
35
|
) -> DatacosmosItem:
|
|
31
|
-
"""Upload a STAC item and its assets to Datacosmos.
|
|
36
|
+
"""Upload a STAC item (and optionally its assets) to Datacosmos.
|
|
37
|
+
|
|
38
|
+
`item` can be either:
|
|
39
|
+
• a DatacosmosItem instance, or
|
|
40
|
+
• the path to an item JSON file on disk.
|
|
41
|
+
|
|
42
|
+
If `included_assets` is:
|
|
43
|
+
• True → upload every asset in the item
|
|
44
|
+
• list → upload only the asset keys in that list
|
|
45
|
+
• False → upload nothing; just register the item
|
|
46
|
+
"""
|
|
32
47
|
if not assets_path and not isinstance(item, str):
|
|
33
48
|
raise ValueError(
|
|
34
49
|
"assets_path must be provided if item is not the path to an item file."
|
|
@@ -37,8 +52,7 @@ class Uploader(StorageBase):
|
|
|
37
52
|
if isinstance(item, str):
|
|
38
53
|
item_filename = item
|
|
39
54
|
item = self._load_item(item_filename)
|
|
40
|
-
|
|
41
|
-
assets_path = str(Path(item_filename).parent)
|
|
55
|
+
assets_path = assets_path or str(Path(item_filename).parent)
|
|
42
56
|
|
|
43
57
|
assets_path = assets_path or str(Path.cwd())
|
|
44
58
|
|
|
@@ -50,18 +64,18 @@ class Uploader(StorageBase):
|
|
|
50
64
|
else []
|
|
51
65
|
)
|
|
52
66
|
|
|
53
|
-
jobs = [
|
|
54
|
-
|
|
67
|
+
jobs = [
|
|
68
|
+
(item, asset_key, assets_path, project_id) for asset_key in upload_assets
|
|
69
|
+
]
|
|
55
70
|
self._run_in_threads(self._upload_asset, jobs, max_workers, time_out)
|
|
56
71
|
|
|
57
72
|
self.item_client.add_item(item)
|
|
58
|
-
|
|
59
73
|
return item
|
|
60
74
|
|
|
61
75
|
def upload_from_file(
|
|
62
76
|
self, src: str, dst: str, mime_type: str | None = None
|
|
63
77
|
) -> None:
|
|
64
|
-
"""
|
|
78
|
+
"""Upload a single file to the specified destination path in storage."""
|
|
65
79
|
url = self.base_url.with_suffix(dst)
|
|
66
80
|
mime = mime_type or self._guess_mime(src)
|
|
67
81
|
headers = {"Content-Type": mime}
|
|
@@ -71,25 +85,40 @@ class Uploader(StorageBase):
|
|
|
71
85
|
|
|
72
86
|
@staticmethod
|
|
73
87
|
def _load_item(item_json_file_path: str) -> DatacosmosItem:
|
|
88
|
+
"""Load a DatacosmosItem from a JSON file on disk."""
|
|
74
89
|
with open(item_json_file_path, "rb") as file:
|
|
75
90
|
data = file.read().decode("utf-8")
|
|
76
91
|
return TypeAdapter(DatacosmosItem).validate_json(data)
|
|
77
92
|
|
|
78
93
|
def _upload_asset(
|
|
79
|
-
self, item: DatacosmosItem, asset_key: str, assets_path: str
|
|
94
|
+
self, item: DatacosmosItem, asset_key: str, assets_path: str, project_id: str
|
|
80
95
|
) -> None:
|
|
96
|
+
"""Upload a single asset file and update its href inside the item object.
|
|
97
|
+
|
|
98
|
+
Runs in parallel via _run_in_threads().
|
|
99
|
+
"""
|
|
81
100
|
asset = item.assets[asset_key]
|
|
82
|
-
|
|
101
|
+
|
|
102
|
+
# Build storage key: project/<project_id>/<item_id>/<asset_name>
|
|
103
|
+
upload_path = UploadPath.from_item_path(
|
|
104
|
+
item,
|
|
105
|
+
project_id,
|
|
106
|
+
Path(asset.href).name,
|
|
107
|
+
)
|
|
108
|
+
|
|
83
109
|
local_src = Path(assets_path) / asset.href
|
|
84
110
|
if local_src.exists():
|
|
85
111
|
src = str(local_src)
|
|
86
112
|
asset.href = f"file:///{upload_path}"
|
|
87
113
|
else:
|
|
114
|
+
# fallback: try matching just the filename inside assets_path
|
|
88
115
|
src = str(Path(assets_path) / Path(asset.href).name)
|
|
89
|
-
|
|
116
|
+
|
|
117
|
+
self._update_asset_href(asset) # turn href into public URL
|
|
90
118
|
self.upload_from_file(src, str(upload_path), mime_type=asset.type)
|
|
91
119
|
|
|
92
120
|
def _update_asset_href(self, asset: Asset) -> None:
|
|
121
|
+
"""Convert the storage key to a public HTTPS URL."""
|
|
93
122
|
try:
|
|
94
123
|
url = self.client.config.datacosmos_public_cloud_storage.as_domain_url()
|
|
95
124
|
new_href = url.with_base(asset.href) # type: ignore
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
"""Module defining a structured URL configuration model.
|
|
2
|
-
|
|
3
|
-
Ensures that URLs contain required components such as protocol, host,
|
|
4
|
-
port, and path.
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
from pydantic import BaseModel
|
|
8
|
-
|
|
9
|
-
from datacosmos.utils.url import URL as DomainURL
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class URL(BaseModel):
|
|
13
|
-
"""Generic configuration model for a URL.
|
|
14
|
-
|
|
15
|
-
This class provides attributes to store URL components and a method
|
|
16
|
-
to convert them into a `DomainURL` instance.
|
|
17
|
-
"""
|
|
18
|
-
|
|
19
|
-
protocol: str
|
|
20
|
-
host: str
|
|
21
|
-
port: int
|
|
22
|
-
path: str
|
|
23
|
-
|
|
24
|
-
def as_domain_url(self) -> DomainURL:
|
|
25
|
-
"""Convert the URL instance to a `DomainURL` object.
|
|
26
|
-
|
|
27
|
-
Returns:
|
|
28
|
-
DomainURL: A domain-specific URL object.
|
|
29
|
-
"""
|
|
30
|
-
return DomainURL(
|
|
31
|
-
protocol=self.protocol,
|
|
32
|
-
host=self.host,
|
|
33
|
-
port=self.port,
|
|
34
|
-
base=self.path,
|
|
35
|
-
)
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
"""Dataclass for retrieving the upload path of a file."""
|
|
2
|
-
|
|
3
|
-
from dataclasses import dataclass
|
|
4
|
-
from datetime import datetime
|
|
5
|
-
from pathlib import Path
|
|
6
|
-
|
|
7
|
-
import structlog
|
|
8
|
-
|
|
9
|
-
from datacosmos.stac.enums.processing_level import ProcessingLevel
|
|
10
|
-
from datacosmos.stac.item.models.datacosmos_item import DatacosmosItem
|
|
11
|
-
|
|
12
|
-
logger = structlog.get_logger()
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
@dataclass
|
|
16
|
-
class UploadPath:
|
|
17
|
-
"""Dataclass for retrieving the upload path of a file."""
|
|
18
|
-
|
|
19
|
-
mission: str
|
|
20
|
-
level: ProcessingLevel
|
|
21
|
-
day: int
|
|
22
|
-
month: int
|
|
23
|
-
year: int
|
|
24
|
-
id: str
|
|
25
|
-
path: str
|
|
26
|
-
|
|
27
|
-
def __str__(self):
|
|
28
|
-
"""Return a human-readable string representation of the Path."""
|
|
29
|
-
path = f"full/{self.mission.lower()}/{self.level.value.lower()}/{self.year:02}/{self.month:02}/{self.day:02}/{self.id}/{self.path}"
|
|
30
|
-
return path.removesuffix("/")
|
|
31
|
-
|
|
32
|
-
@classmethod
|
|
33
|
-
def from_item_path(
|
|
34
|
-
cls, item: DatacosmosItem, mission: str, item_path: str
|
|
35
|
-
) -> "Path":
|
|
36
|
-
"""Create a Path instance from a DatacosmosItem and a path."""
|
|
37
|
-
dt = datetime.strptime(item.properties["datetime"], "%Y-%m-%dT%H:%M:%SZ")
|
|
38
|
-
path = UploadPath(
|
|
39
|
-
mission=mission,
|
|
40
|
-
level=ProcessingLevel(item.properties["processing:level"]),
|
|
41
|
-
day=dt.day,
|
|
42
|
-
month=dt.month,
|
|
43
|
-
year=dt.year,
|
|
44
|
-
id=item.id,
|
|
45
|
-
path=item_path,
|
|
46
|
-
)
|
|
47
|
-
return cls(**path.__dict__)
|
|
48
|
-
|
|
49
|
-
@classmethod
|
|
50
|
-
def from_path(cls, path: str) -> "Path":
|
|
51
|
-
"""Create a Path instance from a string path."""
|
|
52
|
-
parts = path.split("/")
|
|
53
|
-
if len(parts) < 7:
|
|
54
|
-
raise ValueError(f"Invalid path {path}")
|
|
55
|
-
return cls(
|
|
56
|
-
mission=parts[0],
|
|
57
|
-
level=ProcessingLevel(parts[1]),
|
|
58
|
-
day=int(parts[4]),
|
|
59
|
-
month=int(parts[3]),
|
|
60
|
-
year=int(parts[2]),
|
|
61
|
-
id=parts[5],
|
|
62
|
-
path="/".join(parts[6:]),
|
|
63
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/config/models/m2m_authentication_config.py
RENAMED
|
File without changes
|
{datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/config/models/no_authentication_config.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/stac/collection/models/collection_update.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/stac/item/models/catalog_search_parameters.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/utils/http_response/check_api_response.py
RENAMED
|
File without changes
|
|
File without changes
|
{datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/utils/http_response/models/datacosmos_error.py
RENAMED
|
File without changes
|
{datacosmos-0.0.10 → datacosmos-0.0.12}/datacosmos/utils/http_response/models/datacosmos_response.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|