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.
- fmtr/tools/data_modelling_tools.py +47 -24
- fmtr/tools/datatype_tools.py +3 -0
- fmtr/tools/version +1 -1
- {fmtr_tools-1.3.66.dist-info → fmtr_tools-1.3.68.dist-info}/METADATA +50 -50
- {fmtr_tools-1.3.66.dist-info → fmtr_tools-1.3.68.dist-info}/RECORD +9 -9
- {fmtr_tools-1.3.66.dist-info → fmtr_tools-1.3.68.dist-info}/WHEEL +0 -0
- {fmtr_tools-1.3.66.dist-info → fmtr_tools-1.3.68.dist-info}/entry_points.txt +0 -0
- {fmtr_tools-1.3.66.dist-info → fmtr_tools-1.3.68.dist-info}/licenses/LICENSE +0 -0
- {fmtr_tools-1.3.66.dist-info → fmtr_tools-1.3.68.dist-info}/top_level.txt +0 -0
|
@@ -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 =
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
90
|
-
|
|
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
|
-
|
|
121
|
+
Fill description mask, if specified
|
|
101
122
|
|
|
102
123
|
"""
|
|
103
124
|
|
|
104
|
-
|
|
105
|
-
|
|
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,
|
|
215
|
+
for name, field in fields.items():
|
|
193
216
|
if name in cls.__annotations__:
|
|
194
217
|
continue
|
|
195
218
|
|
|
196
|
-
|
|
197
|
-
|
|
219
|
+
if inspect.isclass(field):
|
|
220
|
+
field = field()
|
|
198
221
|
|
|
199
|
-
|
|
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
|
"""
|
fmtr/tools/datatype_tools.py
CHANGED
|
@@ -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.
|
|
1
|
+
1.3.68
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fmtr.tools
|
|
3
|
-
Version: 1.3.
|
|
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:
|
|
172
|
-
Requires-Dist:
|
|
173
|
-
Requires-Dist:
|
|
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:
|
|
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:
|
|
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:
|
|
191
|
-
Requires-Dist:
|
|
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:
|
|
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:
|
|
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:
|
|
208
|
-
Requires-Dist:
|
|
209
|
-
Requires-Dist:
|
|
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:
|
|
213
|
-
Requires-Dist:
|
|
214
|
-
Requires-Dist:
|
|
215
|
-
Requires-Dist:
|
|
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:
|
|
220
|
-
Requires-Dist:
|
|
221
|
-
Requires-Dist:
|
|
222
|
-
Requires-Dist:
|
|
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:
|
|
229
|
-
Requires-Dist:
|
|
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=
|
|
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=
|
|
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=
|
|
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.
|
|
89
|
-
fmtr_tools-1.3.
|
|
90
|
-
fmtr_tools-1.3.
|
|
91
|
-
fmtr_tools-1.3.
|
|
92
|
-
fmtr_tools-1.3.
|
|
93
|
-
fmtr_tools-1.3.
|
|
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,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|