fmtr.tools 1.1.23__py3-none-any.whl → 1.1.25__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/__init__.py CHANGED
@@ -31,7 +31,7 @@ from fmtr.tools.path_tools import Path, PackagePaths, AppPaths
31
31
  from fmtr.tools import ai_tools as ai
32
32
 
33
33
  import fmtr.tools.setup_tools as setup
34
- from fmtr.tools.setup_tools import Setup, SetupPaths, Dependencies
34
+ from fmtr.tools.setup_tools import Setup, SetupPaths, Dependencies, Tools
35
35
 
36
36
  try:
37
37
  from fmtr.tools import augmentation_tools as augmentation
@@ -1,6 +1,6 @@
1
1
  from fmtr.tools.import_tools import MissingExtraMockModule
2
2
 
3
- from fmtr.tools.setup_tools.setup_tools import Setup, SetupPaths, Dependencies
3
+ from fmtr.tools.setup_tools.setup_tools import Setup, SetupPaths, Dependencies, Tools
4
4
 
5
5
  try:
6
6
  from setuptools import find_namespace_packages, find_packages, setup as setup_setuptools
@@ -1,6 +1,5 @@
1
1
  import sys
2
2
  from datetime import datetime
3
- from fnmatch import fnmatch
4
3
  from functools import cached_property
5
4
  from itertools import chain
6
5
  from typing import List, Dict
@@ -17,9 +16,7 @@ class SetupPaths(FromCallerMixin):
17
16
 
18
17
  """
19
18
 
20
- SKIP_DIRS = {'data', 'build', 'dist', '.*', '*egg-info*'}
21
-
22
- def __init__(self, path=None):
19
+ def __init__(self, path=None, org=Constants.ORG_NAME):
23
20
 
24
21
  """
25
22
 
@@ -29,15 +26,9 @@ class SetupPaths(FromCallerMixin):
29
26
  if not path:
30
27
  path = self.from_caller()
31
28
 
29
+ self.org_name = org
32
30
  self.repo = Path(path)
33
31
 
34
- @property
35
- def path(self):
36
- if self.is_namespace:
37
- return self.repo / self.org / self.name
38
- else:
39
- return self.repo / self.name
40
-
41
32
  @property
42
33
  def readme(self):
43
34
  return self.repo / 'README.md'
@@ -47,41 +38,40 @@ class SetupPaths(FromCallerMixin):
47
38
  return self.path / Constants.FILENAME_VERSION
48
39
 
49
40
  @cached_property
50
- def layout(self):
41
+ def path(self):
42
+
43
+ from fmtr.tools import setup
44
+
45
+ if self.org:
46
+ base = self.org
47
+ else:
48
+ base = self.repo
51
49
 
52
- directories = [
53
- dir for dir in self.repo.iterdir()
54
- if dir.is_dir()
55
- and not any(fnmatch(dir.name, pattern) for pattern in self.SKIP_DIRS)
56
- ]
50
+ directories = [base / dir for dir in setup.find_packages(base)]
57
51
 
58
52
  if len(directories) != 1:
59
53
  dirs_str = ', '.join([str(dir) for dir in directories])
60
54
  raise ValueError(f'Expected exactly one directory in {self.repo}, found {dirs_str}')
61
55
 
62
- target = next(iter(directories))
63
-
64
- contents = list(target.iterdir())
65
- if len(contents) == 1 and (item := next(iter(contents))).is_dir():
66
- return True, target.name, item.name
67
-
68
- else:
69
- return False, None, target.name
56
+ package = next(iter(directories))
57
+ return package
70
58
 
71
59
  @property
72
- def is_namespace(self) -> str:
73
- is_namespace, org, name = self.layout
74
- return is_namespace
60
+ def org(self):
61
+ if not self.org_name:
62
+ return False
63
+ org = self.repo / self.org_name
64
+ if not org.is_dir():
65
+ return False
66
+ return org
75
67
 
76
68
  @property
77
- def org(self) -> str:
78
- is_namespace, org, name = self.layout
79
- return org
69
+ def is_namespace(self) -> bool:
70
+ return bool(self.org)
80
71
 
81
72
  @property
82
73
  def name(self) -> str:
