fmtr.tools 1.3.66__py3-none-any.whl → 1.3.68__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 fmtr.tools might be problematic. Click here for more details.

@@ -1,3 +1,4 @@
1
+ import inspect
1
2
  from functools import cached_property
2
3
  from typing import ClassVar, List, Any, Dict
3
4
 
@@ -9,7 +10,7 @@ from pydantic_core import PydanticUndefined, PydanticUndefinedType
9
10
  from fmtr.tools.datatype_tools import is_optional
10
11
  from fmtr.tools.iterator_tools import get_class_lookup
11
12
  from fmtr.tools.string_tools import camel_to_snake
12
- from fmtr.tools.tools import Auto, Required
13
+ from fmtr.tools.tools import Auto, Required, Empty
13
14
 
14
15
 
15
16
  class Field(FieldInfo):
@@ -19,28 +20,41 @@ class Field(FieldInfo):
19
20
 
20
21
  """
21
22
  NAME = Auto
22
- ANNOTATION = None
23
+ ANNOTATION = Empty
24
+ EXCLUDE = False
23
25
  DEFAULT = Auto
24
26
  FILLS = None
25
27
  DESCRIPTION = None
26
28
  TITLE = Auto
27
29
  CONFIG = None
28
30
 
29
- def __init__(self):
31
+ def __init__(self, annotation=Empty, default=Empty, description=None, title=None, fills=None, exclude=None, **kwargs):
30
32
  """
31
33
 
32
34
  Infer default from type annotation, if enabled, use class/argument fills to create titles/descriptions, etc.
33
35
 
34
36
  """
35
- title = self.get_title_auto()
36
- description = self.get_desc()
37
- default = self.get_default_auto()
38
- kwargs = self.CONFIG or {}
39
37
 
38
+ fills_super = getattr(super(), 'FILLS', None)
39
+ self.fills = (fills_super or {}) | (self.FILLS or {}) | (fills or {})
40
+
41
+ exclude = exclude if exclude is not None else self.EXCLUDE
42
+
43
+ self.annotation = self.ANNOTATION if annotation is Empty else annotation
44
+ if self.annotation is Empty:
45
+ raise ValueError("Annotation must be specified.")
46
+ annotation = self.annotation
47
+
48
+ default = self.get_default_auto(default)
40
49
  if default is Required:
41
50
  default = PydanticUndefined
42
51
 
43
- super().__init__(default=default, title=title, description=description, **kwargs)
52
+ description = self.get_desc(description)
53
+ title = self.get_title_auto(title)
54
+ kwargs |= (self.CONFIG or {})
55
+
56
+ super().__init__(default=default, title=title, description=description, exclude=exclude, **kwargs)
57
+ self.annotation = annotation
44
58
 
45
59
  @classmethod
46
60
  def get_name_auto(cls) -> str:
@@ -63,46 +77,55 @@ class Field(FieldInfo):
63
77
  Get fills with filled title merged in
64
78
 
65
79
  """
66
- return (self.FILLS or {}) | dict(title=self.get_title_auto())
67
80
 
68
- def get_default_auto(self) -> type[Any] | None | PydanticUndefinedType:
81
+ fills_super = getattr(super(), 'FILLS', None)
82
+
83
+ return (fills_super or {}) | (self.FILLS or {}) | dict(title=self.get_title_auto())
84
+
85
+ def get_default_auto(self, default) -> type[Any] | None | PydanticUndefinedType:
69
86
  """
70
87
 
71
88
  Infer default, if not specified.
72
89
 
73
90
  """
91
+
92
+ if default is not Empty:
93
+ return default
94
+
74
95
  if self.DEFAULT is not Auto:
75
96
  return self.DEFAULT
76
97
 
77
- if is_optional(self.ANNOTATION):
98
+ if is_optional(self.annotation):
78
99
  return None
79
100
  else:
80
101
  return Required
81
102
 
82
- def get_title_auto(self) -> str | None:
103
+ def get_title_auto(self, mask) -> str | None:
83
104
  """
84
105
 
85
106
  Get title from classname/mask
86
107
 
87
108
  """
