fairagro-middleware-api-client 8.7.1.dev8__tar.gz → 8.7.1.dev9__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.
- {fairagro_middleware_api_client-8.7.1.dev8 → fairagro_middleware_api_client-8.7.1.dev9}/PKG-INFO +1 -1
- {fairagro_middleware_api_client-8.7.1.dev8 → fairagro_middleware_api_client-8.7.1.dev9}/src/middleware/api_client/api_client.py +7 -5
- {fairagro_middleware_api_client-8.7.1.dev8 → fairagro_middleware_api_client-8.7.1.dev9}/tests/unit/test_client.py +16 -13
- {fairagro_middleware_api_client-8.7.1.dev8 → fairagro_middleware_api_client-8.7.1.dev9}/.gitignore +0 -0
- {fairagro_middleware_api_client-8.7.1.dev8 → fairagro_middleware_api_client-8.7.1.dev9}/README.md +0 -0
- {fairagro_middleware_api_client-8.7.1.dev8 → fairagro_middleware_api_client-8.7.1.dev9}/example_client_config.yaml +0 -0
- {fairagro_middleware_api_client-8.7.1.dev8 → fairagro_middleware_api_client-8.7.1.dev9}/pyproject.toml +0 -0
- {fairagro_middleware_api_client-8.7.1.dev8 → fairagro_middleware_api_client-8.7.1.dev9}/src/middleware/api_client/__init__.py +0 -0
- {fairagro_middleware_api_client-8.7.1.dev8 → fairagro_middleware_api_client-8.7.1.dev9}/src/middleware/api_client/config.py +0 -0
- {fairagro_middleware_api_client-8.7.1.dev8 → fairagro_middleware_api_client-8.7.1.dev9}/src/middleware/api_client/models.py +0 -0
- {fairagro_middleware_api_client-8.7.1.dev8 → fairagro_middleware_api_client-8.7.1.dev9}/src/middleware/api_client/py.typed +0 -0
- {fairagro_middleware_api_client-8.7.1.dev8 → fairagro_middleware_api_client-8.7.1.dev9}/tests/conftest.py +0 -0
- {fairagro_middleware_api_client-8.7.1.dev8 → fairagro_middleware_api_client-8.7.1.dev9}/tests/integration/conftest.py +0 -0
- {fairagro_middleware_api_client-8.7.1.dev8 → fairagro_middleware_api_client-8.7.1.dev9}/tests/integration/test_create_arcs.py +0 -0
- {fairagro_middleware_api_client-8.7.1.dev8 → fairagro_middleware_api_client-8.7.1.dev9}/tests/unit/test_api_client_config.py +0 -0
- {fairagro_middleware_api_client-8.7.1.dev8 → fairagro_middleware_api_client-8.7.1.dev9}/tests/unit/test_client_config.py +0 -0
- {fairagro_middleware_api_client-8.7.1.dev8 → fairagro_middleware_api_client-8.7.1.dev9}/tests/unit/test_retry_logic.py +0 -0
|
@@ -280,12 +280,14 @@ class ApiClient:
|
|
|
280
280
|
identifier = self._extract_identifier_from_rocrate(serialized)
|
|
281
281
|
if identifier is not None:
|
|
282
282
|
if identifier in seen_identifiers:
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
283
|
+
logger.error(
|
|
284
|
+
"Skipping duplicate ARC identifier '%s' in harvest %s. "
|
|
285
|
+
"Two ARCs share the same identifier — this is a client-side data error.",
|
|
286
|
+
identifier,
|
|
287
|
+
harvest_id,
|
|
288
288
|
)
|
|
289
|
+
failed_submissions += 1
|
|
290
|
+
continue
|
|
289
291
|
seen_identifiers.add(identifier)
|
|
290
292
|
|
|
291
293
|
task = asyncio.create_task(submit_one(serialized))
|
|
@@ -714,11 +714,13 @@ async def test_harvest_arcs_cancels_on_catastrophic_error(client_config: Config)
|
|
|
714
714
|
|
|
715
715
|
@pytest.mark.asyncio
|
|
716
716
|
@respx.mock
|
|
717
|
-
async def
|
|
718
|
-
"""harvest_arcs
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
717
|
+
async def test_harvest_arcs_skips_duplicate_identifier(client_config: Config) -> None:
|
|
718
|
+
"""harvest_arcs skips a duplicate ARC and completes the harvest successfully.
|
|
719
|
+
|
|
720
|
+
When the same RO-Crate identifier appears twice in the input, the second
|
|
721
|
+
occurrence is counted as a failed submission and the harvest continues.
|
|
722
|
+
This prevents a single client-side data error from aborting the whole harvest.
|
|
723
|
+
"""
|
|
722
724
|
arc_a = {
|
|
723
725
|
"@context": "https://w3id.org/ro/crate/1.1/context",
|
|
724
726
|
"@graph": [{"@id": "./", "@type": "Dataset", "identifier": "duplicate-arc", "name": "ARC A"}],
|
|
@@ -727,23 +729,24 @@ async def test_harvest_arcs_fails_on_duplicate_identifier(client_config: Config)
|
|
|
727
729
|
"@context": "https://w3id.org/ro/crate/1.1/context",
|
|
728
730
|
"@graph": [{"@id": "./", "@type": "Dataset", "identifier": "duplicate-arc", "name": "ARC B"}],
|
|
729
731
|
}
|
|
730
|
-
|
|
732
|
+
completed_response = {**_HARVEST_RESPONSE, "status": "COMPLETED", "completed_at": "2024-01-01T01:00:00Z"}
|
|
731
733
|
respx.post(f"{client_config.api_url}v3/harvests").mock(
|
|
732
734
|
return_value=httpx.Response(http.HTTPStatus.OK, json=_HARVEST_RESPONSE)
|
|
733
735
|
)
|
|
734
|
-
#
|
|
735
|
-
respx.post(f"{client_config.api_url}v3/harvests/harvest-456/arcs").mock(
|
|
736
|
+
# Only the first ARC is submitted; the duplicate is skipped client-side.
|
|
737
|
+
arc_route = respx.post(f"{client_config.api_url}v3/harvests/harvest-456/arcs").mock(
|
|
736
738
|
return_value=httpx.Response(http.HTTPStatus.OK, json=_ARC_RESPONSE)
|
|
737
739
|
)
|
|
738
|
-
|
|
739
|
-
return_value=httpx.Response(http.HTTPStatus.OK, json=
|
|
740
|
+
complete_route = respx.post(f"{client_config.api_url}v3/harvests/harvest-456/complete").mock(
|
|
741
|
+
return_value=httpx.Response(http.HTTPStatus.OK, json=completed_response)
|
|
740
742
|
)
|
|
741
743
|
|
|
742
744
|
async with ApiClient(client_config) as client:
|
|
743
|
-
|
|
744
|
-
await client.harvest_arcs("test-rdi", _arc_gen(arc_a, arc_b))
|
|
745
|
+
result = await client.harvest_arcs("test-rdi", _arc_gen(arc_a, arc_b))
|
|
745
746
|
|
|
746
|
-
assert
|
|
747
|
+
assert result.status == "COMPLETED"
|
|
748
|
+
assert arc_route.call_count == 1 # duplicate was skipped, not submitted
|
|
749
|
+
assert complete_route.called
|
|
747
750
|
|
|
748
751
|
|
|
749
752
|
@pytest.mark.asyncio
|
{fairagro_middleware_api_client-8.7.1.dev8 → fairagro_middleware_api_client-8.7.1.dev9}/.gitignore
RENAMED
|
File without changes
|
{fairagro_middleware_api_client-8.7.1.dev8 → fairagro_middleware_api_client-8.7.1.dev9}/README.md
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
|
|
File without changes
|