fmtr.tools 1.3.64__py3-none-any.whl → 1.3.66__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.

@@ -8,6 +8,7 @@ from pydantic_core import PydanticUndefined, PydanticUndefinedType
8
8
 
9
9
  from fmtr.tools.datatype_tools import is_optional
10
10
  from fmtr.tools.iterator_tools import get_class_lookup
11
+ from fmtr.tools.string_tools import camel_to_snake
11
12
  from fmtr.tools.tools import Auto, Required
12
13
 
13
14
 
@@ -17,12 +18,13 @@ class Field(FieldInfo):
17
18
  Allow DRYer field definitions, set annotation and defaults at the same time, easier field inheritance, etc.
18
19
 
19
20
  """
21
+ NAME = Auto
20
22
  ANNOTATION = None
21
23
  DEFAULT = Auto
22
24
  FILLS = None
23
25
  DESCRIPTION = None
24
26
  TITLE = Auto
25
- KWARGS = None
27
+ CONFIG = None
26
28
 
27
29
  def __init__(self):
28
30
  """
@@ -33,13 +35,27 @@ class Field(FieldInfo):
33
35
  title = self.get_title_auto()
34
36
  description = self.get_desc()
35
37
  default = self.get_default_auto()
36
- kwargs = self.KWARGS or {}
38
+ kwargs = self.CONFIG or {}
37
39
 
38
40
  if default is Required:
39
41
  default = PydanticUndefined
40
42
 
41
43
  super().__init__(default=default, title=title, description=description, **kwargs)
42
44
 
45
+ @classmethod
46
+ def get_name_auto(cls) -> str:
47
+ """
48
+
49
+ Infer field name, if set to auto.
50
+
51
+ """
52
+ if cls.NAME is Auto:
53
+ return camel_to_snake(cls.__name__)
54
+ elif cls.NAME is None:
55
+ return cls.__name__
56
+
57
+ return cls.NAME
58
+
43
59
  @cached_property
44
60
  def fills(self) -> Dict[str, str]:
45
61
  """
@@ -169,7 +185,7 @@ class Base(BaseModel, MixinFromJson):
169
185
  if isinstance(raw, dict):
170
186
  fields |= raw
171
187
  else:
172
- fields |= get_class_lookup(*raw, name_function=str.lower)
188
+ fields |= get_class_lookup(*raw, name_function=lambda cls_field: cls_field.get_name_auto())
173
189
 
174
190
  cls.FIELDS = fields
175
191
 
@@ -2,13 +2,23 @@ from functools import cached_property
2
2
  from typing import List
3
3
 
4
4
  import beanie
5
+ from beanie.odm import actions
5
6
  from motor.motor_asyncio import AsyncIOMotorClient
6
7
 
8
+ from fmtr.tools import data_modelling_tools
7
9
  from fmtr.tools.constants import Constants
8
10
  from fmtr.tools.logging_tools import logger
9
11
 
12
+ ModifyEvents = [
13
+ actions.Insert,
14
+ actions.Replace,
15
+ actions.Save,
16
+ actions.SaveChanges,
17
+ actions.Update
18
+ ]
10
19
 
11
- class Document(beanie.Document):
20
+
21
+ class Document(beanie.Document, data_modelling_tools.Base):
12
22
  """
13
23
 
14
24
  Document stub.
@@ -2,7 +2,6 @@ from itertools import chain, batched
2
2
  from typing import List, Dict, Any
3
3
 
4
4
  from fmtr.tools.datatype_tools import is_none
5
- from fmtr.tools.tools import identity
6
5
 
7
6
 
8
7
  def enlist(value) -> List[Any]:
@@ -75,10 +74,10 @@ def dedupe(items):
75
74
  return list(dict.fromkeys(items))
76
75
 
77
76
 
78
- def get_class_lookup(*classes, name_function=identity):
77
+ def get_class_lookup(*classes, name_function=lambda cls: cls.__name__):
79
78
  """
80
79
 
81
80
  Dictionary of class names to classes
82
81
 
83
82
  """
84
- return {name_function(cls.__name__): cls for cls in classes}
83
+ return {name_function(cls): cls for cls in classes}
@@ -241,3 +241,18 @@ def trim(text: str) -> str:
241
241
 
