amati 0.1.0__py3-none-any.whl → 0.2__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.
amati/model_validators.py CHANGED
@@ -10,7 +10,7 @@ from pydantic._internal._decorators import (
10
10
  PydanticDescriptorProxy,
11
11
  )
12
12
 
13
- from amati.logging import Log, LogMixin
13
+ from amati.logging import LogMixin
14
14
  from amati.validators.generic import GenericObject
15
15
 
16
16
 
@@ -107,14 +107,13 @@ def at_least_one_of(
107
107
  The validator that ensures at least one public field is non-empty.
108
108
 
109
109
  Example:
110
- >>> from amati import Reference
111
110
  >>> LogMixin.logs = []
112
111
  >>>
113
112
  >>> class User(GenericObject):
114
113
  ... name: str = ""
115
114
  ... email: str = None
116
115
  ... _at_least_one_of = at_least_one_of()
117
- ... _reference: Reference = Reference(title="test")
116
+ ... _reference_uri = "https://example.com"
118
117
  ...
119
118
  >>> user = User()
120
119
  >>> assert len(LogMixin.logs) == 1
@@ -125,7 +124,7 @@ def at_least_one_of(
125
124
  ... email: str = None
126
125
  ... age: int = None
127
126
  ... _at_least_one_of = at_least_one_of(fields=["name", "email"])
128
- ... _reference: Reference = Reference(title="test")
127
+ ... _reference_uri = "https://example.com"
129
128
  ...
130
129
  >>>
131
130
  >>> user = User(name="John") # Works fine
@@ -159,11 +158,13 @@ def at_least_one_of(
159
158
 
160
159
  msg = f"{public_fields} do not have values, expected at least one."
161
160
  LogMixin.log(
162
- Log(
163
- message=msg,
164
- type=ValueError,
165
- reference=self._reference, # pylint: disable=protected-access # type: ignore
166
- )
161
+ {
162
+ "msg": msg,
163
+ "type": "value_error",
164
+ "loc": (self.__class__.__name__,),
165
+ "input": candidates,
166
+ "url": self._reference_uri, # pylint: disable=protected-access # type: ignore
167
+ }
167
168
  )
168
169
 
169
170
  return self
@@ -173,6 +174,7 @@ def at_least_one_of(
173
174
 
174
175
  def only_one_of(
175
176
  fields: Optional[Sequence[str]] = None,
177
+ type_: Optional[str] = "value_error",
176
178
  ) -> PydanticDescriptorProxy[ModelValidatorDecoratorInfo]:
177
179
  """Factory that adds validation to ensure one public field is non-empty.
178
180
 
@@ -189,14 +191,13 @@ def only_one_of(
189
191
  The validator that ensures at one public field is non-empty.
190
192
 
191
193
  Example:
192
- >>> from amati import Reference
193
194
  >>> LogMixin.logs = []
194
195
  >>>
195
196
  >>> class User(GenericObject):
196
197
  ... email: str = ""
197
198
  ... name: str = ""
198
199
  ... _only_one_of = only_one_of()
199
- ... _reference: Reference = Reference(title="test")
200
+ ... _reference_uri = "https://example.com"
200
201
  ...
201
202
  >>> user = User(email="test@example.com") # Works fine
202
203
  >>> user = User(name="123-456-7890") # Works fine
@@ -210,7 +211,7 @@ def only_one_of(
210
211
  ... email: str = ""
211
212
  ... age: int = None
212
213
  ... _only_one_of = only_one_of(["name", "email"])
213
- ... _reference: Reference = Reference(title="test")
214
+ ... _reference_uri = "https://example.com"
214
215
  ...
215
216
  >>> user = User(name="Bob") # Works fine
216
217
  >>> user = User(email="test@example.com") # Works fine
@@ -242,14 +243,20 @@ def only_one_of(
242
243
  truthy.append(name)
243
244
 
244
245
  if len(truthy) != 1:
245
- msg = f"Expected at most one field to have a value, {", ".join(truthy)} did"
246
+ if truthy:
247
+ field_string = ", ".join(truthy)
248
+ else:
249
+ field_string = "none"
250
+ msg = f"Expected at most one field to have a value, {field_string} did"
246
251
 
247
252
  LogMixin.log(
248
- Log(
249
- message=msg,
250
- type=ValueError,
251
- reference=self._reference, # pylint: disable=protected-access # type: ignore
252
- )
253
+ {
254
+ "msg": msg,
255
+ "type": type_ or "value_error",
256
+ "loc": (self.__class__.__name__,),
257
+ "input": candidates,
258
+ "url": self._reference_uri, # pylint: disable=protected-access # type: ignore
259
+ }
253
260
  )
254
261
 
255
262
  return self
@@ -275,14 +282,13 @@ def all_of(
275
282
  The validator that ensures at most one public field is non-empty.
276
283
 
277
284
  Example:
278
- >>> from amati import Reference
279
285
  >>> LogMixin.logs = []
280
286
  >>>
281
287
  >>> class User(GenericObject):
282
288
  ... email: str = ""
283
289
  ... name: str = ""
284
290
  ... _all_of = all_of()
285
- ... _reference: Reference = Reference(title="test")
291
+ ... _reference_uri = "https://example.com"
286
292
  ...
287
293
  >>> user = User(email="a@b.com", name="123") # Works fine
288
294
  >>> assert not LogMixin.logs
@@ -296,7 +302,7 @@ def all_of(
296
302
  ... email: str = ""
297
303
  ... age: int = None
298
304
  ... _all_of = all_of(["name", "email"])
299
- ... _reference: Reference = Reference(title="test")
305
+ ... _reference_uri = "https://example.com"
300
306
  ...
301
307
  >>> LogMixin.logs = []
302
308
  >>> user = User(name="Bob", email="a@b.com") # Works fine
@@ -334,11 +340,13 @@ def all_of(
334
340
  msg = f"Expected at all fields to have a value, {", ".join(falsy)} did not"
335
341
 
336
342
  LogMixin.log(
337
- Log(
338
- message=msg,
339
- type=ValueError,
340
- reference=self._reference, # pylint: disable=protected-access # type: ignore
341
- )
343
+ {
344
+ "msg": msg,
345
+ "type": "value_error",
346
+ "loc": (self.__class__.__name__,),
347
+ "input": candidates,
348
+ "url": self._reference_uri, # pylint: disable=protected-access # type: ignore
349
+ }
342
350
  )
343
351
 
344
352
  return self
@@ -370,7 +378,6 @@ def if_then(
370
378
  ValueError: If a condition and consequence are not present
371
379
 
372
380
  Example:
373
- >>> from amati import Reference
374
381
  >>> LogMixin.logs = []
375
382
  >>>
376
383
  >>> class User(GenericObject):
@@ -380,7 +387,7 @@ def if_then(
380
387
  ... conditions={"role": "admin"},
381
388
  ... consequences={"can_edit": True}
382
389
  ... )
383
- ... _reference: Reference = Reference(title="test")
390
+ ... _reference_uri = "https://example.com"
384
391
  ...
385
392
  >>> user = User(role="admin", can_edit=True) # Works fine
386
393
  >>> assert not LogMixin.logs
@@ -425,12 +432,14 @@ def if_then(
425
432
  continue
426
433
 
427
434
  LogMixin.log(
428
- Log(
429
- message=f"Expected {field} to be {"in " if iterable else ""}"
435
+ {
436
+ "msg": f"Expected {field} to be {"in " if iterable else ""}"
430
437
  f"{value} found {actual}",
431
- type=ValueError,
432
- reference=self._reference, # pylint: disable=protected-access # type: ignore
433
- )
438
+ "type": "value_error",
439
+ "loc": (self.__class__.__name__,),
440
+ "input": candidates,
441
+ "url": self._reference_uri, # pylint: disable=protected-access # type: ignore
442
+ }
434
443
  )
435
444
 
436
445
  return self
@@ -20,17 +20,16 @@ from typing import (
20
20
  from pydantic import BaseModel, ConfigDict, PrivateAttr
21
21
  from pydantic_core._pydantic_core import PydanticUndefined
22
22
 
23
- from amati import Reference
24
- from amati.logging import Log, LogMixin
23
+ from amati.logging import LogMixin
25
24
 
26
25
 
27
- class GenericObject(LogMixin, BaseModel):
26
+ class GenericObject(BaseModel):
28
27
  """
29
28
  A generic model to overwrite provide extra functionality
30
29
  to pydantic.BaseModel.
31
30
  """
32
31
 
33
- _reference: ClassVar[Reference] = PrivateAttr()
32
+ _reference_uri: ClassVar[str] = PrivateAttr()
34
33
  _extra_field_pattern: Optional[Pattern[str]] = PrivateAttr()
35
34
 
36
35
  def __init__(self, **data: Any) -> None:
@@ -48,11 +47,14 @@ class GenericObject(LogMixin, BaseModel):
48
47
  and field not in self.get_field_aliases()
49
48
  ):
50
49
  message = f"{field} is not a valid field for {self.__repr_name__()}."
51
- self.log(
52
- Log(
53
- message=message,
54
- type=ValueError,
55
- )
50
+ LogMixin.log(
51
+ {
52
+ "msg": message,
53
+ "type": "value_error",
54
+ "loc": (self.__repr_name__(),),
55
+ "input": field,
56
+ "url": self._reference_uri,
57
+ }
56
58
  )
57
59
 
58
60
  def model_post_init(self, __context: Any) -> None:
@@ -78,10 +80,13 @@ class GenericObject(LogMixin, BaseModel):
78
80
  for field in excess_fields:
79
81
  message = f"{field} is not a valid field for {self.__repr_name__()}."
80
82
  LogMixin.log(
81
- Log(
82
- message=message,
83
- type=ValueError,
84
- )
83
+ {
84
+ "msg": message,
85
+ "type": "value_error",
86
+ "loc": (self.__repr_name__(),),
87
+ "input": field,
88
+ "url": self._reference_uri,
89
+ }
85
90
  )
86
91
 
87
92
  def get_field_aliases(self) -> list[str]: