sws-api-client 3.1.0__tar.gz → 3.2.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.
Files changed (31) hide show
  1. {sws_api_client-3.1.0 → sws_api_client-3.2.0}/PKG-INFO +8 -1
  2. {sws_api_client-3.1.0 → sws_api_client-3.2.0}/README.md +7 -0
  3. {sws_api_client-3.1.0 → sws_api_client-3.2.0}/pyproject.toml +1 -1
  4. {sws_api_client-3.1.0 → sws_api_client-3.2.0}/sws_api_client/__init__.py +1 -1
  5. {sws_api_client-3.1.0 → sws_api_client-3.2.0}/sws_api_client/campaign_manager.py +15 -4
  6. {sws_api_client-3.1.0 → sws_api_client-3.2.0}/.gitignore +0 -0
  7. {sws_api_client-3.1.0 → sws_api_client-3.2.0}/LICENSE +0 -0
  8. {sws_api_client-3.1.0 → sws_api_client-3.2.0}/sws_api_client/auth.py +0 -0
  9. {sws_api_client-3.1.0 → sws_api_client-3.2.0}/sws_api_client/case_agnostic_model.py +0 -0
  10. {sws_api_client-3.1.0 → sws_api_client-3.2.0}/sws_api_client/codelist.py +0 -0
  11. {sws_api_client-3.1.0 → sws_api_client-3.2.0}/sws_api_client/data_retrieval.py +0 -0
  12. {sws_api_client-3.1.0 → sws_api_client-3.2.0}/sws_api_client/datasets.py +0 -0
  13. {sws_api_client-3.1.0 → sws_api_client-3.2.0}/sws_api_client/datatable.py +0 -0
  14. {sws_api_client-3.1.0 → sws_api_client-3.2.0}/sws_api_client/db.py +0 -0
  15. {sws_api_client-3.1.0 → sws_api_client-3.2.0}/sws_api_client/discover.py +0 -0
  16. {sws_api_client-3.1.0 → sws_api_client-3.2.0}/sws_api_client/files.py +0 -0
  17. {sws_api_client-3.1.0 → sws_api_client-3.2.0}/sws_api_client/flaglist.py +0 -0
  18. {sws_api_client-3.1.0 → sws_api_client-3.2.0}/sws_api_client/generic_models.py +0 -0
  19. {sws_api_client-3.1.0 → sws_api_client-3.2.0}/sws_api_client/harvester.py +0 -0
  20. {sws_api_client-3.1.0 → sws_api_client-3.2.0}/sws_api_client/mail.py +0 -0
  21. {sws_api_client-3.1.0 → sws_api_client-3.2.0}/sws_api_client/metadata_instances.py +0 -0
  22. {sws_api_client-3.1.0 → sws_api_client-3.2.0}/sws_api_client/plugins.py +0 -0
  23. {sws_api_client-3.1.0 → sws_api_client-3.2.0}/sws_api_client/s3.py +0 -0
  24. {sws_api_client-3.1.0 → sws_api_client-3.2.0}/sws_api_client/schemas/validation-report.schema.json +0 -0
  25. {sws_api_client-3.1.0 → sws_api_client-3.2.0}/sws_api_client/sessions.py +0 -0
  26. {sws_api_client-3.1.0 → sws_api_client-3.2.0}/sws_api_client/sws_api_client.py +0 -0
  27. {sws_api_client-3.1.0 → sws_api_client-3.2.0}/sws_api_client/tags.py +0 -0
  28. {sws_api_client-3.1.0 → sws_api_client-3.2.0}/sws_api_client/tasks.py +0 -0
  29. {sws_api_client-3.1.0 → sws_api_client-3.2.0}/sws_api_client/token.py +0 -0
  30. {sws_api_client-3.1.0 → sws_api_client-3.2.0}/sws_api_client/users.py +0 -0
  31. {sws_api_client-3.1.0 → sws_api_client-3.2.0}/sws_api_client/validation_report.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: sws_api_client
3
- Version: 3.1.0
3
+ Version: 3.2.0
4
4
  Author-email: Matteo <matteo.terrinoni@fao.org>, Daniele <daniele.mansillo@fao.org>, Luca <luca.simi@fao.org>
5
5
  License-File: LICENSE
6
6
  Requires-Python: <4,>=3.10
@@ -235,3 +235,10 @@ The `main` branch is the production branch. Any commit to the main branch will c
235
235
 
236
236
  ### Release
237
237
  Migrated to github test 6