88
109
 
89
- mask = self.__class__.__name__ if self.TITLE is Auto else self.TITLE
90
- fills = (self.FILLS or {})
110
+ if not mask:
111
+ mask = self.__class__.__name__ if self.TITLE is Auto else self.TITLE
91
112
 
92
113
  if mask:
93
- return mask.format(**fills)
114
+ return mask.format(**self.fills)
94
115
 
95
116
  return None
96
117
 
97
- def get_desc(self) -> str | None:
118
+ def get_desc(self, mask) -> str | None:
98
119
  """
99
120
 
100
- Get description from classname/mask
121
+ Fill description mask, if specified
101
122
 
102
123
  """
103
124
 
104
- if self.DESCRIPTION:
105
- return self.DESCRIPTION.format(**self.fills)
125
+ mask = mask or self.DESCRIPTION
126
+
127
+ if mask:
128
+ return mask.format(**self.fills)
106
129
 
107
130
  return None
108
131
 
@@ -189,15 +212,15 @@ class Base(BaseModel, MixinFromJson):
189
212
 
190
213
  cls.FIELDS = fields
191
214
 
192
- for name, FieldInfoType in fields.items():
215
+ for name, field in fields.items():
193
216
  if name in cls.__annotations__:
194
217
  continue
195
218
 
196
- field = FieldInfoType()
197
- setattr(cls, name, field)
219
+ if inspect.isclass(field):
220
+ field = field()
198
221
 
199
- annotation = FieldInfoType.ANNOTATION
200
- cls.__annotations__[name] = annotation
222
+ setattr(cls, name, field)
223
+ cls.__annotations__[name] = field.annotation
201
224
 
202
225
  def to_df(self, name_value='value'):
203
226
  """
@@ -93,6 +93,9 @@ def is_optional(annotation) -> bool:
93
93
  Is type/annotation optional? todo should be in typing_tools?
94
94
 
95
95
  """
96
+ if annotation is None:
97
+ return True
98
+
96
99
  origin = get_origin(annotation)
97
100
  args = get_args(annotation)
98
101
  is_opt = origin is UnionType and NoneType in args
fmtr/tools/version CHANGED
@@ -1 +1 @@
1
- 1.3.66
1
+ 1.3.68
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fmtr.tools
3
- Version: 1.3.66
3
+ Version: 1.3.68
4
4
  Summary: Collection of high-level tools to simplify everyday development tasks, with a focus on AI/ML
5
5
  Home-page: https://github.com/fmtr/fmtr.tools
6
6
  Author: Frontmatter
@@ -168,68 +168,68 @@ Provides-Extra: db-document
168
168
  Requires-Dist: beanie[odm]; extra == "db-document"
169
169
  Requires-Dist: motor; extra == "db-document"
170
170
  Provides-Extra: all
171
- Requires-Dist: python-on-whales; extra == "all"
172
- Requires-Dist: pydantic-settings; extra == "all"
173
- Requires-Dist: logfire; extra == "all"
174
- Requires-Dist: pydantic; extra == "all"
175
- Requires-Dist: pycountry; extra == "all"
176
- Requires-Dist: logfire[fastapi]; extra == "all"
177
- Requires-Dist: contexttimer; extra == "all"
178
- Requires-Dist: json_repair; extra == "all"
179
- Requires-Dist: diskcache; extra == "all"
171
+ Requires-Dist: tinynetrc; extra == "all"
172
+ Requires-Dist: flet-video; extra == "all"
173
+ Requires-Dist: google-auth-httplib2; extra == "all"
180
174
  Requires-Dist: pymupdf4llm; extra == "all"
181
- Requires-Dist: dnspython[doh]; extra == "all"
175
+ Requires-Dist: tabulate; extra == "all"
176
+ Requires-Dist: huggingface_hub; extra == "all"
177
+ Requires-Dist: cachetools; extra == "all"
182
178
  Requires-Dist: beanie[odm]; extra == "all"
179
+ Requires-Dist: pytest-cov; extra == "all"
183
180
  Requires-Dist: html2text; extra == "all"