83
- is_namespace, org, name = self.layout
84
- return name
74
+ return self.path.stem
85
75
 
86
76
 
87
77
  class Setup(FromCallerMixin):
@@ -89,9 +79,9 @@ class Setup(FromCallerMixin):
89
79
  AUTHOR_EMAIL = 'innovative.fowler@mask.pro.fmtr.dev'
90
80
 
91
81
  REQUIREMENTS_ARG = 'requirements'
82
+ SKIP_DIRS = {'data', 'build', 'dist', '.*', '*egg-info*'}
92
83
 
93
-
94
- def __init__(self, dependencies, paths=None, console_scripts=None, client=None, do_setup=True, **kwargs):
84
+ def __init__(self, dependencies, paths=None, org=Constants.ORG_NAME, console_scripts=None, client=None, do_setup=True, **kwargs):
95
85
 
96
86
  self.kwargs = kwargs
97
87
 
@@ -105,8 +95,10 @@ class Setup(FromCallerMixin):
105
95
  self.print_requirements()
106
96
  return
107
97
 
98
+ self.org = org
99
+
108
100
  if not paths:
109
- paths = SetupPaths(path=self.from_caller())
101
+ paths = SetupPaths(path=self.from_caller(), org=self.org)
110
102
  self.paths = paths
111
103
 
112
104
  self.client = client
@@ -189,7 +181,7 @@ class Setup(FromCallerMixin):
189
181
  @property
190
182
  def packages(self):
191
183
 
192
- excludes = list(SetupPaths.SKIP_DIRS) + [f'{name}.*' for name in SetupPaths.SKIP_DIRS]
184
+ excludes = list(self.SKIP_DIRS) + [f'{name}.*' for name in self.SKIP_DIRS if '*' not in name]
193
185
 
194
186
  packages = self.find(where=str(self.paths.repo), exclude=excludes)
195
187
  return packages
@@ -211,7 +203,7 @@ class Setup(FromCallerMixin):
211
203
 
212
204
  @property
213
205
  def data(self):
