fmtr.tools 1.1.20__py3-none-any.whl → 1.1.22__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
@@ -177,5 +177,6 @@ except ImportError as exception:
177
177
 
178
178
  try:
179
179
  from fmtr.tools import setup_tools as setup
180
+ from fmtr.tools.setup_tools import Setup, SetupPaths, Dependencies
180
181
  except ImportError as exception:
181
- setup = MissingExtraMockModule('setup', exception)
182
+ setup = Setup = SetupPaths = Dependencies = MissingExtraMockModule('setup', exception)
@@ -177,8 +177,14 @@ class Path(type(Path())):
177
177
  kind = path.guess(str(self.absolute()))
178
178
  return kind
179
179
 
180
+ @property
181
+ def children(self):
182
+ if not self.is_dir():
183
+ return None
184
+ return sorted(self.iterdir(), key=lambda x: x.is_dir(), reverse=True)
185
+
180
186
 
181
- class PathsBase:
187
+ class FromCallerMixin:
182
188
  """
183
189
 
184
190
 
@@ -190,7 +196,7 @@ class PathsBase:
190
196
  return path
191
197
 
192
198
 
193
- class PackagePaths(PathsBase):
199
+ class PackagePaths(FromCallerMixin):
194
200
  """
195
201
 
196
202
  Canonical paths for a package.
fmtr/tools/setup_tools.py CHANGED
@@ -1,4 +1,6 @@
1
+ import sys
1
2
  from datetime import datetime
3
+ from fnmatch import fnmatch
2
4
  from functools import cached_property
3
5
  from itertools import chain
4
6
  from typing import List, Dict
@@ -7,17 +9,17 @@ from setuptools import find_namespace_packages, find_packages, setup
7
9
 
8
10
  from fmtr.tools.constants import Constants
9
11
  from fmtr.tools.path_tools import Path
10
- from fmtr.tools.path_tools.path_tools import PathsBase
12
+ from fmtr.tools.path_tools.path_tools import FromCallerMixin
11
13
 
12
14
 
13
- class SetupPaths(PathsBase):
15
+ class SetupPaths(FromCallerMixin):
14
16
  """
15
17
 
16
- Canonical paths for a package.
18
+ Canonical paths for a repo.
17
19
 
18
20
  """
19
21
 
20
- SKIP_DIRS = {'data'}
22
+ SKIP_DIRS = {'data', 'build', 'dist', '.*', '*egg-info*'}
21
23
 
22
24
  def __init__(self, path=None):
23
25
 
@@ -51,18 +53,13 @@ class SetupPaths(PathsBase):
51
53
 
52
54
  directories = [
53
55
  dir for dir in self.repo.iterdir()
54
- if
55
- (
56
- dir.is_dir()
57
- and not dir.name.startswith('.')
58
- and dir.name not in self.SKIP_DIRS
59
- and 'egg-info' not in dir.name
60
- )
56
+ if dir.is_dir()
57
+ and not any(fnmatch(dir.name, pattern) for pattern in self.SKIP_DIRS)
61
58
  ]
62
59
 
63
60
  if len(directories) != 1:
64
61
  dirs_str = ', '.join([str(dir) for dir in directories])
65
- raise ValueError(f'Expected exactly one directory in "{self.repo}", found {dirs_str}')
62
+ raise ValueError(f'Expected exactly one directory in {self.repo}, found {dirs_str}')
66
63
 
67
64
  target = next(iter(directories))
68
65
 
@@ -89,19 +86,56 @@ class SetupPaths(PathsBase):
89
86
  return name
90
87
 
91
88
 
92
- class Setup:
89
+ class Setup(FromCallerMixin):
93
90
  AUTHOR = 'Frontmatter'
94
91
  AUTHOR_EMAIL = 'innovative.fowler@mask.pro.fmtr.dev'
95
92
 
96
- def __init__(self, paths, dependencies, console_scripts=None, client=None, **kwargs):
93
+ REQUIREMENTS_ARG = 'requirements'
94
+
95
+
96
+ def __init__(self, dependencies, paths=None, console_scripts=None, client=None, do_setup=True, **kwargs):
97
97
 
98
98
  self.kwargs = kwargs