184
- Requires-Dist: faker; extra == "all"
185
- Requires-Dist: semver; extra == "all"
186
- Requires-Dist: ollama; extra == "all"
187
- Requires-Dist: torchvision; extra == "all"
188
- Requires-Dist: regex; extra == "all"
181
+ Requires-Dist: appdirs; extra == "all"
189
182
  Requires-Dist: filetype; extra == "all"
190
- Requires-Dist: pydantic-extra-types; extra == "all"
191
- Requires-Dist: tinynetrc; extra == "all"
183
+ Requires-Dist: motor; extra == "all"
184
+ Requires-Dist: dask[bag]; extra == "all"
185
+ Requires-Dist: pyyaml; extra == "all"
186
+ Requires-Dist: json_repair; extra == "all"
187
+ Requires-Dist: pymupdf; extra == "all"
188
+ Requires-Dist: httpx_retries; extra == "all"
189
+ Requires-Dist: transformers[sentencepiece]; extra == "all"
190
+ Requires-Dist: dnspython[doh]; extra == "all"
191
+ Requires-Dist: playwright; extra == "all"
192
+ Requires-Dist: fastapi; extra == "all"
192
193
  Requires-Dist: pydantic-ai[logfire,openai]; extra == "all"
193
- Requires-Dist: google-auth-oauthlib; extra == "all"
194
+ Requires-Dist: flet-webview; extra == "all"
195
+ Requires-Dist: pydevd-pycharm~=251.25410.159; extra == "all"
196
+ Requires-Dist: openai; extra == "all"
197
+ Requires-Dist: pycountry; extra == "all"
194
198
  Requires-Dist: httpx; extra == "all"
195
- Requires-Dist: uvicorn[standard]; extra == "all"
199
+ Requires-Dist: semver; extra == "all"
200
+ Requires-Dist: pydantic; extra == "all"
201
+ Requires-Dist: diskcache; extra == "all"
202
+ Requires-Dist: pandas; extra == "all"
203
+ Requires-Dist: bokeh; extra == "all"
204
+ Requires-Dist: sre_yield; extra == "all"
205
+ Requires-Dist: faker; extra == "all"
206
+ Requires-Dist: tokenizers; extra == "all"
196
207
  Requires-Dist: peft; extra == "all"
197
- Requires-Dist: flet[all]; extra == "all"
198
- Requires-Dist: fastapi; extra == "all"
199
- Requires-Dist: Unidecode; extra == "all"
200
- Requires-Dist: httpx_retries; extra == "all"
201
- Requires-Dist: deepmerge; extra == "all"
202
- Requires-Dist: pydevd-pycharm~=251.25410.159; extra == "all"
203
- Requires-Dist: motor; extra == "all"
204
- Requires-Dist: sentence_transformers; extra == "all"
205
208
  Requires-Dist: distributed; extra == "all"
209
+ Requires-Dist: openpyxl; extra == "all"
210
+ Requires-Dist: python-on-whales; extra == "all"
206
211
  Requires-Dist: google-auth; extra == "all"
207
- Requires-Dist: openai; extra == "all"
208
- Requires-Dist: pytest-cov; extra == "all"
209
- Requires-Dist: logfire[httpx]; extra == "all"
212
+ Requires-Dist: uvicorn[standard]; extra == "all"
213
+ Requires-Dist: regex; extra == "all"
214
+ Requires-Dist: torchvision; extra == "all"
215
+ Requires-Dist: yamlscript; extra == "all"
216
+ Requires-Dist: Unidecode; extra == "all"
217
+ Requires-Dist: google-api-python-client; extra == "all"
210
218
  Requires-Dist: deepdiff; extra == "all"
219
+ Requires-Dist: sentence_transformers; extra == "all"
211
220
  Requires-Dist: setuptools; extra == "all"
