arthur-common 1.0.1__py3-none-any.whl

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.

Potentially problematic release.


This version of arthur-common might be problematic. Click here for more details.

Files changed (40) hide show
  1. arthur_common/__init__.py +0 -0
  2. arthur_common/__version__.py +1 -0
  3. arthur_common/aggregations/__init__.py +2 -0
  4. arthur_common/aggregations/aggregator.py +214 -0
  5. arthur_common/aggregations/functions/README.md +26 -0
  6. arthur_common/aggregations/functions/__init__.py +25 -0
  7. arthur_common/aggregations/functions/categorical_count.py +89 -0
  8. arthur_common/aggregations/functions/confusion_matrix.py +412 -0
  9. arthur_common/aggregations/functions/inference_count.py +69 -0
  10. arthur_common/aggregations/functions/inference_count_by_class.py +206 -0
  11. arthur_common/aggregations/functions/inference_null_count.py +82 -0
  12. arthur_common/aggregations/functions/mean_absolute_error.py +110 -0
  13. arthur_common/aggregations/functions/mean_squared_error.py +110 -0
  14. arthur_common/aggregations/functions/multiclass_confusion_matrix.py +205 -0
  15. arthur_common/aggregations/functions/multiclass_inference_count_by_class.py +90 -0
  16. arthur_common/aggregations/functions/numeric_stats.py +90 -0
  17. arthur_common/aggregations/functions/numeric_sum.py +87 -0
  18. arthur_common/aggregations/functions/py.typed +0 -0
  19. arthur_common/aggregations/functions/shield_aggregations.py +752 -0
  20. arthur_common/aggregations/py.typed +0 -0
  21. arthur_common/models/__init__.py +0 -0
  22. arthur_common/models/connectors.py +41 -0
  23. arthur_common/models/datasets.py +22 -0
  24. arthur_common/models/metrics.py +227 -0
  25. arthur_common/models/py.typed +0 -0
  26. arthur_common/models/schema_definitions.py +420 -0
  27. arthur_common/models/shield.py +504 -0
  28. arthur_common/models/task_job_specs.py +78 -0
  29. arthur_common/py.typed +0 -0
  30. arthur_common/tools/__init__.py +0 -0
  31. arthur_common/tools/aggregation_analyzer.py +243 -0
  32. arthur_common/tools/aggregation_loader.py +59 -0
  33. arthur_common/tools/duckdb_data_loader.py +329 -0
  34. arthur_common/tools/functions.py +46 -0
  35. arthur_common/tools/py.typed +0 -0
  36. arthur_common/tools/schema_inferer.py +104 -0
  37. arthur_common/tools/time_utils.py +33 -0
  38. arthur_common-1.0.1.dist-info/METADATA +74 -0
  39. arthur_common-1.0.1.dist-info/RECORD +40 -0
  40. arthur_common-1.0.1.dist-info/WHEEL +4 -0
