clue-api 1.5.0.dev295__tar.gz → 1.5.0.dev305__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 (99) hide show
  1. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/PKG-INFO +1 -1
  2. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/actions.py +32 -3
  3. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/pyproject.toml +1 -1
  4. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/LICENSE +0 -0
  5. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/README.md +0 -0
  6. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/.gitignore +0 -0
  7. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/__init__.py +0 -0
  8. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/api/__init__.py +0 -0
  9. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/api/base.py +0 -0
  10. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/api/v1/__init__.py +0 -0
  11. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/api/v1/actions.py +0 -0
  12. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/api/v1/auth.py +0 -0
  13. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/api/v1/configs.py +0 -0
  14. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/api/v1/fetchers.py +0 -0
  15. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/api/v1/lookup.py +0 -0
  16. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/api/v1/registration.py +0 -0
  17. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/api/v1/static.py +0 -0
  18. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/api/v1/sync.py +0 -0
  19. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/app.py +0 -0
  20. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/cache/__init__.py +0 -0
  21. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/common/__init__.py +0 -0
  22. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/common/bytes_utils.py +0 -0
  23. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/common/classification.py +0 -0
  24. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/common/classification.yml +0 -0
  25. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/common/dict_utils.py +0 -0
  26. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/common/exceptions.py +0 -0
  27. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/common/forge.py +0 -0
  28. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/common/json_utils.py +0 -0
  29. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/common/list_utils.py +0 -0
  30. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/common/logging/__init__.py +0 -0
  31. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/common/logging/audit.py +0 -0
  32. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/common/logging/format.py +0 -0
  33. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/common/regex.py +0 -0
  34. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/common/str_utils.py +0 -0
  35. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/common/swagger.py +0 -0
  36. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/common/uid.py +0 -0
  37. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/config.py +0 -0
  38. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/constants/__init__.py +0 -0
  39. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/constants/env.py +0 -0
  40. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/constants/supported_types.py +0 -0
  41. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/cronjobs/__init__.py +0 -0
  42. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/cronjobs/plugins.py +0 -0
  43. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/error.py +0 -0
  44. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/extensions/__init__.py +0 -0
  45. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/extensions/config.py +0 -0
  46. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/gunicorn_config.py +0 -0
  47. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/healthz.py +0 -0
  48. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/helper/discover.py +0 -0
  49. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/helper/headers.py +0 -0
  50. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/helper/oauth.py +0 -0
  51. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/__init__.py +0 -0
  52. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/config.py +0 -0
  53. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/fetchers.py +0 -0
  54. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/graph.py +0 -0
  55. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/model_list.py +0 -0
  56. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/network.py +0 -0
  57. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/results/__init__.py +0 -0
  58. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/results/base.py +0 -0
  59. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/results/file.py +0 -0
  60. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/results/graph.py +0 -0
  61. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/results/image.py +0 -0
  62. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/results/status.py +0 -0
  63. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/results/validation.py +0 -0
  64. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/schema.py +0 -0
  65. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/selector.py +0 -0
  66. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/sync.py +0 -0
  67. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/validators.py +0 -0
  68. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/patched.py +0 -0
  69. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/plugin/__init__.py +0 -0
  70. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/plugin/celery_app.py +0 -0
  71. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/plugin/helpers/__init__.py +0 -0
  72. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/plugin/helpers/central_server.py +0 -0
  73. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/plugin/helpers/email_render.py +0 -0
  74. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/plugin/helpers/token.py +0 -0
  75. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/plugin/helpers/trino.py +0 -0
  76. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/plugin/models.py +0 -0
  77. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/plugin/utils.py +0 -0
  78. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/py.typed +0 -0
  79. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/remote/__init__.py +0 -0
  80. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/remote/datatypes/__init__.py +0 -0
  81. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/remote/datatypes/cache.py +0 -0
  82. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/remote/datatypes/events.py +0 -0
  83. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/remote/datatypes/hash.py +0 -0
  84. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/remote/datatypes/queues/__init__.py +0 -0
  85. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/remote/datatypes/queues/comms.py +0 -0
  86. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/remote/datatypes/set.py +0 -0
  87. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/remote/datatypes/user_quota_tracker.py +0 -0
  88. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/security/__init__.py +0 -0
  89. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/security/obo.py +0 -0
  90. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/security/utils.py +0 -0
  91. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/services/action_service.py +0 -0
  92. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/services/auth_service.py +0 -0
  93. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/services/config_service.py +0 -0
  94. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/services/fetcher_service.py +0 -0
  95. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/services/jwt_service.py +0 -0
  96. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/services/lookup_service.py +0 -0
  97. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/services/mongo_service.py +0 -0
  98. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/services/type_service.py +0 -0
  99. {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/services/user_service.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: clue-api
3
- Version: 1.5.0.dev295
3
+ Version: 1.5.0.dev305
4
4
  Summary: Clue distributed enrichment service
5
5
  License: MIT
6
6
  License-File: LICENSE
@@ -258,18 +258,32 @@ class Action(ActionBase, Generic[ER]):
258
258
  return data
259
259
 
260
260
 
261
+ class PendingActionOutput(BaseModel, Generic[DATA]):
262
+ model_config = ConfigDict(extra="forbid")
263
+
264
+ message: str | None = Field(
265
+ description="Optional message to display feedback or the current state of the pending action.",
266
+ default=None,
267
+ )
268
+ progress: float | None = Field(
269
+ description="Optional progress of the pending async action.", default=None, ge=0.0, le=1.0
270
+ )
271
+
272
+ partial_data: DATA | None = Field(description="Optional partial data of the pending async action.", default=None)
273
+
274
+
261
275
  class ActionResult(BaseModel, Generic[DATA]):
262
276
  outcome: Literal["success", "failure", "pending"] = Field(
263
277
  description="Did the action succeed/fail, or is it pending?"
264
278
  )
265
279
  summary: str | None = Field(description="Message explaining the outcome of the action.", default=None)
266
- output: DATA | Url | None = Field(description="The output of the action.", default=None)
280
+ output: DATA | Url | PendingActionOutput[DATA] | None = Field(description="The output of the action.", default=None)
267
281
  format: str | None = Field(
268
282
  description="What is the format of the output? Used to indicate what component to use when rendering "
269
283
  "the output.",
270
284
  default=None,
271
285
  )
272
- link: Url | None = Field(description="Link to more information on the outcome of the action", default=None)
286
+ link: Url | None = Field(description="Link to more information on the outcome of the action.", default=None)
273
287
  task_id: str | None = Field(description="The celery task id if the action is pending.", default=None)
274
288
 
275
289
  @model_validator(mode="after")
@@ -288,6 +302,18 @@ class ActionResult(BaseModel, Generic[DATA]):
288
302
  if not self.task_id and self.outcome == "pending":
289
303
  raise ClueValueError("task_id must be set if outcome is pending.")
290
304
 
305
+ if self.outcome == "pending" and self.output is not None:
306
+ try:
307
+ self.output = PendingActionOutput[DATA].model_validate(self.output)
308
+ if self.output.partial_data is not None:
309
+ if self.format is None:
310
+ raise ClueValueError("You must set a format if partial_data is provided in output.")
311
+ else:
312
+ self.output.partial_data = validate_result(self.format, self.output.partial_data, info)
313
+
314
+ except ValidationError as exc:
315
+ raise ClueValueError("output must be a valid PendingActionOutput when outcome is pending.") from exc
316
+
291
317
  if self.format == "pivot" and (not self.output or not isinstance(self.output, Url)):
292
318
  if isinstance(self.output, str):
293
319
  try:
@@ -301,7 +327,10 @@ class ActionResult(BaseModel, Generic[DATA]):
301
327
  if self.format != "pivot" and isinstance(self.output, Url):
302
328
  raise ClueValueError("You can only return a Url if format is set to pivot.")
303
329
 
304
- if self.format and not isinstance(self.output, Url):
330
+ if self.outcome != "pending" and isinstance(self.output, PendingActionOutput):
331
+ raise ClueValueError("output must not be PendingActionOutput unless outcome is pending.")
332
+
333
+ if self.format and not isinstance(self.output, Url) and not isinstance(self.output, PendingActionOutput):
305
334
  self.output = validate_result(self.format, self.output, info)
306
335
 
307
336
  return self
@@ -141,7 +141,7 @@ log_cli_level = "WARN"
141
141
  [tool.poetry]
142
142
  package-mode = true
143
143
  name = "clue-api"
144
- version = "1.5.0.dev295"
144
+ version = "1.5.0.dev305"
145
145
  description = "Clue distributed enrichment service"
146
146
  authors = ["Canadian Centre for Cyber Security <contact@cyber.gc.ca>"]
147
147
  license = "MIT"
File without changes