212
- Requires-Dist: google-auth-httplib2; extra == "all"
213
- Requires-Dist: playwright; extra == "all"
214
- Requires-Dist: bokeh; extra == "all"
215
- Requires-Dist: tokenizers; extra == "all"
216
- Requires-Dist: tabulate; extra == "all"
217
- Requires-Dist: huggingface_hub; extra == "all"
221
+ Requires-Dist: pydantic-extra-types; extra == "all"
222
+ Requires-Dist: ollama; extra == "all"
223
+ Requires-Dist: flet[all]; extra == "all"
224
+ Requires-Dist: deepmerge; extra == "all"
218
225
  Requires-Dist: odfpy; extra == "all"
219
- Requires-Dist: flet-webview; extra == "all"
220
- Requires-Dist: sre_yield; extra == "all"
221
- Requires-Dist: cachetools; extra == "all"
222
- Requires-Dist: pyyaml; extra == "all"
223
- Requires-Dist: transformers[sentencepiece]; extra == "all"
224
- Requires-Dist: pymupdf; extra == "all"
225
- Requires-Dist: yamlscript; extra == "all"
226
- Requires-Dist: openpyxl; extra == "all"
226
+ Requires-Dist: google-auth-oauthlib; extra == "all"
227
+ Requires-Dist: logfire[httpx]; extra == "all"
228
+ Requires-Dist: logfire[fastapi]; extra == "all"
229
+ Requires-Dist: contexttimer; extra == "all"
227
230
  Requires-Dist: torchaudio; extra == "all"
228
- Requires-Dist: google-api-python-client; extra == "all"
229
- Requires-Dist: flet-video; extra == "all"
230
- Requires-Dist: dask[bag]; extra == "all"
231
- Requires-Dist: pandas; extra == "all"
232
- Requires-Dist: appdirs; extra == "all"
231
+ Requires-Dist: pydantic-settings; extra == "all"
232
+ Requires-Dist: logfire; extra == "all"
233
233
  Dynamic: author
234
234
  Dynamic: author-email
235
235
  Dynamic: description
@@ -5,9 +5,9 @@ fmtr/tools/augmentation_tools.py,sha256=-6ESbO4CDlKqVOV1J1V6qBeoBMzbFIinkDHRHnCB
5
5
  fmtr/tools/caching_tools.py,sha256=74p7m2GLFfeP41LX69wxgfkilxEAoWkMIfFMjKsYpyg,4976
6
6
  fmtr/tools/constants.py,sha256=90wCirUpw4bWMAbjhip0LL6k57eS5VmxRUP9pLCChBg,1812
7
7
  fmtr/tools/context_tools.py,sha256=4UvIHYgLqAh7dXMX9EBrLEpYp81qfzhSVrkffOSAoGA,350
8
- fmtr/tools/data_modelling_tools.py,sha256=vD7nbqeQh_azoNZUiVWvK8GuyNE-Qagcqg_RE7wYNBk,5303
8
+ fmtr/tools/data_modelling_tools.py,sha256=iu_TQ44Ild9nYWqdzAutFKn4Gjj0kWabHNsuw_CmcbI,6101
9
9
  fmtr/tools/dataclass_tools.py,sha256=0Gt6KeLhtPgubo_2tYkIVqB8oQ91Qzag8OAGZDdjvMU,1209
10
- fmtr/tools/datatype_tools.py,sha256=1XznVwlY4-DkYa6FwhHMstD8qz27vCcV64IvCrcJgMA,1830
10
+ fmtr/tools/datatype_tools.py,sha256=89QmlQ_fANqFQKsEMzhhRftfby-1PcrR3cylfbQNt9U,1878
11
11
  fmtr/tools/datetime_tools.py,sha256=L7wmBoQbD9h_pJIL92WQOX32r_vrXgRvE-_0PVPRAGY,232
12
12
  fmtr/tools/debugging_tools.py,sha256=_xzqS0V5BpL8d06j-jVQjGgI7T020QsqVXKAKMz7Du8,2082
13
13
  fmtr/tools/environment_tools.py,sha256=43uqfj1G1bNX0IwKz-NKbu3AbFYSdbBuGN9rlThe030,1845