242
242
  """
243
243
  return dedent(text).strip()
244
+
245
+
246
+ ACRONYM_BOUNDARY = re.compile(r'([A-Z]+)([A-Z][a-z])')
247
+ CAMEL_BOUNDARY = re.compile(r'([a-z0-9])([A-Z])')
248
+
249
+
250
+ def camel_to_snake(name: str) -> str:
251
+ """
252
+
253
+ Camel case to snake case
254
+
255
+ """
256
+ name = ACRONYM_BOUNDARY.sub(r'\1_\2', name)
257
+ name = CAMEL_BOUNDARY.sub(r'\1_\2', name)
258
+ return name.lower()
fmtr/tools/version CHANGED
@@ -1 +1 @@
1
- 1.3.64
1
+ 1.3.66
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fmtr.tools
3
- Version: 1.3.64
3
+ Version: 1.3.66
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"
171
179
  Requires-Dist: diskcache; extra == "all"
172
- Requires-Dist: sre_yield; extra == "all"
173
- Requires-Dist: setuptools; extra == "all"
174
- Requires-Dist: tabulate; extra == "all"
175
- Requires-Dist: httpx; extra == "all"
176
- Requires-Dist: pymupdf; extra == "all"
177
- Requires-Dist: flet-video; extra == "all"
178
- Requires-Dist: cachetools; extra == "all"
180
+ Requires-Dist: pymupdf4llm; extra == "all"
181
+ Requires-Dist: dnspython[doh]; extra == "all"
182
+ Requires-Dist: beanie[odm]; extra == "all"
183
+ Requires-Dist: html2text; extra == "all"
184
+ Requires-Dist: faker; extra == "all"
179
185
  Requires-Dist: semver; extra == "all"
186
+ Requires-Dist: ollama; extra == "all"
187
+ Requires-Dist: torchvision; extra == "all"
188
+ Requires-Dist: regex; extra == "all"
189
+ Requires-Dist: filetype; extra == "all"
180
190
  Requires-Dist: pydantic-extra-types; extra == "all"
181
- Requires-Dist: beanie[odm]; extra == "all"
182
- Requires-Dist: google-auth; extra == "all"
191
+ Requires-Dist: tinynetrc; extra == "all"
192
+ Requires-Dist: pydantic-ai[logfire,openai]; extra == "all"
183
193
  Requires-Dist: google-auth-oauthlib; extra == "all"
194
+ Requires-Dist: httpx; extra == "all"
184
195
  Requires-Dist: uvicorn[standard]; extra == "all"
185
- Requires-Dist: yamlscript; extra == "all"
186
- Requires-Dist: dask[bag]; extra == "all"
187
- Requires-Dist: json_repair; extra == "all"
188
196
  Requires-Dist: peft; extra == "all"
189
- Requires-Dist: distributed; extra == "all"
190
- Requires-Dist: tokenizers; extra == "all"
191
- Requires-Dist: motor; extra == "all"
192
- Requires-Dist: odfpy; extra == "all"
193
- Requires-Dist: pycountry; extra == "all"
194
- Requires-Dist: fastapi; extra == "all"
195
- Requires-Dist: google-api-python-client; extra == "all"
196
- Requires-Dist: html2text; extra == "all"
197
- Requires-Dist: transformers[sentencepiece]; extra == "all"
198
- Requires-Dist: pydantic-settings; extra == "all"
199
- Requires-Dist: deepdiff; extra == "all"
200
- Requires-Dist: logfire; extra == "all"
201
- Requires-Dist: sentence_transformers; extra == "all"
202
- Requires-Dist: pymupdf4llm; extra == "all"
203
- Requires-Dist: logfire[httpx]; extra == "all"
204
197
  Requires-Dist: flet[all]; extra == "all"
198
+ Requires-Dist: fastapi; extra == "all"
199
+ Requires-Dist: Unidecode; extra == "all"
205
200
  Requires-Dist: httpx_retries; extra == "all"
206
- Requires-Dist: tinynetrc; 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
+ Requires-Dist: distributed; extra == "all"
206
+ Requires-Dist: google-auth; extra == "all"
207
+ Requires-Dist: openai; extra == "all"
207
208
  Requires-Dist: pytest-cov; extra == "all"
208
- Requires-Dist: torchvision; extra == "all"
209
- Requires-Dist: dnspython[doh]; extra == "all"
210
- Requires-Dist: pydantic-ai[logfire,openai]; extra == "all"
209
+ Requires-Dist: logfire[httpx]; extra == "all"
210
+ Requires-Dist: deepdiff; extra == "all"
211
+ Requires-Dist: setuptools; extra == "all"
211
212
  Requires-Dist: google-auth-httplib2; extra == "all"
212
- Requires-Dist: regex; extra == "all"
213
- Requires-Dist: huggingface_hub; extra == "all"
214
- Requires-Dist: logfire[fastapi]; extra == "all"
215
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"
218
+ 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"
216
222
  Requires-Dist: pyyaml; extra == "all"
217
- Requires-Dist: pandas; 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"
218
227
  Requires-Dist: torchaudio; extra == "all"
219
- Requires-Dist: python-on-whales; extra == "all"
220
- Requires-Dist: flet-webview; extra == "all"
221
- Requires-Dist: deepmerge; extra == "all"
222
- Requires-Dist: openai; 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"
223
232
  Requires-Dist: appdirs; extra == "all"
224
- Requires-Dist: pydevd-pycharm~=251.25410.159; extra == "all"
225
- Requires-Dist: ollama; extra == "all"
226
- Requires-Dist: faker; extra == "all"
227
- Requires-Dist: openpyxl; extra == "all"
228
- Requires-Dist: pydantic; extra == "all"
229
- Requires-Dist: bokeh; extra == "all"
230
- Requires-Dist: filetype; extra == "all"
231
- Requires-Dist: Unidecode; extra == "all"
232
- Requires-Dist: contexttimer; extra == "all"
233
233
  Dynamic: author
234
234
  Dynamic: author-email
235
235
  Dynamic: description
@@ -5,7 +5,7 @@ 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=pSAnf-pt-c4RGqDMCkDb_XGxsmEEQqLmBMlMTVU76yg,4916
8
+ fmtr/tools/data_modelling_tools.py,sha256=vD7nbqeQh_azoNZUiVWvK8GuyNE-Qagcqg_RE7wYNBk,5303
9
9
  fmtr/tools/dataclass_tools.py,sha256=0Gt6KeLhtPgubo_2tYkIVqB8oQ91Qzag8OAGZDdjvMU,1209
10
10
  fmtr/tools/datatype_tools.py,sha256=1XznVwlY4-DkYa6FwhHMstD8qz27vCcV64IvCrcJgMA,1830
11
11
  fmtr/tools/datetime_tools.py,sha256=L7wmBoQbD9h_pJIL92WQOX32r_vrXgRvE-_0PVPRAGY,232
@@ -20,7 +20,7 @@ fmtr/tools/http_tools.py,sha256=RVwGrBNMyjfbpgAPCSnxEkXfSzXXWARb3ayq981ONQE,464
20
20
  fmtr/tools/import_tools.py,sha256=XJmiWLukRncJAcaGReDn4jIz1_IpVBjfYCQHH1hIg7c,588
21
21
  fmtr/tools/inherit_tools.py,sha256=gTGL4mRm5RsbFW76s25AbuAJ2vlymbh1c8Q4Hl2uJGU,646
22
22
  fmtr/tools/inspection_tools.py,sha256=tLTRvzy9XVomQPi0dfnF_cgwc7KiDVZAr7gPTk4S_bQ,278
23
- fmtr/tools/iterator_tools.py,sha256=IwHdRj72oP3e191h7gs15g0HEW6haP28t8CmB0R8qbo,1847
23
+ fmtr/tools/iterator_tools.py,sha256=ucsDj-T4YgwRCieFvjBXLfTe4RipL1CJ1_1GOxvEIW8,1816
24
24
  fmtr/tools/json_fix_tools.py,sha256=vNSlswVQnujPmKEqDjFJcO901mjMyv59q3awsT7mlhs,477
25
25
  fmtr/tools/json_tools.py,sha256=WkFc5q7oqMtcFejhN1K5zQFULa9TdLOup83Fr0saDRY,348
26
26
  fmtr/tools/logging_tools.py,sha256=jZFKnL-7HHOaPkn7F3fT9DyffIgwY-g7SEQ0p1RhzBo,2673
@@ -40,19 +40,19 @@ fmtr/tools/random_tools.py,sha256=4VlQdk5THbR8ka4pZaLbk_ZO_4yy6PF_lHZes_rgenY,22
40
40
  fmtr/tools/semantic_tools.py,sha256=cxY9NSAHWj4nEc6Oj4qA1omR3dWbl2OuH7_PkINc6_E,1386
41
41
  fmtr/tools/settings_tools.py,sha256=o11W3T60UZSvCTkh_eEQq1Mx74GycQ6JxUr0plBDbsk,2356
42
42
  fmtr/tools/spaces_tools.py,sha256=D_he3mve6DruB3OPS6QyzqD05ChHnRTb4buViKPe7To,1099
43
- fmtr/tools/string_tools.py,sha256=fVJADFWHtGStakgPNOPn_lmnRC94v1VYE1ETCmsvJVA,5298
43
+ fmtr/tools/string_tools.py,sha256=ZKHBrl2tui9VjWt7qit4UWbvpuzY6zp5ytiQvhlJVG4,5610
44
44
  fmtr/tools/tabular_tools.py,sha256=mw6vOij1Ch-pVAyHMPtm5zj__ULZN_TKeBYOfj33wFM,1634
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=PN6bG6VIuodXixpV8uCQygcpWuLKFNtVOv7BZZS_XrQ,6
48
+ fmtr/tools/version,sha256=n4zX1YVX0dMhq7mFDh_xh19zo5isz-FQXXDc31JZieI,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
52
52
  fmtr/tools/ai_tools/agentic_tools.py,sha256=Zj6WcbDc1yLFi3raTSD0BeOkWR3l5RmmccFYGx8-0XE,5534
53
53
  fmtr/tools/ai_tools/inference_tools.py,sha256=2UP2gXEyOJUjyyV6zmFIYmIxUsh1rXkRH0IbFvr2bRs,11908
54
54
  fmtr/tools/database_tools/__init__.py,sha256=-YXEs3P4nwg7hdvALpaW4K2Pg9FIc49rD53smqnBgT4,221
55
- fmtr/tools/database_tools/document.py,sha256=YciaSNYyLSPRFZbHQEVwN-G_7RXgXFaq27IN62--fDA,989
55
+ fmtr/tools/database_tools/document.py,sha256=uGmyznAKqshv8yjFoVRlkPmnSVao3oPJ7iaxvZSpi3g,1214
56
56
  fmtr/tools/dns_tools/__init__.py,sha256=HP0Qcwyi1C6vBH_ejuWrGJOWdp-GZ_cmH-QofjD6Mmg,266
57
57
  fmtr/tools/dns_tools/client.py,sha256=IBbd7Xgx9ExTn_EPoL7ts9JfXokHHuOiD9m4K6tl1Q0,2817
58
58
  fmtr/tools/dns_tools/dm.py,sha256=Lp1HaF7rpVtL_Ji4Bd32B29105H9ZKQ8AcVj_AB7nsA,6678
@@ -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.64.dist-info/licenses/LICENSE,sha256=FW9aa6vVN5IjRQWLT43hs4_koYSmpcbIovlKeAJ0_cI,10757
89
- fmtr_tools-1.3.64.dist-info/METADATA,sha256=8h7PBKhUZ_hxyfZ1P8NA4z4J2qspewCV8Q4GnePKL2M,18035
90
- fmtr_tools-1.3.64.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
91
- fmtr_tools-1.3.64.dist-info/entry_points.txt,sha256=h-r__Xh5njtFqreMLg6cGuTFS4Qh-QqJPU1HB-_BS-Q,357
92
- fmtr_tools-1.3.64.dist-info/top_level.txt,sha256=LXem9xCgNOD72tE2gRKESdiQTL902mfFkwWb6-dlwEE,5
93
- fmtr_tools-1.3.64.dist-info/RECORD,,
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,,