@@ -0,0 +1,504 @@
1
+ from enum import Enum
2
+ from typing import Any, Dict, List, Optional, Self, Type, Union
3
+
4
+ from fastapi import HTTPException
5
+ from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
6
+
7
+ DEFAULT_TOXICITY_RULE_THRESHOLD = 0.5
8
+ DEFAULT_PII_RULE_CONFIDENCE_SCORE_THRESHOLD = 0
9
+
10
+
11
+ class RuleType(str, Enum):
12
+ KEYWORD = "KeywordRule"
13
+ MODEL_HALLUCINATION = "ModelHallucinationRule"
14
+ MODEL_HALLUCINATION_V2 = "ModelHallucinationRuleV2"
15
+ MODEL_HALLUCINATION_V3 = "ModelHallucinationRuleV3"
16
+ MODEL_SENSITIVE_DATA = "ModelSensitiveDataRule"
17
+ PII_DATA = "PIIDataRule"
18
+ PROMPT_INJECTION = "PromptInjectionRule"
19
+ REGEX = "RegexRule"
20
+ TOXICITY = "ToxicityRule"
21
+
22
+ def __str__(self) -> str:
23
+ return self.value
24
+
25
+
26
+ class RuleScope(str, Enum):
27
+ DEFAULT = "default"
28
+ TASK = "task"
29
+
30
+
31
+ class BaseEnum(str, Enum):
32
+ @classmethod
33
+ def values(cls) -> list[Any]:
34
+ values: list[str] = [e for e in cls]
35
+ return values
36
+
37
+ def __str__(self) -> Any:
38
+ return self.value
39
+
40
+
41
+ # Note: These string values are not arbitrary and map to Presidio entity types: https://microsoft.github.io/presidio/supported_entities/
42
+ class PIIEntityTypes(BaseEnum):
43
+ CREDIT_CARD = "CREDIT_CARD"
44
+ CRYPTO = "CRYPTO"
45
+ DATE_TIME = "DATE_TIME"
46
+ EMAIL_ADDRESS = "EMAIL_ADDRESS"
47
+ IBAN_CODE = "IBAN_CODE"
48
+ IP_ADDRESS = "IP_ADDRESS"
49
+ NRP = "NRP"
50
+ LOCATION = "LOCATION"
51
+ PERSON = "PERSON"
52
+ PHONE_NUMBER = "PHONE_NUMBER"
53
+ MEDICAL_LICENSE = "MEDICAL_LICENSE"
54
+ URL = "URL"
55
+ US_BANK_NUMBER = "US_BANK_NUMBER"
56
+ US_DRIVER_LICENSE = "US_DRIVER_LICENSE"
57
+ US_ITIN = "US_ITIN"
58
+ US_PASSPORT = "US_PASSPORT"
59
+ US_SSN = "US_SSN"
60
+
61
+ @classmethod
62
+ def to_string(cls) -> str:
63
+ return ",".join(member.value for member in cls)
64
+
65
+
66
+ class KeywordsConfig(BaseModel):
67
+ keywords: List[str] = Field(description="List of Keywords")
68
+
69
+ model_config = ConfigDict(
70
+ json_schema_extra={
71
+ "example": {"keywords": ["Blocked_Keyword_1", "Blocked_Keyword_2"]},
72
+ },
73
+ )
74
+
75
+
76
+ class RegexConfig(BaseModel):
77
+ regex_patterns: List[str] = Field(
78
+ description="List of Regex patterns to be used for validation. Be sure to encode requests in JSON and account for escape characters.",
79
+ )
80
+
81
+ model_config = ConfigDict(
82
+ json_schema_extra={
83
+ "example": {
84
+ "regex_patterns": ["\\d{3}-\\d{2}-\\d{4}", "\\d{5}-\\d{6}-\\d{7}"],
85
+ },
86
+ },
87
+ extra="forbid",
88
+ )
89
+
90
+
91
+ class ToxicityConfig(BaseModel):
92
+ threshold: float = Field(
93
+ default=DEFAULT_TOXICITY_RULE_THRESHOLD,
94
+ description=f"Optional. Float (0, 1) indicating the level of tolerable toxicity to consider the rule passed or failed. Min: 0 (no toxic language) Max: 1 (very toxic language). Default: {DEFAULT_TOXICITY_RULE_THRESHOLD}",
95
+ )
96
+
97
+ model_config = ConfigDict(
98
+ extra="forbid",
99
+ json_schema_extra={"example": {"threshold": DEFAULT_TOXICITY_RULE_THRESHOLD}},
100
+ )
101
+
102
+ @field_validator("threshold")
103
+ def validate_toxicity_threshold(cls, v: float) -> float:
104
+ if v and ((v < 0) | (v > 1)):
105
+ raise ValueError(f'"threshold" must be between 0 and 1')
106
+ return v
107
+
108
+
109
+ class PIIConfig(BaseModel):
110
+ disabled_pii_entities: Optional[list[str]] = Field(
111
+ description=f"Optional. List of PII entities to disable. Valid values are: {PIIEntityTypes.to_string()}",
112
+ default=None,
113
+ )
114
+
115
+ confidence_threshold: Optional[float] = Field(
116
+ description=f"Optional. Float (0, 1) indicating the level of tolerable PII to consider the rule passed or failed. Min: 0 (less confident) Max: 1 (very confident). Default: {DEFAULT_PII_RULE_CONFIDENCE_SCORE_THRESHOLD}",
117
+ default=DEFAULT_PII_RULE_CONFIDENCE_SCORE_THRESHOLD,
118
+ json_schema_extra={"deprecated": True},
119
+ )
120
+
121
+ allow_list: Optional[list[str]] = Field(
122
+ description="Optional. List of strings to pass PII validation.",
123
+ default=None,
124
+ )
125
+
126
+ @field_validator("disabled_pii_entities")
127
+ def validate_pii_entities(cls, v: Optional[List[str]]) -> Optional[List[str]]:
128
+ if v:
129
+ entities_passed = set(v)
130
+ entities_supported = set(PIIEntityTypes.values())
131
+ invalid_entities = entities_passed - entities_supported
132
+ if invalid_entities:
133
+ raise ValueError(
134
+ f"The following values are not valid PII entities: {invalid_entities}",
135
+ )
136
+
137
+ # Fail the case where they are trying to disable all PII entity types
138
+ if (not invalid_entities) & (
139
+ len(entities_passed) == len(entities_supported)
140
+ ):
141
+ raise ValueError(
142
+ f"Cannot disable all supported PII entities on PIIDataRule",
143
+ )
144
+ return v
145
+ else:
146
+ return v
147
+
148
+ @field_validator("confidence_threshold")
149
+ def validate_confidence_threshold(cls, v: Optional[float]) -> Optional[float]:
150
+ if v and ((v < 0) | (v > 1)):
151
+ raise ValueError(f'"confidence_threshold" must be between 0 and 1')
152
+ return v
153
+
154
+ model_config = ConfigDict(
155
+ json_schema_extra={
156
+ "example": {
157
+ "disabled_pii_entities": ["PERSON", "URL"],
158
+ "confidence_threshold": "0.5",
159
+ "allow_list": ["arthur.ai", "Arthur"],
160
+ },
161
+ },
162
+ extra="forbid",
163
+ )
164
+
165
+
166
+ NEGATIVE_BLOOD_EXAMPLE = "John has O negative blood group"
167
+
168
+
169
+ class ExampleConfig(BaseModel):
170
+ example: str = Field(description="Custom example for the sensitive data")
171
+ result: bool = Field(
172
+ description="Boolean value representing if the example passes or fails the the sensitive "
173
+ "data rule ",
174
+ )
175
+
176
+ model_config = ConfigDict(
177
+ json_schema_extra={
178
+ "example": {"example": NEGATIVE_BLOOD_EXAMPLE, "result": True},
179
+ },
180
+ )
181
+
182
+
183
+ class ExamplesConfig(BaseModel):
184
+ examples: List[ExampleConfig] = Field(
185
+ description="List of all the examples for Sensitive Data Rule",
186
+ )
187
+
188
+ model_config = ConfigDict(
189
+ json_schema_extra={
190
+ "example": {
191
+ "examples": [
192
+ {"example": NEGATIVE_BLOOD_EXAMPLE, "result": True},
193
+ {
194
+ "example": "Most of the people have A positive blood group",
195
+ "result": False,
196
+ },
197
+ ],
198
+ "hint": "specific individual's blood type",
199
+ },
200
+ },
201
+ )
202
+ hint: Optional[str] = Field(
203
+ description="Optional. Hint added to describe what Sensitive Data Rule should be checking for",
204
+ default=None,
205
+ )
206
+
207
+ def to_dict(self) -> Dict[str, Any]:
208
+ d = self.__dict__
209
+ d["examples"] = [ex.__dict__ for ex in self.examples]
210
+ d["hint"] = self.hint
211
+ return d
212
+
213
+
214
+ class RuleResponse(BaseModel):
215
+ id: str = Field(description="ID of the Rule")
216
+ name: str = Field(description="Name of the Rule")
217
+ type: RuleType = Field(description="Type of Rule")
218
+ apply_to_prompt: bool = Field(description="Rule applies to prompt")
219
+ apply_to_response: bool = Field(description="Rule applies to response")
220
+ enabled: Optional[bool] = Field(
221
+ description="Rule is enabled for the task",
222
+ default=None,
223
+ )
224
+ scope: RuleScope = Field(
225
+ description="Scope of the rule. The rule can be set at default level or task level.",
226
+ )
227
+ # UNIX millis format
228
+ created_at: int = Field(
229
+ description="Time the rule was created in unix milliseconds",
230
+ )
231
+ updated_at: int = Field(
232
+ description="Time the rule was updated in unix milliseconds",
233
+ )
234
+ # added a title to this to differentiate it in the generated client from the
235
+ # config field on the NewRuleRequest object
236
+ config: Optional[
237
+ Union[KeywordsConfig, RegexConfig, ExamplesConfig, ToxicityConfig, PIIConfig]
238
+ ] = Field(
239
+ description="Config of the rule",
240
+ default=None,
241
+ title="Rule Response Config",
242
+ )
243
+
244
+
245
+ class TaskResponse(BaseModel):
246
+ id: str = Field(description=" ID of the task")
247
+ name: str = Field(description="Name of the task")
248
+ created_at: int = Field(
249
+ description="Time the task was created in unix milliseconds",
250
+ )
251
+ updated_at: int = Field(
252
+ description="Time the task was created in unix milliseconds",
253
+ )
254
+ rules: List[RuleResponse] = Field(description="List of all the rules for the task.")
255
+
256
+
257
+ class UpdateRuleRequest(BaseModel):
258
+ enabled: bool = Field(description="Boolean value to enable or disable the rule. ")
259
+
260
+
261
+ HALLUCINATION_RULE_NAME = "Hallucination Rule"
262
+
263
+
264
+ class NewRuleRequest(BaseModel):
265
+ name: str = Field(description="Name of the rule", examples=["SSN Regex Rule"])
266
+ type: str = Field(
267
+ description="Type of the rule. It can only be one of KeywordRule, RegexRule, "
268
+ "ModelSensitiveDataRule, ModelHallucinationRule, ModelHallucinationRuleV2, PromptInjectionRule, PIIDataRule",
269
+ examples=["RegexRule"],
270
+ )
271
+ apply_to_prompt: bool = Field(
272
+ description="Boolean value to enable or disable the rule for llm prompt",
273
+ examples=[True],
274
+ )
275
+ apply_to_response: bool = Field(
276
+ description="Boolean value to enable or disable the rule for llm response",
277
+ examples=[False],
278
+ )
279
+ config: Optional[
280
+ Union[RegexConfig, KeywordsConfig, ToxicityConfig, PIIConfig, ExamplesConfig]
281
+ ] = Field(description="Config for the rule", default=None)
282
+
283
+ model_config = ConfigDict(
284
+ json_schema_extra={
285
+ "example1": {
286
+ "summary": "Sensitive Data Example",
287
+ "description": "Sensitive Data Example with its required configuration",
288
+ "value": {
289
+ "name": "Sensitive Data Rule",
290
+ "type": "ModelSensitiveDataRule",
291
+ "apply_to_prompt": True,
292
+ "apply_to_response": False,
293
+ "config": {
294
+ "examples": [
295
+ {
296
+ "example": NEGATIVE_BLOOD_EXAMPLE,
297
+ "result": True,
298
+ },
299
+ {
300
+ "example": "Most of the people have A positive blood group",
301
+ "result": False,
302
+ },
303
+ ],
304
+ "hint": "specific individual's blood types",
305
+ },
306
+ },
307
+ },
308
+ "example2": {
309
+ "summary": "Regex Example",
310
+ "description": "Regex Example with its required configuration. Be sure to properly encode requests "
311
+ "using JSON libraries. For example, the regex provided encodes to a different string "
312
+ "when encoded to account for escape characters.",
313
+ "value": {
314
+ "name": "SSN Regex Rule",
315
+ "type": "RegexRule",
316
+ "apply_to_prompt": True,
317
+ "apply_to_response": True,
318
+ "config": {
319
+ "regex_patterns": [
320
+ "\\d{3}-\\d{2}-\\d{4}",
321
+ "\\d{5}-\\d{6}-\\d{7}",
322
+ ],
323
+ },
324
+ },
325
+ },
326
+ "example3": {
327
+ "summary": "Keywords Rule Example",
328
+ "description": "Keywords Rule Example with its required configuration",
329
+ "value": {
330
+ "name": "Blocked Keywords Rule",
331
+ "type": "KeywordRule",
332
+ "apply_to_prompt": True,
333
+ "apply_to_response": True,
334
+ "config": {"keywords": ["Blocked_Keyword_1", "Blocked_Keyword_2"]},
335
+ },
336
+ },
337
+ "example4": {
338
+ "summary": "Prompt Injection Rule Example",
339
+ "description": "Prompt Injection Rule Example, no configuration required",
340
+ "value": {
341
+ "name": "Prompt Injection Rule",
342
+ "type": "PromptInjectionRule",
343
+ "apply_to_prompt": True,
344
+ "apply_to_response": False,
345
+ },
346
+ },
347
+ "example5": {
348
+ "summary": "Hallucination Rule V1 Example (Deprecated)",
349
+ "description": "Hallucination Rule Example, no configuration required (This rule is deprecated. Use "
350
+ "ModelHallucinationRuleV2 instead.)",
351
+ "value": {
352
+ "name": HALLUCINATION_RULE_NAME,
353
+ "type": "ModelHallucinationRule",
354
+ "apply_to_prompt": False,
355
+ "apply_to_response": True,
356
+ },
357
+ },
358
+ "example6": {
359
+ "summary": "Hallucination Rule V2 Example",
360
+ "description": "Hallucination Rule Example, no configuration required",
361
+ "value": {
362
+ "name": HALLUCINATION_RULE_NAME,
363
+ "type": "ModelHallucinationRuleV2",
364
+ "apply_to_prompt": False,
365
+ "apply_to_response": True,
366
+ },
367
+ },
368
+ "example7": {
369
+ "summary": "Hallucination Rule V3 Example (Beta)",
370
+ "description": "Hallucination Rule Example, no configuration required. This rule is in beta and must "
371
+ "be enabled by the system administrator.",
372
+ "value": {
373
+ "name": HALLUCINATION_RULE_NAME,
374
+ "type": "ModelHallucinationRuleV3",
375
+ "apply_to_prompt": False,
376
+ "apply_to_response": True,
377
+ },
378
+ },
379
+ "example8": {
380
+ "summary": "PII Rule Example",
381
+ "description": f'PII Rule Example, no configuration required. "disabled_pii_entities", '
382
+ f'"confidence_threshold", and "allow_list" accepted. Valid value for '
383
+ f'"confidence_threshold" is 0.0-1.0. Valid values for "disabled_pii_entities" '
384
+ f"are {PIIEntityTypes.to_string()}",
385
+ "value": {
386
+ "name": "PII Rule",
387
+ "type": "PIIDataRule",
388
+ "apply_to_prompt": True,
389
+ "apply_to_response": True,
390
+ "config": {
391
+ "disabled_pii_entities": [
392
+ "EMAIL_ADDRESS",
393
+ "PHONE_NUMBER",
394
+ ],
395
+ "confidence_threshold": "0.5",
396
+ "allow_list": ["arthur.ai", "Arthur"],
397
+ },
398
+ },
399
+ },
400
+ "example9": {
401
+ "summary": "Toxicity Rule Example",
402
+ "description": "Toxicity Rule Example, no configuration required. Threshold accepted",
403
+ "value": {
404
+ "name": "Toxicity Rule",
405
+ "type": "ToxicityRule",
406
+ "apply_to_prompt": True,
407
+ "apply_to_response": True,
408
+ "config": {"threshold": 0.5},
409
+ },
410
+ },
411
+ },
412
+ )
413
+
414
+ @model_validator(mode="before")
415
+ def set_config_type(cls, values: Dict[str, Any]) -> Dict[str, Any]:
416
+ config_type_to_class: Dict[str, Type[BaseModel]] = {
417
+ RuleType.REGEX: RegexConfig,
418
+ RuleType.KEYWORD: KeywordsConfig,
419
+ RuleType.TOXICITY: ToxicityConfig,
420
+ RuleType.PII_DATA: PIIConfig,
421
+ RuleType.MODEL_SENSITIVE_DATA: ExamplesConfig,
422
+ }
423
+
424
+ config_type = values["type"]
425
+ config_class = config_type_to_class.get(config_type)
426
+
427
+ if config_class is not None:
428
+ config_values = values.get("config")
429
+ if config_values is None:
430
+ if config_type in [RuleType.REGEX, RuleType.KEYWORD]:
431
+ raise HTTPException(
432
+ status_code=400,
433
+ detail="This rule must be created with a config parameter",
434
+ )
435
+ config_values = {}
436
+ if isinstance(config_values, BaseModel):
437
+ config_values = config_values.model_dump()
438
+ values["config"] = config_class(**config_values)
439
+ return values
440
+
441
+ @model_validator(mode="after")
442
+ def check_prompt_or_response(self) -> Self:
443
+ if (self.type == RuleType.MODEL_SENSITIVE_DATA) and (
444
+ self.apply_to_response is True
445
+ ):
446
+ raise HTTPException(
447
+ status_code=400,
448
+ detail="ModelSensitiveDataRule can only be enabled for prompt. Please set the 'apply_to_response' "
449
+ "field to false.",
450
+ )
451
+ if (self.type == RuleType.PROMPT_INJECTION) and (
452
+ self.apply_to_response is True
453
+ ):
454
+ raise HTTPException(
455
+ status_code=400,
456
+ detail="PromptInjectionRule can only be enabled for prompt. Please set the 'apply_to_response' field "
457
+ "to false.",
458
+ )
459
+ if (self.type == RuleType.MODEL_HALLUCINATION) and (
460
+ self.apply_to_prompt is True
461
+ ):
462
+ raise HTTPException(
463
+ status_code=400,
464
+ detail="ModelHallucinationRule can only be enabled for response. Please set the 'apply_to_prompt' "
465
+ "field to false.",
466
+ )
467
+ if (self.type == RuleType.MODEL_HALLUCINATION_V2) and (
468
+ self.apply_to_prompt is True
469
+ ):
470
+ raise HTTPException(
471
+ status_code=400,
472
+ detail="ModelHallucinationRuleV2 can only be enabled for response. Please set the 'apply_to_prompt' "
473
+ "field to false.",
474
+ )
475
+ if (self.type == RuleType.MODEL_HALLUCINATION_V3) and (
476
+ self.apply_to_prompt is True
477
+ ):
478
+ raise HTTPException(
479
+ status_code=400,
480
+ detail="ModelHallucinationRuleV3 can only be enabled for response. Please set the "
481
+ "'apply_to_prompt' field to false.",
482
+ )
483
+ if (self.apply_to_prompt is False) and (self.apply_to_response is False):
484
+ raise HTTPException(
485
+ status_code=400,
486
+ detail="Rule must be either applied to the prompt or to the response.",
487
+ )
488
+
489
+ return self
490
+
491
+ @model_validator(mode="after")
492
+ def check_examples_non_null(self) -> Self:
493
+ if self.type == RuleType.MODEL_SENSITIVE_DATA:
494
+ config = self.config
495
+ if (
496
+ config is not None
497
+ and isinstance(config, ExamplesConfig)
498
+ and (config.examples is None or len(config.examples) == 0)
499
+ ):
500
+ raise HTTPException(
501
+ status_code=400,
502
+ detail="Examples must be provided to onboard a ModelSensitiveDataRule",
503
+ )
504
+ return self
@@ -0,0 +1,78 @@
1
+ from typing import Literal, Optional
2
+ from uuid import UUID
3
+
4
+ from arthur_common.models.shield import NewRuleRequest
5
+ from pydantic import BaseModel, Field
6
+
7
+ onboarding_id_desc = "An identifier to assign to the created model to make it easy to retrieve. Used by the UI during the GenAI model creation flow."
8
+
9
+
10
+ class CreateModelTaskJobSpec(BaseModel):
11
+ job_type: Literal["create_model_task"] = "create_model_task"
12
+ connector_id: UUID = Field(
13
+ description="The id of the engine internal connector to use to create the task.",
14
+ )
15
+ task_name: str = Field(description="The name of the task.")
16
+ onboarding_identifier: Optional[str] = Field(
17
+ default=None,
18
+ description=onboarding_id_desc,
19
+ )
20
+ initial_rules: list[NewRuleRequest] = Field(
21
+ description="The initial rules to apply to the created model.",
22
+ )
23
+
24
+
25
+ class CreateModelLinkTaskJobSpec(BaseModel):
26
+ job_type: Literal["link_model_task"] = "link_model_task"
27
+ task_id: UUID = Field(
28
+ description="The id of the Shield task to link when creating the new model.",
29
+ )
30
+ connector_id: UUID = Field(
31
+ description="The id of the engine internal connector to use to link the task.",
32
+ )
33
+ onboarding_identifier: Optional[str] = Field(
34
+ default=None,
35
+ description=onboarding_id_desc,
36
+ )
37
+
38
+
39
+ class UpdateModelTaskRulesJobSpec(BaseModel):
40
+ job_type: Literal["update_model_task_rules"] = "update_model_task_rules"
41
+ scope_model_id: UUID = Field(
42
+ description="The id of the model to update the task rules.",
43
+ )
44
+ rules_to_enable: list[UUID] = Field(
45
+ default_factory=list,
46
+ description="The list of rule IDs to enable on the task.",
47
+ )
48
+ rules_to_disable: list[UUID] = Field(
49
+ default_factory=list,
50
+ description="The list of rule IDs to disable on the task.",
51
+ )
52
+ rules_to_archive: list[UUID] = Field(
53
+ default_factory=list,
54
+ description="The list of rule IDs to archive on the task.",
55
+ )
56
+ rules_to_add: list[NewRuleRequest] = Field(
57
+ default_factory=list,
58
+ description="The new rules to add to the task.",
59
+ )
60
+
61
+
62
+ class DeleteModelTaskJobSpec(BaseModel):
63
+ job_type: Literal["delete_model_task"] = "delete_model_task"
64
+ scope_model_id: UUID = Field(description="The id of the model to delete.")
65
+
66
+
67
+ class FetchModelTaskJobSpec(BaseModel):
68
+ job_type: Literal["fetch_model_task"] = "fetch_model_task"
69
+ scope_model_id: UUID = Field(
70
+ description="The id of the model to fetch its corresponding task.",
71
+ )
72
+
73
+
74
+ class RegenerateTaskValidationKeyJobSpec(BaseModel):
75
+ job_type: Literal["regenerate_validation_key"] = "regenerate_validation_key"
76
+ scope_model_id: UUID = Field(
77
+ description="The ID of the model to regenerate the validation key for.",
78
+ )
arthur_common/py.typed ADDED
File without changes
File without changes