99
+
100
+ if type(dependencies) is not Dependencies:
101
+ dependencies = Dependencies(**dependencies)
99
102
  self.dependencies = dependencies
103
+
104
+ requirements_extras = self.get_requirements_extras()
105
+
106
+ if requirements_extras:
107
+ self.print_requirements()
108
+ return
109
+
110
+ if not paths:
111
+ paths = SetupPaths(path=self.from_caller())
100
112
  self.paths = paths
101
113
 
102
114
  self.client = client
103
115
  self.console_scripts = console_scripts
104
116
 
117
+ if do_setup:
118
+ self.setup()
119
+
120
+ def get_requirements_extras(self):
121
+ if self.REQUIREMENTS_ARG not in sys.argv:
122
+ return None
123
+
124
+ extras_str = sys.argv[-1]
125
+ extras = extras_str.split(',')
126
+ return extras
127
+
128
+ def print_requirements(self):
129
+ reqs = []
130
+ reqs += self.dependencies.install
131
+
132
+ for extra in sys.argv[-1].split(','):
133
+ reqs += self.dependencies.extras[extra]
134
+ reqs = '\n'.join(reqs)
135
+ print(reqs)
136
+
137
+
138
+
105
139
  def get_entrypoint_path(self, key, value):
106
140
  if value:
107
141
  return f'{self.name}.{value}:{key}'
@@ -169,7 +203,8 @@ class Setup:
169
203
  def url(self):
170
204
  return f'https://github.com/{self.paths.org}/{self.paths.name}'
171
205
 
172
- def get_data_setup(self):
206
+ @property
207
+ def data(self):
173
208
  return dict(
174
209
  name=self.name,
175
210
  version=self.version,
@@ -188,27 +223,10 @@ class Setup:
188
223
  ) | self.kwargs
189
224
 
190
225
  def setup(self):
191
- data = self.get_data_setup()
192
- return setup(**data)
193
226
 
227
+ return setup(**self.data)
194
228
 
195
- class Entrypoints:
196
- ALL = 'all'
197
- INSTALL = 'install'
198
229
 
199
- def __init__(self, console_scripts=None, **kwargs):
200
- self.kwargs = kwargs
201
- self._console_scripts = console_scripts
202
-
203
- @property
204
- def console_scripts(self):
205
- return [f'{key} = {value}:{key}' for key, value in self._console_scripts.items()]
206
-
207
- @property
208
- def data(self):
209
- return dict(
210
- console_scripts=self.console_scripts,
211
- ) | self.kwargs
212
230
 
213
231
 
214
232
  class Dependencies:
@@ -237,7 +255,7 @@ class Dependencies:
237
255
 
238
256
  return values_resolved
239
257
 
240
- @property
258
+ @cached_property
241
259
  def extras(self) -> Dict[str, List[str]]:
242
260
  """
243
261
 
@@ -249,7 +267,7 @@ class Dependencies:
249
267
  resolved[self.ALL] = list(set(chain.from_iterable(resolved.values())))
250
268
  return resolved
251
269
 
252
- @property
270
+ @cached_property
253
271
  def install(self):
254
272
  return self.resolve_values(self.INSTALL)
255
273
 
fmtr/tools/version CHANGED
@@ -1 +1 @@
1
- 1.1.20
1
+ 1.1.22
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fmtr.tools
3
- Version: 1.1.20
3
+ Version: 1.1.22
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: yamlscript; extra == "test"
13
- Requires-Dist: semver; extra == "test"
14
- Requires-Dist: setuptools; extra == "test"
15
- Requires-Dist: deepmerge; extra == "test"
16
12
  Requires-Dist: google-auth-oauthlib; extra == "test"
17
- Requires-Dist: html2text; extra == "test"
18
- Requires-Dist: pydantic; extra == "test"
19
- Requires-Dist: logfire[httpx]; extra == "test"
20
- Requires-Dist: json_repair; extra == "test"
21
- Requires-Dist: sre_yield; extra == "test"
22
- Requires-Dist: pydantic-settings; extra == "test"
23
13
  Requires-Dist: google-auth-httplib2; extra == "test"
24
- Requires-Dist: tinynetrc; extra == "test"
25
- Requires-Dist: openai; extra == "test"
26
- Requires-Dist: pydevd-pycharm; extra == "test"
27
- Requires-Dist: contexttimer; extra == "test"
28
- Requires-Dist: pymupdf; extra == "test"
29
- Requires-Dist: ollama; extra == "test"
30
- Requires-Dist: dnspython[doh]; extra == "test"
31
- Requires-Dist: pyyaml; extra == "test"
32
- Requires-Dist: huggingface_hub; extra == "test"
33
- Requires-Dist: logfire[fastapi]; extra == "test"
34
- Requires-Dist: transformers[sentencepiece]; extra == "test"
35
- Requires-Dist: google-api-python-client; extra == "test"
36
- Requires-Dist: flet[all]; extra == "test"
37
- Requires-Dist: pytest-cov; extra == "test"
38
- Requires-Dist: torchaudio; extra == "test"
39
- Requires-Dist: flet-video; extra == "test"
14
+ Requires-Dist: json_repair; extra == "test"
15
+ Requires-Dist: pydantic; extra == "test"
16
+ Requires-Dist: docker; extra == "test"
40
17
  Requires-Dist: httpx_retries; extra == "test"
41
- Requires-Dist: faker; extra == "test"
42
- Requires-Dist: pymupdf4llm; extra == "test"
43
- Requires-Dist: filetype; extra == "test"
44
- Requires-Dist: uvicorn[standard]; extra == "test"
45
- Requires-Dist: peft; extra == "test"
46
- Requires-Dist: logfire; extra == "test"
47
18
  Requires-Dist: bokeh; extra == "test"
48
- Requires-Dist: pydantic-ai[logfire,openai]; extra == "test"
49
- Requires-Dist: regex; extra == "test"
50
- Requires-Dist: tabulate; extra == "test"
19
+ Requires-Dist: dask[bag]; extra == "test"
20
+ Requires-Dist: faker; extra == "test"
21
+ Requires-Dist: Unidecode; extra == "test"
22
+ Requires-Dist: tokenizers; extra == "test"
51
23
  Requires-Dist: sentence_transformers; extra == "test"
24
+ Requires-Dist: peft; extra == "test"
25
+ Requires-Dist: flet-webview; extra == "test"
26
+ Requires-Dist: yamlscript; extra == "test"
27
+ Requires-Dist: dnspython[doh]; extra == "test"
28
+ Requires-Dist: flet[all]; extra == "test"
29
+ Requires-Dist: fastapi; extra == "test"
30
+ Requires-Dist: filetype; extra == "test"
31
+ Requires-Dist: pyyaml; extra == "test"
32
+ Requires-Dist: html2text; extra == "test"
33
+ Requires-Dist: ollama; extra == "test"
34
+ Requires-Dist: transformers[sentencepiece]; extra == "test"
52
35
  Requires-Dist: openpyxl; extra == "test"
36
+ Requires-Dist: logfire; extra == "test"
53
37
  Requires-Dist: distributed; extra == "test"
54
- Requires-Dist: dask[bag]; extra == "test"
55
- Requires-Dist: appdirs; extra == "test"
56
- Requires-Dist: Unidecode; extra == "test"
57
- Requires-Dist: docker; extra == "test"
58
- Requires-Dist: httpx; extra == "test"
38
+ Requires-Dist: deepmerge; extra == "test"
39
+ Requires-Dist: pydantic-ai[logfire,openai]; extra == "test"
59
40
  Requires-Dist: diskcache; extra == "test"
41
+ Requires-Dist: pymupdf4llm; extra == "test"
60
42
  Requires-Dist: pandas; extra == "test"
43
+ Requires-Dist: setuptools; extra == "test"
44
+ Requires-Dist: tabulate; extra == "test"
45
+ Requires-Dist: pydantic-settings; extra == "test"
46
+ Requires-Dist: contexttimer; extra == "test"
47
+ Requires-Dist: httpx; extra == "test"
48
+ Requires-Dist: sre_yield; extra == "test"
49
+ Requires-Dist: google-api-python-client; extra == "test"
50
+ Requires-Dist: openai; extra == "test"
51
+ Requires-Dist: appdirs; extra == "test"
52
+ Requires-Dist: logfire[httpx]; extra == "test"
61
53
  Requires-Dist: google-auth; extra == "test"
62
- Requires-Dist: tokenizers; extra == "test"
63
- Requires-Dist: fastapi; extra == "test"
64
- Requires-Dist: flet-webview; extra == "test"
54
+ Requires-Dist: pymupdf; extra == "test"
55
+ Requires-Dist: pydevd-pycharm; extra == "test"
56
+ Requires-Dist: tinynetrc; extra == "test"
57
+ Requires-Dist: logfire[fastapi]; extra == "test"
58
+ Requires-Dist: pytest-cov; extra == "test"
59
+ Requires-Dist: huggingface_hub; extra == "test"
65
60
  Requires-Dist: torchvision; extra == "test"
61
+ Requires-Dist: torchaudio; extra == "test"
62
+ Requires-Dist: semver; extra == "test"
63
+ Requires-Dist: regex; extra == "test"
64
+ Requires-Dist: flet-video; extra == "test"
65
+ Requires-Dist: uvicorn[standard]; 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=KFSvu0OIyX5QsE4_rkFrFhhSxyvYFTaGsLemJqvNAys,5683
1
+ fmtr/tools/__init__.py,sha256=v4XtEHm35sT7Z7-kKdFdBPXw_yFtxF0GOCx4q4y5Qg4,5790
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
@@ -39,14 +39,14 @@ fmtr/tools/profiling_tools.py,sha256=jpXVjaNKPydTasEQVNXvxzGtMhXPit08AnJddkU8uIc
39
39
  fmtr/tools/random_tools.py,sha256=4VlQdk5THbR8ka4pZaLbk_ZO_4yy6PF_lHZes_rgenY,2223
40
40
  fmtr/tools/semantic_tools.py,sha256=cxY9NSAHWj4nEc6Oj4qA1omR3dWbl2OuH7_PkINc6_E,1386
41
41
  fmtr/tools/settings_tools.py,sha256=o11W3T60UZSvCTkh_eEQq1Mx74GycQ6JxUr0plBDbsk,2356
42
- fmtr/tools/setup_tools.py,sha256=J-48XFnBuf1DF3Twt3M1scSbuEEf-yNaBkYXwYLlNVg,7303
42
+ fmtr/tools/setup_tools.py,sha256=_mKoOAv2-vf2Y9HxjUkgblTDUfmWbMTNkOhJeaSN3SE,7712
43
43
  fmtr/tools/spaces_tools.py,sha256=D_he3mve6DruB3OPS6QyzqD05ChHnRTb4buViKPe7To,1099
44
44
  fmtr/tools/string_tools.py,sha256=mjO7NSqhtYMtnX7fKb8eXZ7MO2lXWGMl0kXxnZznupM,3764
45
45
  fmtr/tools/tabular_tools.py,sha256=tpIpZzYku1HcJrHZJL6BC39LmN3WUWVhFbK2N7nDVmE,120
46
46
  fmtr/tools/tokenization_tools.py,sha256=me-IBzSLyNYejLybwjO9CNB6Mj2NYfKPaOVThXyaGNg,4268
47
47
  fmtr/tools/tools.py,sha256=CAsApa1YwVdNE6H66Vjivs_mXYvOas3rh7fPELAnTpk,795
48
48
  fmtr/tools/unicode_tools.py,sha256=yS_9wpu8ogNoiIL7s1G_8bETFFO_YQlo4LNPv1NLDeY,52
49
- fmtr/tools/version,sha256=dLWYVtGE882f5xI3OPEgua_42l7bfjVlF-pj0odcsdo,6
49
+ fmtr/tools/version,sha256=5sJzGyhKAQgHkvJs_DynT9WCkII9EsWuLE-qBuMX-s8,6
50
50
  fmtr/tools/version_tools.py,sha256=yNs_CGqWpqE4jbK9wsPIi14peJVXYbhIcMqHAFOw3yE,1480
51
51
  fmtr/tools/yaml_tools.py,sha256=9kuYChqJelWQIjGlSnK4iDdOWWH06P0gp9jIcRrC3UI,1903
52
52
  fmtr/tools/ai_tools/__init__.py,sha256=JZrLuOFNV1A3wvJgonxOgz_4WS-7MfCuowGWA5uYCjs,372
@@ -54,7 +54,7 @@ fmtr/tools/ai_tools/agentic_tools.py,sha256=YebH7R9ovVo3GzfWAZxY49e2fNt13APDMe29
54
54
  fmtr/tools/ai_tools/inference_tools.py,sha256=2UP2gXEyOJUjyyV6zmFIYmIxUsh1rXkRH0IbFvr2bRs,11908
55
55
  fmtr/tools/path_tools/__init__.py,sha256=v5CpmzXq5Ii90FtcmxAJKiLxmguZMrPnQ_HdT872Np0,443
56
56
  fmtr/tools/path_tools/app_path_tools.py,sha256=JrJvtTDd_gkCKcZtBCDTMktsM77PZwGV_hzQX0g5GU8,1722
57
- fmtr/tools/path_tools/path_tools.py,sha256=Lw7ebHUAOrs-OXLNeM-yVrwV7bn5AO8iWNkcz7ASH5k,7695
57
+ fmtr/tools/path_tools/path_tools.py,sha256=8WBzNctpds5tVT1-FcizAORrBCGlkUbPcfOel-Js7ps,7878
58
58
  fmtr/tools/path_tools/type_path_tools.py,sha256=Zgs-ek-GXRKDIlVDGdg3muB0PIxTg2ba0NeHw6y8FWQ,40
59
59
  fmtr/tools/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
60
60
  fmtr/tools/tests/conftest.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -64,9 +64,9 @@ fmtr/tools/tests/test_environment.py,sha256=iHaiMQfECYZPkPKwfuIZV9uHuWe3aE-p_dN_
64
64
  fmtr/tools/tests/test_json.py,sha256=IeSP4ziPvRcmS8kq7k9tHonC9rN5YYq9GSNT2ul6Msk,287
65
65
  fmtr/tools/tests/test_path.py,sha256=AkZQa6_8BQ-VaCyL_J-iKmdf2ZaM-xFYR37Kun3k4_g,2188
66
66
  fmtr/tools/tests/test_yaml.py,sha256=jc0TwwKu9eC0LvFGNMERdgBue591xwLxYXFbtsRwXVM,287
67
- fmtr_tools-1.1.20.dist-info/licenses/LICENSE,sha256=FW9aa6vVN5IjRQWLT43hs4_koYSmpcbIovlKeAJ0_cI,10757
68
- fmtr_tools-1.1.20.dist-info/METADATA,sha256=D8EESo6eAElR4gnwMVShc3k__fZHNjQrp-rY226DrT4,15735
69
- fmtr_tools-1.1.20.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
70
- fmtr_tools-1.1.20.dist-info/entry_points.txt,sha256=e-eOW1Ml13tbxHC6Er1MnVOEDePeWw7DKwlE-l-gCY0,205
71
- fmtr_tools-1.1.20.dist-info/top_level.txt,sha256=LXem9xCgNOD72tE2gRKESdiQTL902mfFkwWb6-dlwEE,5
72
- fmtr_tools-1.1.20.dist-info/RECORD,,
67
+ fmtr_tools-1.1.22.dist-info/licenses/LICENSE,sha256=FW9aa6vVN5IjRQWLT43hs4_koYSmpcbIovlKeAJ0_cI,10757
68
+ fmtr_tools-1.1.22.dist-info/METADATA,sha256=UPj-c1mI7NPzMe11YWIMkoXU8sR-7XaKKjnIY76Zjeg,15735
69
+ fmtr_tools-1.1.22.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
70
+ fmtr_tools-1.1.22.dist-info/entry_points.txt,sha256=e-eOW1Ml13tbxHC6Er1MnVOEDePeWw7DKwlE-l-gCY0,205
71
+ fmtr_tools-1.1.22.dist-info/top_level.txt,sha256=LXem9xCgNOD72tE2gRKESdiQTL902mfFkwWb6-dlwEE,5
72
+ fmtr_tools-1.1.22.dist-info/RECORD,,