238
+
239
+ ### Harvest attempt correlation
240
+
241
+ Pass the CM event file entry’s `attemptId` as `attempt_id=` to `claim_harvest`,
242
+ `heartbeat_harvest` and `complete_harvest`. Keep that identity through success and failure;
243
+ never look up the file’s newest attempt to complete an older run. Omitting the argument preserves
244
+ the request body used by legacy events.
@@ -221,3 +221,10 @@ The `main` branch is the production branch. Any commit to the main branch will c
221
221
 
222
222
  ### Release
223
223
  Migrated to github test 6
224
+
225
+ ### Harvest attempt correlation
226
+
227
+ Pass the CM event file entry’s `attemptId` as `attempt_id=` to `claim_harvest`,
228
+ `heartbeat_harvest` and `complete_harvest`. Keep that identity through success and failure;
229
+ never look up the file’s newest attempt to complete an older run. Omitting the argument preserves
230
+ the request body used by legacy events.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "sws_api_client"
3
- version = "3.1.0"
3
+ version = "3.2.0"
4
4
  description = ""
5
5
  authors = [
6
6
  { name = "Matteo", email = "matteo.terrinoni@fao.org" },
@@ -58,4 +58,4 @@ from .tasks import PluginPayload, TaskDataset, TaskInfo, TaskManager, TaskRespon
58
58
  from .users import User, Users
59
59
  from .harvester import Harvester
60
60
 
61
- __version__ = "3.1.0"
61
+ __version__ = "3.2.0"
@@ -568,13 +568,16 @@ class CampaignManager:
568
568
  file_id: Union[int, str],
569
569
  task_id: str,
570
570
  expires_at: Optional[str] = None,
571
+ *,
572
+ attempt_id: Optional[str] = None,
571
573
  ) -> Dict[str, Any]:
572
- """Take the job of putting this questionnaire's data into SWS."""
574
+ """Claim the event's harvest attempt; omit attempt_id only for legacy events."""
573
575
  return self._call(
574
576
  "POST",
575
577
  f"/api/v1/files/{file_id}/harvest/processing",
576
578
  params={"teamId": team_id},
577
- json_body={"taskId": task_id, "expiresAt": expires_at},
579
+ json_body={"taskId": task_id, "expiresAt": expires_at,
580
+ **({"attemptId": attempt_id} if attempt_id is not None else {})},
578
581
  )
579
582
 
580
583
  def heartbeat_harvest(
@@ -583,13 +586,16 @@ class CampaignManager:
583
586
  file_id: Union[int, str],
584
587
  expires_at: str,
585
588
  reason: Optional[str] = None,
589
+ *,
590
+ attempt_id: Optional[str] = None,
586
591
  ) -> Dict[str, Any]:
587
- """Still alive — see :meth:`heartbeat_validation`."""
592
+ """Keep the same harvest attempt alive — see :meth:`heartbeat_validation`."""
588
593
  return self._call(
589
594
  "PUT",
590
595
  f"/api/v1/files/{file_id}/harvest/status",
591
596
  params={"teamId": team_id},
592
- json_body={"status": "PENDING", "reason": reason, "expiresAt": expires_at},
597
+ json_body={"status": "PENDING", "reason": reason, "expiresAt": expires_at,
598
+ **({"attemptId": attempt_id} if attempt_id is not None else {})},
593
599
  )
594
600
 
595
601
  def complete_harvest(
@@ -600,9 +606,13 @@ class CampaignManager:
600
606
  reason: Optional[str] = None,
601
607
  result: Optional[Dict[str, Any]] = None,
602
608
  outputs: Optional[List["RunOutput"]] = None,
609
+ *,
610
+ attempt_id: Optional[str] = None,
603
611
  ) -> Dict[str, Any]:
604
612
  """How taking the data in went — and where it went.
605
613
 
614
+ ``attempt_id`` identifies the original request even if another harvest has started.
615
+
606
616
  Harvesting is the one verb whose output is not a file: the data lands inside SWS. So the
607
617
  result travels with the outcome (``{"rows": …, "dataset": …, "session": …}``, or whatever the
608
618
  harvester can say), because without it the platform records that something was taken in and
@@ -613,6 +623,7 @@ class CampaignManager:
613
623
  f"/api/v1/files/{file_id}/harvest/complete",
614
624
  params={"teamId": team_id},
615
625
  json_body={
626
+ **({"attemptId": attempt_id} if attempt_id is not None else {}),
616
627
  "outcome": outcome,
617
628
  "reason": reason,
618
629
  "result": result,
File without changes