@@ -45,7 +45,7 @@ fmtr/tools/tabular_tools.py,sha256=mw6vOij1Ch-pVAyHMPtm5zj__ULZN_TKeBYOfj33wFM,1
45
45
  fmtr/tools/tokenization_tools.py,sha256=me-IBzSLyNYejLybwjO9CNB6Mj2NYfKPaOVThXyaGNg,4268
46
46
  fmtr/tools/tools.py,sha256=sLMXk8juOL8_n_D776cJ-kzjyMHqFI_fctDEjy6PIKs,1115
47
47
  fmtr/tools/unicode_tools.py,sha256=yS_9wpu8ogNoiIL7s1G_8bETFFO_YQlo4LNPv1NLDeY,52
48
- fmtr/tools/version,sha256=n4zX1YVX0dMhq7mFDh_xh19zo5isz-FQXXDc31JZieI,6
48
+ fmtr/tools/version,sha256=xSnaCIMu8ziy2CYAjf46a3tfho_wAnH5SGYlFyByUzU,6
49
49
  fmtr/tools/webhook_tools.py,sha256=q3pVJ1NCem2SrMuFcLxiWd7DibFs7Q-uGtojfXd3Qcg,380
50
50
  fmtr/tools/yaml_tools.py,sha256=Bhhyd6GQVKO72Lp8ky7bAUjIB_65Hdh0Q45SKIEe6S8,1901
51
51
  fmtr/tools/ai_tools/__init__.py,sha256=O8VRlPnnQCncg2ZZ2l_VdWLJf4jkKH6dkZFVbv6o7IM,388
@@ -85,9 +85,9 @@ fmtr/tools/tests/test_path.py,sha256=AkZQa6_8BQ-VaCyL_J-iKmdf2ZaM-xFYR37Kun3k4_g
85
85
  fmtr/tools/tests/test_yaml.py,sha256=jc0TwwKu9eC0LvFGNMERdgBue591xwLxYXFbtsRwXVM,287
86
86
  fmtr/tools/version_tools/__init__.py,sha256=cjE6nO6AoVOUp3RwgTbqL9wiw8J1l2pHJOz6Gn6bxjA,326
87
87
  fmtr/tools/version_tools/version_tools.py,sha256=Hcc6yferZS1hHbugRTdiHhSNmXEEG0hjCiTTXKna-YY,1127
88
- fmtr_tools-1.3.66.dist-info/licenses/LICENSE,sha256=FW9aa6vVN5IjRQWLT43hs4_koYSmpcbIovlKeAJ0_cI,10757
89
- fmtr_tools-1.3.66.dist-info/METADATA,sha256=FDYRqOEAr_MdQkPYIjC9UYvo2_XIUvpAWDsXPj3Jmc8,18035
90
- fmtr_tools-1.3.66.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
91
- fmtr_tools-1.3.66.dist-info/entry_points.txt,sha256=h-r__Xh5njtFqreMLg6cGuTFS4Qh-QqJPU1HB-_BS-Q,357
92
- fmtr_tools-1.3.66.dist-info/top_level.txt,sha256=LXem9xCgNOD72tE2gRKESdiQTL902mfFkwWb6-dlwEE,5
93
- fmtr_tools-1.3.66.dist-info/RECORD,,
88
+ fmtr_tools-1.3.68.dist-info/licenses/LICENSE,sha256=FW9aa6vVN5IjRQWLT43hs4_koYSmpcbIovlKeAJ0_cI,10757
89
+ fmtr_tools-1.3.68.dist-info/METADATA,sha256=_kxvibJHT2KtDhSgtrOhyOdNkV4SPU_ctDtX1pfsb7Y,18035
90
+ fmtr_tools-1.3.68.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
91
+ fmtr_tools-1.3.68.dist-info/entry_points.txt,sha256=h-r__Xh5njtFqreMLg6cGuTFS4Qh-QqJPU1HB-_BS-Q,357
92
+ fmtr_tools-1.3.68.dist-info/top_level.txt,sha256=LXem9xCgNOD72tE2gRKESdiQTL902mfFkwWb6-dlwEE,5
93
+ fmtr_tools-1.3.68.dist-info/RECORD,,