214
- return dict(
206
+ data = dict(
215
207
  name=self.name,
216
208
  version=self.version,
217
209
  author=self.author,
@@ -227,6 +219,7 @@ class Setup(FromCallerMixin):
227
219
  install_requires=self.dependencies.install,
228
220
  extras_require=self.dependencies.extras,
229
221
  ) | self.kwargs
222
+ return data
230
223
 
231
224
  def setup(self):
232
225
 
@@ -235,6 +228,16 @@ class Setup(FromCallerMixin):
235
228
  return setup.setup_setuptools(**self.data)
236
229
 
237
230
 
231
+ class Tools:
232
+ MASK = f'{Constants.LIBRARY_NAME}[{{extras}}]'
233
+
234
+ def __init__(self, *extras):
235
+ self.extras = extras
236
+
237
+ def __str__(self):
238
+ extras_str = ','.join(self.extras)
239
+ return self.MASK.format(extras=extras_str)
240
+
238
241
 
239
242
 
240
243
  class Dependencies:
@@ -256,7 +259,7 @@ class Dependencies:
256
259
  for value in values:
257
260
  if value == key or value not in self.dependencies:
258
261
  # Add the value directly if it references itself or is not a dependency key.
259
- values_resolved.append(value)
262
+ values_resolved.append(str(value))
260
263
  else:
261
264
  # Recurse into nested dependencies.
262
265
  values_resolved += self.resolve_values(value)
fmtr/tools/version CHANGED
@@ -1 +1 @@
1
- 1.1.23
1
+ 1.1.25
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fmtr.tools
3
- Version: 1.1.23
3
+ Version: 1.1.25
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
@@ -9,60 +9,60 @@ License: Copyright © 2025 Frontmatter. All rights reserved.
9
9
  Description-Content-Type: text/markdown
10
10
  License-File: LICENSE
11
11
  Provides-Extra: test
12
- Requires-Dist: pytest-cov; extra == "test"
13
- Requires-Dist: yamlscript; extra == "test"
12
+ Requires-Dist: google-auth; extra == "test"
14
13
  Requires-Dist: pandas; extra == "test"
14
+ Requires-Dist: sre_yield; extra == "test"
15
+ Requires-Dist: semver; extra == "test"
16
+ Requires-Dist: dask[bag]; extra == "test"
17
+ Requires-Dist: torchaudio; extra == "test"
18
+ Requires-Dist: ollama; extra == "test"
19
+ Requires-Dist: sentence_transformers; extra == "test"
20
+ Requires-Dist: fastapi; extra == "test"
21
+ Requires-Dist: faker; extra == "test"
22
+ Requires-Dist: html2text; extra == "test"
23
+ Requires-Dist: pymupdf; extra == "test"
24
+ Requires-Dist: pydantic-ai[logfire,openai]; extra == "test"
25
+ Requires-Dist: uvicorn[standard]; extra == "test"
15
26
  Requires-Dist: regex; extra == "test"
16
27
  Requires-Dist: docker; extra == "test"
17
- Requires-Dist: json_repair; extra == "test"
18
- Requires-Dist: uvicorn[standard]; extra == "test"
19
- Requires-Dist: pymupdf; extra == "test"
20
- Requires-Dist: logfire[fastapi]; extra == "test"
21
28
  Requires-Dist: logfire[httpx]; extra == "test"
22
- Requires-Dist: pymupdf4llm; extra == "test"
23
- Requires-Dist: sentence_transformers; extra == "test"
24
- Requires-Dist: dnspython[doh]; extra == "test"
25
- Requires-Dist: fastapi; extra == "test"
26
- Requires-Dist: torchvision; extra == "test"
29
+ Requires-Dist: transformers[sentencepiece]; extra == "test"
30
+ Requires-Dist: bokeh; extra == "test"
31
+ Requires-Dist: tokenizers; extra == "test"
27
32
  Requires-Dist: httpx_retries; extra == "test"
28
- Requires-Dist: flet[all]; extra == "test"
33
+ Requires-Dist: huggingface_hub; extra == "test"
29
34
  Requires-Dist: pydantic-settings; extra == "test"
30
- Requires-Dist: ollama; extra == "test"
31
- Requires-Dist: diskcache; extra == "test"
32
- Requires-Dist: torchaudio; extra == "test"
33
- Requires-Dist: pydantic-ai[logfire,openai]; extra == "test"
34
- Requires-Dist: faker; extra == "test"
35
+ Requires-Dist: google-auth-oauthlib; extra == "test"
36
+ Requires-Dist: google-api-python-client; extra == "test"
35
37
  Requires-Dist: pydantic; extra == "test"
36
- Requires-Dist: distributed; extra == "test"
37
- Requires-Dist: dask[bag]; extra == "test"
38
- Requires-Dist: sre_yield; extra == "test"
39
38
  Requires-Dist: tabulate; extra == "test"
40
- Requires-Dist: html2text; extra == "test"
39
+ Requires-Dist: distributed; extra == "test"
40
+ Requires-Dist: logfire; extra == "test"
41
+ Requires-Dist: flet-webview; extra == "test"
41
42
  Requires-Dist: tinynetrc; extra == "test"
42
- Requires-Dist: setuptools; extra == "test"
43
+ Requires-Dist: deepmerge; extra == "test"
43
44
  Requires-Dist: pyyaml; extra == "test"
44
- Requires-Dist: openpyxl; extra == "test"
45
- Requires-Dist: flet-video; extra == "test"
46
- Requires-Dist: openai; extra == "test"
47
- Requires-Dist: flet-webview; extra == "test"
48
- Requires-Dist: pydevd-pycharm; extra == "test"
49
45
  Requires-Dist: contexttimer; extra == "test"
50
- Requires-Dist: google-auth; extra == "test"
51
- Requires-Dist: semver; extra == "test"
52
- Requires-Dist: huggingface_hub; extra == "test"
53
- Requires-Dist: tokenizers; extra == "test"
54
- Requires-Dist: peft; extra == "test"
55
- Requires-Dist: logfire; extra == "test"
56
- Requires-Dist: google-auth-oauthlib; extra == "test"
46
+ Requires-Dist: pytest-cov; extra == "test"
57
47
  Requires-Dist: filetype; extra == "test"
58
- Requires-Dist: deepmerge; extra == "test"
59
- Requires-Dist: google-api-python-client; extra == "test"
60
- Requires-Dist: bokeh; extra == "test"
48
+ Requires-Dist: setuptools; extra == "test"
49
+ Requires-Dist: flet[all]; extra == "test"
50
+ Requires-Dist: diskcache; extra == "test"
51
+ Requires-Dist: openpyxl; extra == "test"
52
+ Requires-Dist: dnspython[doh]; extra == "test"
53
+ Requires-Dist: openai; extra == "test"
54
+ Requires-Dist: logfire[fastapi]; extra == "test"
61
55
  Requires-Dist: httpx; extra == "test"
56
+ Requires-Dist: yamlscript; extra == "test"
57
+ Requires-Dist: pydevd-pycharm; extra == "test"
62
58
  Requires-Dist: google-auth-httplib2; extra == "test"
63
59
  Requires-Dist: appdirs; extra == "test"
64
60
  Requires-Dist: Unidecode; extra == "test"
65
- Requires-Dist: transformers[sentencepiece]; extra == "test"
61
+ Requires-Dist: flet-video; extra == "test"
62
+ Requires-Dist: pymupdf4llm; extra == "test"
63
+ Requires-Dist: json_repair; extra == "test"
64
+ Requires-Dist: torchvision; extra == "test"
65
+ Requires-Dist: peft; extra == "test"
66
66
  Provides-Extra: yaml
67
67
  Requires-Dist: yamlscript; extra == "yaml"
68
68
  Requires-Dist: pyyaml; extra == "yaml"
@@ -1,4 +1,4 @@
1
- fmtr/tools/__init__.py,sha256=PeQKmb9q7xTaiDGy7TUa_5V2lh8k0rV0BJgjwf37udI,5571
1
+ fmtr/tools/__init__.py,sha256=SMYBulUmtwW27eKblcTq1GCZjSOQDPiZBUCd2mRcTGc,5578
2
2
  fmtr/tools/api_tools.py,sha256=w8Zrp_EwN5KlUghwLoTCXo4z1irg5tAsReCqDLjASfE,2133
3
3
  fmtr/tools/async_tools.py,sha256=ewz757WcveQJd-G5SVr2JDOQVbdLGecCgl-tsBGVZz4,284
4
4
  fmtr/tools/augmentation_tools.py,sha256=-6ESbO4CDlKqVOV1J1V6qBeoBMzbFIinkDHRHnCBej0,55
@@ -45,7 +45,7 @@ fmtr/tools/tabular_tools.py,sha256=tpIpZzYku1HcJrHZJL6BC39LmN3WUWVhFbK2N7nDVmE,1
45
45
  fmtr/tools/tokenization_tools.py,sha256=me-IBzSLyNYejLybwjO9CNB6Mj2NYfKPaOVThXyaGNg,4268
46
46
  fmtr/tools/tools.py,sha256=CAsApa1YwVdNE6H66Vjivs_mXYvOas3rh7fPELAnTpk,795
47
47
  fmtr/tools/unicode_tools.py,sha256=yS_9wpu8ogNoiIL7s1G_8bETFFO_YQlo4LNPv1NLDeY,52
48
- fmtr/tools/version,sha256=3LplPseqc2k-fqP6873j8m5kUAOUMVJ7Cpo-3h23Q3s,6
48
+ fmtr/tools/version,sha256=MXtcMHPDkm9DBt901I2qwVZouqD5wzakzj7n9M5gDCI,6
49
49
  fmtr/tools/version_tools.py,sha256=yNs_CGqWpqE4jbK9wsPIi14peJVXYbhIcMqHAFOw3yE,1480
50
50
  fmtr/tools/yaml_tools.py,sha256=9kuYChqJelWQIjGlSnK4iDdOWWH06P0gp9jIcRrC3UI,1903
51
51
  fmtr/tools/ai_tools/__init__.py,sha256=JZrLuOFNV1A3wvJgonxOgz_4WS-7MfCuowGWA5uYCjs,372
@@ -55,8 +55,8 @@ fmtr/tools/path_tools/__init__.py,sha256=v5CpmzXq5Ii90FtcmxAJKiLxmguZMrPnQ_HdT87
55
55
  fmtr/tools/path_tools/app_path_tools.py,sha256=JrJvtTDd_gkCKcZtBCDTMktsM77PZwGV_hzQX0g5GU8,1722
56
56
  fmtr/tools/path_tools/path_tools.py,sha256=8WBzNctpds5tVT1-FcizAORrBCGlkUbPcfOel-Js7ps,7878
57
57
  fmtr/tools/path_tools/type_path_tools.py,sha256=Zgs-ek-GXRKDIlVDGdg3muB0PIxTg2ba0NeHw6y8FWQ,40
58
- fmtr/tools/setup_tools/__init__.py,sha256=8HX-GvGxeCK3nIHH5PHkvhkH0MIt89AK8a5l6Vua2dQ,379
59
- fmtr/tools/setup_tools/setup_tools.py,sha256=1pbpQ70PeGfgkWpKQx1rQ8GoIYCArzw22uyuCT93Qas,7790
58
+ fmtr/tools/setup_tools/__init__.py,sha256=fUCjzyE4JBPEOZhC4B--VPj_eOCkQb1QG5PIgiGj03U,386
59
+ fmtr/tools/setup_tools/setup_tools.py,sha256=A70uc80HrfvTh41LOizC14jQEY6N-ol4O-PkxYIJNBQ,7803
60
60
  fmtr/tools/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
61
61
  fmtr/tools/tests/conftest.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
62
62
  fmtr/tools/tests/helpers.py,sha256=N5sf9YoZV93a7tf_UxpLeyQ9vp6Ec0teNIimFDvc054,1091
@@ -65,9 +65,9 @@ fmtr/tools/tests/test_environment.py,sha256=iHaiMQfECYZPkPKwfuIZV9uHuWe3aE-p_dN_
65
65
  fmtr/tools/tests/test_json.py,sha256=IeSP4ziPvRcmS8kq7k9tHonC9rN5YYq9GSNT2ul6Msk,287
66
66
  fmtr/tools/tests/test_path.py,sha256=AkZQa6_8BQ-VaCyL_J-iKmdf2ZaM-xFYR37Kun3k4_g,2188
67
67
  fmtr/tools/tests/test_yaml.py,sha256=jc0TwwKu9eC0LvFGNMERdgBue591xwLxYXFbtsRwXVM,287
68
- fmtr_tools-1.1.23.dist-info/licenses/LICENSE,sha256=FW9aa6vVN5IjRQWLT43hs4_koYSmpcbIovlKeAJ0_cI,10757
69
- fmtr_tools-1.1.23.dist-info/METADATA,sha256=ywC-2AZET6ohT0uWvxuHEAZ9IgcEiNjkUB7DDKHiCL4,15735
70
- fmtr_tools-1.1.23.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
71
- fmtr_tools-1.1.23.dist-info/entry_points.txt,sha256=e-eOW1Ml13tbxHC6Er1MnVOEDePeWw7DKwlE-l-gCY0,205
72
- fmtr_tools-1.1.23.dist-info/top_level.txt,sha256=LXem9xCgNOD72tE2gRKESdiQTL902mfFkwWb6-dlwEE,5
73
- fmtr_tools-1.1.23.dist-info/RECORD,,
68
+ fmtr_tools-1.1.25.dist-info/licenses/LICENSE,sha256=FW9aa6vVN5IjRQWLT43hs4_koYSmpcbIovlKeAJ0_cI,10757
69
+ fmtr_tools-1.1.25.dist-info/METADATA,sha256=4suZ_4qo32TLcy5mPDvTPyr-4ewe_ygsW92UYBbqzDs,15735
70
+ fmtr_tools-1.1.25.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
71
+ fmtr_tools-1.1.25.dist-info/entry_points.txt,sha256=e-eOW1Ml13tbxHC6Er1MnVOEDePeWw7DKwlE-l-gCY0,205
72
+ fmtr_tools-1.1.25.dist-info/top_level.txt,sha256=LXem9xCgNOD72tE2gRKESdiQTL902mfFkwWb6-dlwEE,5
73
+ fmtr_tools-1.1.25.dist-info/RECORD,,