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.
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/PKG-INFO +1 -1
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/actions.py +32 -3
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/pyproject.toml +1 -1
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/LICENSE +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/README.md +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/.gitignore +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/__init__.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/api/__init__.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/api/base.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/api/v1/__init__.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/api/v1/actions.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/api/v1/auth.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/api/v1/configs.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/api/v1/fetchers.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/api/v1/lookup.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/api/v1/registration.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/api/v1/static.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/api/v1/sync.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/app.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/cache/__init__.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/common/__init__.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/common/bytes_utils.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/common/classification.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/common/classification.yml +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/common/dict_utils.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/common/exceptions.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/common/forge.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/common/json_utils.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/common/list_utils.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/common/logging/__init__.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/common/logging/audit.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/common/logging/format.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/common/regex.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/common/str_utils.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/common/swagger.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/common/uid.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/config.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/constants/__init__.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/constants/env.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/constants/supported_types.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/cronjobs/__init__.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/cronjobs/plugins.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/error.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/extensions/__init__.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/extensions/config.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/gunicorn_config.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/healthz.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/helper/discover.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/helper/headers.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/helper/oauth.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/__init__.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/config.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/fetchers.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/graph.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/model_list.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/network.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/results/__init__.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/results/base.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/results/file.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/results/graph.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/results/image.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/results/status.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/results/validation.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/schema.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/selector.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/sync.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/models/validators.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/patched.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/plugin/__init__.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/plugin/celery_app.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/plugin/helpers/__init__.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/plugin/helpers/central_server.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/plugin/helpers/email_render.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/plugin/helpers/token.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/plugin/helpers/trino.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/plugin/models.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/plugin/utils.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/py.typed +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/remote/__init__.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/remote/datatypes/__init__.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/remote/datatypes/cache.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/remote/datatypes/events.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/remote/datatypes/hash.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/remote/datatypes/queues/__init__.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/remote/datatypes/queues/comms.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/remote/datatypes/set.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/remote/datatypes/user_quota_tracker.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/security/__init__.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/security/obo.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/security/utils.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/services/action_service.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/services/auth_service.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/services/config_service.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/services/fetcher_service.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/services/jwt_service.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/services/lookup_service.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/services/mongo_service.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/services/type_service.py +0 -0
- {clue_api-1.5.0.dev295 → clue_api-1.5.0.dev305}/clue/services/user_service.py +0 -0
|
@@ -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.
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|