portolan-python 0.1.1__tar.gz → 0.1.2__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.
- {portolan_python-0.1.1 → portolan_python-0.1.2}/.coverage +0 -0
- {portolan_python-0.1.1 → portolan_python-0.1.2}/PKG-INFO +1 -1
- {portolan_python-0.1.1 → portolan_python-0.1.2}/pyproject.toml +1 -1
- {portolan_python-0.1.1 → portolan_python-0.1.2}/src/portolan/registry.py +8 -1
- {portolan_python-0.1.1 → portolan_python-0.1.2}/tests/test_registry_api.py +27 -0
- {portolan_python-0.1.1 → portolan_python-0.1.2}/uv.lock +1 -1
- {portolan_python-0.1.1 → portolan_python-0.1.2}/.github/workflows/release.yml +0 -0
- {portolan_python-0.1.1 → portolan_python-0.1.2}/.gitignore +0 -0
- {portolan_python-0.1.1 → portolan_python-0.1.2}/Makefile +0 -0
- {portolan_python-0.1.1 → portolan_python-0.1.2}/README.md +0 -0
- {portolan_python-0.1.1 → portolan_python-0.1.2}/docs/development.md +0 -0
- {portolan_python-0.1.1 → portolan_python-0.1.2}/docs/distribution.md +0 -0
- {portolan_python-0.1.1 → portolan_python-0.1.2}/docs/examples.md +0 -0
- {portolan_python-0.1.1 → portolan_python-0.1.2}/docs/scope.md +0 -0
- {portolan_python-0.1.1 → portolan_python-0.1.2}/src/portolan/__init__.py +0 -0
- {portolan_python-0.1.1 → portolan_python-0.1.2}/src/portolan/catalog.py +0 -0
- {portolan_python-0.1.1 → portolan_python-0.1.2}/src/portolan/py.typed +0 -0
- {portolan_python-0.1.1 → portolan_python-0.1.2}/src/portolan/validation.py +0 -0
- {portolan_python-0.1.1 → portolan_python-0.1.2}/tests/test_catalog_api.py +0 -0
|
Binary file
|
|
@@ -106,7 +106,12 @@ def _write_catalog_tree(
|
|
|
106
106
|
root_url: str,
|
|
107
107
|
output_root: Path,
|
|
108
108
|
fetch_json: Callable[[str], JsonObject],
|
|
109
|
+
visited: set[str] | None = None,
|
|
109
110
|
) -> None:
|
|
111
|
+
if visited is None:
|
|
112
|
+
visited = set()
|
|
113
|
+
visited.add(document_url)
|
|
114
|
+
|
|
110
115
|
relative_path = _relative_document_path(root_url, document_url)
|
|
111
116
|
target = output_root / relative_path
|
|
112
117
|
target.parent.mkdir(parents=True, exist_ok=True)
|
|
@@ -121,9 +126,11 @@ def _write_catalog_tree(
|
|
|
121
126
|
if not isinstance(href, str):
|
|
122
127
|
continue
|
|
123
128
|
child_url = urljoin(document_url, href)
|
|
129
|
+
if child_url in visited:
|
|
130
|
+
continue
|
|
124
131
|
child = fetch_json(child_url)
|
|
125
132
|
if child.get("type") in {"Catalog", "Collection"}:
|
|
126
|
-
_write_catalog_tree(child_url, child, root_url, output_root, fetch_json)
|
|
133
|
+
_write_catalog_tree(child_url, child, root_url, output_root, fetch_json, visited)
|
|
127
134
|
|
|
128
135
|
|
|
129
136
|
def _with_absolute_asset_hrefs(document_url: str, collection: JsonObject) -> JsonObject:
|
|
@@ -169,6 +169,33 @@ def test_download_registry_catalog_writes_snapshot_with_absolute_asset_hrefs(
|
|
|
169
169
|
assert collection["assets"]["data"]["href"] == "https://example.test/demo/roads/roads.parquet"
|
|
170
170
|
|
|
171
171
|
|
|
172
|
+
def test_download_registry_catalog_skips_child_cycles(tmp_path: Path) -> None:
|
|
173
|
+
root_url = "https://example.test/demo/catalog.json"
|
|
174
|
+
child_url = "https://example.test/demo/roads/collection.json"
|
|
175
|
+
responses = {
|
|
176
|
+
root_url: {
|
|
177
|
+
"type": "Catalog",
|
|
178
|
+
"id": "demo",
|
|
179
|
+
"links": [{"rel": "child", "href": "./roads/collection.json"}],
|
|
180
|
+
},
|
|
181
|
+
child_url: {
|
|
182
|
+
**_collection("roads", {}),
|
|
183
|
+
"links": [{"rel": "child", "href": "../catalog.json"}],
|
|
184
|
+
},
|
|
185
|
+
}
|
|
186
|
+
fetched_urls: list[str] = []
|
|
187
|
+
|
|
188
|
+
def fetch_json(url: str) -> dict[str, Any]:
|
|
189
|
+
fetched_urls.append(url)
|
|
190
|
+
if fetched_urls.count(url) > 1:
|
|
191
|
+
raise AssertionError(f"Fetched document twice: {url}")
|
|
192
|
+
return responses[url]
|
|
193
|
+
|
|
194
|
+
download_registry_catalog(root_url, tmp_path, fetch_json=fetch_json)
|
|
195
|
+
|
|
196
|
+
assert fetched_urls == [root_url, child_url]
|
|
197
|
+
|
|
198
|
+
|
|
172
199
|
def test_download_registry_catalog_recurses_nested_catalogs_and_uses_fallback_id(
|
|
173
200
|
tmp_path: Path,
|
|
174
201
|
) -> None:
|
|
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
|
|
File without changes
|
|
File without changes
|