fmtr.tools 1.1.24__tar.gz → 1.1.26__tar.gz

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.

Files changed (80) hide show
  1. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/PKG-INFO +43 -43
  2. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/__init__.py +7 -1
  3. fmtr_tools-1.1.26/fmtr/tools/http_tools.py +26 -0
  4. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/pattern_tools.py +7 -72
  5. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/setup_tools/__init__.py +1 -1
  6. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/setup_tools/setup_tools.py +16 -11
  7. fmtr_tools-1.1.26/fmtr/tools/version +1 -0
  8. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr.tools.egg-info/PKG-INFO +43 -43
  9. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr.tools.egg-info/SOURCES.txt +1 -0
  10. fmtr_tools-1.1.24/fmtr/tools/version +0 -1
  11. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/LICENSE +0 -0
  12. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/README.md +0 -0
  13. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/ai_tools/__init__.py +0 -0
  14. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/ai_tools/agentic_tools.py +0 -0
  15. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/ai_tools/inference_tools.py +0 -0
  16. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/api_tools.py +0 -0
  17. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/async_tools.py +0 -0
  18. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/augmentation_tools.py +0 -0
  19. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/caching_tools.py +0 -0
  20. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/console_script_tools.py +0 -0
  21. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/constants.py +0 -0
  22. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/data_modelling_tools.py +0 -0
  23. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/dataclass_tools.py +0 -0
  24. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/datatype_tools.py +0 -0
  25. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/debugging_tools.py +0 -0
  26. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/dns_tools.py +0 -0
  27. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/docker_tools.py +0 -0
  28. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/environment_tools.py +0 -0
  29. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/function_tools.py +0 -0
  30. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/google_api_tools.py +0 -0
  31. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/hash_tools.py +0 -0
  32. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/hfh_tools.py +0 -0
  33. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/html_tools.py +0 -0
  34. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/import_tools.py +0 -0
  35. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/inspection_tools.py +0 -0
  36. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/interface_tools.py +0 -0
  37. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/iterator_tools.py +0 -0
  38. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/json_fix_tools.py +0 -0
  39. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/json_tools.py +0 -0
  40. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/logging_tools.py +0 -0
  41. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/merging_tools.py +0 -0
  42. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/metric_tools.py +0 -0
  43. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/name_tools.py +0 -0
  44. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/netrc_tools.py +0 -0
  45. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/openai_tools.py +0 -0
  46. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/packaging_tools.py +0 -0
  47. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/parallel_tools.py +0 -0
  48. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/path_tools/__init__.py +0 -0
  49. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/path_tools/app_path_tools.py +0 -0
  50. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/path_tools/path_tools.py +0 -0
  51. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/path_tools/type_path_tools.py +0 -0
  52. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/pdf_tools.py +0 -0
  53. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/platform_tools.py +0 -0
  54. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/process_tools.py +0 -0
  55. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/profiling_tools.py +0 -0
  56. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/random_tools.py +0 -0
  57. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/semantic_tools.py +0 -0
  58. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/settings_tools.py +0 -0
  59. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/spaces_tools.py +0 -0
  60. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/string_tools.py +0 -0
  61. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/tabular_tools.py +0 -0
  62. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/tests/__init__.py +0 -0
  63. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/tests/conftest.py +0 -0
  64. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/tests/helpers.py +0 -0
  65. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/tests/test_datatype.py +0 -0
  66. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/tests/test_environment.py +0 -0
  67. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/tests/test_json.py +0 -0
  68. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/tests/test_path.py +0 -0
  69. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/tests/test_yaml.py +0 -0
  70. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/tokenization_tools.py +0 -0
  71. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/tools.py +0 -0
  72. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/unicode_tools.py +0 -0
  73. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/version_tools.py +0 -0
  74. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr/tools/yaml_tools.py +0 -0
  75. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr.tools.egg-info/dependency_links.txt +0 -0
  76. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr.tools.egg-info/entry_points.txt +0 -0
  77. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr.tools.egg-info/requires.txt +42 -42
  78. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/fmtr.tools.egg-info/top_level.txt +0 -0
  79. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/setup.cfg +0 -0
  80. {fmtr_tools-1.1.24 → fmtr_tools-1.1.26}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fmtr.tools
3
- Version: 1.1.24
3
+ Version: 1.1.26
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: openpyxl; extra == "test"
13
- Requires-Dist: Unidecode; extra == "test"
14
- Requires-Dist: pyyaml; extra == "test"
15
- Requires-Dist: flet-video; extra == "test"
16
- Requires-Dist: dask[bag]; extra == "test"
17
- Requires-Dist: appdirs; extra == "test"
12
+ Requires-Dist: torchaudio; extra == "test"
18
13
  Requires-Dist: semver; extra == "test"
14
+ Requires-Dist: docker; extra == "test"
15
+ Requires-Dist: logfire; extra == "test"
16
+ Requires-Dist: ollama; extra == "test"
17
+ Requires-Dist: openpyxl; extra == "test"
18
+ Requires-Dist: flet[all]; extra == "test"
19
+ Requires-Dist: diskcache; extra == "test"
19
20
  Requires-Dist: pymupdf; extra == "test"
20
- Requires-Dist: bokeh; extra == "test"
21
- Requires-Dist: tabulate; extra == "test"
22
- Requires-Dist: uvicorn[standard]; extra == "test"
23
- Requires-Dist: transformers[sentencepiece]; extra == "test"
24
- Requires-Dist: google-auth-oauthlib; extra == "test"
25
- Requires-Dist: dnspython[doh]; extra == "test"
21
+ Requires-Dist: pydevd-pycharm; extra == "test"
22
+ Requires-Dist: filetype; extra == "test"
26
23
  Requires-Dist: sentence_transformers; extra == "test"
27
- Requires-Dist: pydantic-settings; extra == "test"
28
- Requires-Dist: deepmerge; extra == "test"
29
- Requires-Dist: pydantic; extra == "test"
30
- Requires-Dist: httpx_retries; extra == "test"
31
- Requires-Dist: logfire; extra == "test"
32
- Requires-Dist: google-auth-httplib2; extra == "test"
33
- Requires-Dist: torchvision; extra == "test"
34
- Requires-Dist: pymupdf4llm; extra == "test"
35
- Requires-Dist: torchaudio; extra == "test"
36
- Requires-Dist: contexttimer; extra == "test"
37
- Requires-Dist: distributed; extra == "test"
38
24
  Requires-Dist: peft; extra == "test"
39
- Requires-Dist: httpx; extra == "test"
40
- Requires-Dist: regex; extra == "test"
41
- Requires-Dist: yamlscript; extra == "test"
42
- Requires-Dist: filetype; extra == "test"
43
- Requires-Dist: pydevd-pycharm; extra == "test"
25
+ Requires-Dist: flet-video; extra == "test"
26
+ Requires-Dist: appdirs; extra == "test"
44
27
  Requires-Dist: huggingface_hub; extra == "test"
45
- Requires-Dist: sre_yield; extra == "test"
46
28
  Requires-Dist: flet-webview; extra == "test"
47
- Requires-Dist: json_repair; extra == "test"
29
+ Requires-Dist: httpx; extra == "test"
30
+ Requires-Dist: deepmerge; extra == "test"
48
31
  Requires-Dist: pytest-cov; extra == "test"
49
- Requires-Dist: fastapi; extra == "test"
50
- Requires-Dist: tinynetrc; extra == "test"
51
- Requires-Dist: google-api-python-client; extra == "test"
52
- Requires-Dist: ollama; extra == "test"
53
- Requires-Dist: tokenizers; extra == "test"
54
- Requires-Dist: diskcache; extra == "test"
55
- Requires-Dist: pydantic-ai[logfire,openai]; extra == "test"
32
+ Requires-Dist: dnspython[doh]; extra == "test"
33
+ Requires-Dist: regex; extra == "test"
34
+ Requires-Dist: openai; extra == "test"
56
35
  Requires-Dist: html2text; extra == "test"
36
+ Requires-Dist: yamlscript; extra == "test"
37
+ Requires-Dist: pydantic-settings; extra == "test"
38
+ Requires-Dist: dask[bag]; extra == "test"
39
+ Requires-Dist: tinynetrc; extra == "test"
57
40
  Requires-Dist: pandas; extra == "test"
58
- Requires-Dist: setuptools; extra == "test"
41
+ Requires-Dist: bokeh; extra == "test"
42
+ Requires-Dist: uvicorn[standard]; extra == "test"
43
+ Requires-Dist: torchvision; extra == "test"
44
+ Requires-Dist: logfire[fastapi]; extra == "test"
45
+ Requires-Dist: Unidecode; extra == "test"
46
+ Requires-Dist: tabulate; extra == "test"
47
+ Requires-Dist: distributed; extra == "test"
48
+ Requires-Dist: tokenizers; extra == "test"
59
49
  Requires-Dist: faker; extra == "test"
60
- Requires-Dist: openai; extra == "test"
50
+ Requires-Dist: contexttimer; extra == "test"
51
+ Requires-Dist: google-auth-oauthlib; extra == "test"
52
+ Requires-Dist: fastapi; extra == "test"
53
+ Requires-Dist: google-api-python-client; extra == "test"
61
54
  Requires-Dist: logfire[httpx]; extra == "test"
62
- Requires-Dist: docker; extra == "test"
63
- Requires-Dist: logfire[fastapi]; extra == "test"
64
- Requires-Dist: flet[all]; extra == "test"
55
+ Requires-Dist: json_repair; extra == "test"
56
+ Requires-Dist: pymupdf4llm; extra == "test"
57
+ Requires-Dist: sre_yield; extra == "test"
58
+ Requires-Dist: setuptools; extra == "test"
59
+ Requires-Dist: transformers[sentencepiece]; extra == "test"
60
+ Requires-Dist: pydantic-ai[logfire,openai]; extra == "test"
61
+ Requires-Dist: pydantic; extra == "test"
65
62
  Requires-Dist: google-auth; extra == "test"
63
+ Requires-Dist: pyyaml; extra == "test"
64
+ Requires-Dist: google-auth-httplib2; extra == "test"
65
+ Requires-Dist: httpx_retries; extra == "test"
66
66
  Provides-Extra: yaml
67
67
  Requires-Dist: yamlscript; extra == "yaml"
68
68
  Requires-Dist: pyyaml; extra == "yaml"
@@ -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
@@ -176,3 +176,9 @@ try:
176
176
  from fmtr.tools import dns_tools as dns
177
177
  except ImportError as exception:
178
178
  dns = MissingExtraMockModule('dns', exception)
179
+
180
+ try:
181
+ from fmtr.tools import http_tools as http
182
+ from fmtr.tools.http_tools import Client
183
+ except ImportError as exception:
184
+ http = Client = MissingExtraMockModule('http', exception)
@@ -0,0 +1,26 @@
1
+ import httpx
2
+ from httpx_retries import RetryTransport
3
+
4
+ from fmtr.tools import logging_tools
5
+
6
+ logging_tools.logger.instrument_httpx()
7
+
8
+
9
+ class Client(httpx.Client):
10
+ """
11
+
12
+ Instrumented client base
13
+
14
+ """
15
+
16
+ TRANSPORT = RetryTransport()
17
+
18
+ def __init__(self, *args, **kwargs):
19
+ super().__init__(*args, transport=self.TRANSPORT, **kwargs)
20
+
21
+
22
+ client = Client()
23
+
24
+ if __name__ == '__main__':
25
+ resp = client.get('http://httpbin.org/delay/10')
26
+ resp
@@ -1,8 +1,9 @@
1
- import regex as re
2
1
  from dataclasses import dataclass
3
2
  from functools import cached_property
4
3
  from typing import List
5
4
 
5
+ import regex as re
6
+
6
7
  from fmtr.tools.logging_tools import logger
7
8
 
8
9
 
@@ -15,7 +16,7 @@ class RewriteCircularLoopError(Exception):
15
16
 
16
17
 
17
18
  @dataclass
18
- class Rule:
19
+ class Rewrite:
19
20
  """
20
21
  Represents a single rule for pattern matching and target string replacement.
21
22
 
@@ -66,7 +67,7 @@ class Rewriter:
66
67
  recursive rewriting until a stable state is reached.
67
68
 
68
69
  """
69
- rules: List[Rule]
70
+ rules: List[Rewrite]
70
71
 
71
72
  @cached_property
72
73
  def pattern(self):
@@ -106,7 +107,7 @@ class Rewriter:
106
107
 
107
108
  """
108
109
 
109
- match = self.rx.match(source)
110
+ match = self.rx.fullmatch(source)
110
111
 
111
112
  if not match:
112
113
  return source
@@ -163,75 +164,9 @@ class Rewriter:
163
164
 
164
165
  @classmethod
165
166
  def from_data(cls, data):
166
- rules = [Rule(*pair) for pair in data.items()]
167
+ rules = [Rewrite(*pair) for pair in data.items()]
167
168
  self = cls(rules=rules)
168
169
  return self
169
170
 
170
171
 
171
- if __name__ == '__main__':
172
- data = {
173
-
174
- r'(?P<name>[a-z]+)\.dev\.example\.com': '{name}.test.example.com',
175
- r'img\d+\.static\.cdn\.example\.com': 'images.cdn.example.com',
176
- r'service\.(?P<env>dev|staging|prod)\.example\.org': '{env}-service.example.org',
177
- r'legacy\.(?P<region>[a-z]+)\.oldsite\.com': '{region}.newsitenow.com',
178
- r'shop\.(?P<country_code>[a-z]{2})\.example\.net': 'store.{country_code}.example.net',
179
- r'(?P<user>[a-z]+)\.mail\.example\.com': '{user}.email.example.com',
180
- r'app1\.cluster(?P<num>[0-9]+)\.example\.cloud': 'service{num}.example.cloud',
181
- r'(?P<project>[a-z]+)\.research\.corp\.com': '{project}.lab.corp.com',
182
- r'cdn\.(?P<version>v[0-9]+)\.content\.net': 'static.{version}.content.net',
183
- # Literal rule without named group
184
- r'corp\.secureaccess\.com': 'access.corp.com',
185
- # Literal rule without named group
186
- r'redirect\.oldsite\.org': 'homepage.newsite.org',
187
- # # Recursive rules
188
-
189
- r'archive\.(?P<year>\d{4})\.oldsite\.net': 'legacy.{year}.oldsite.net', # Recursive matching
190
- r'legacy\.(?P<year>\d{4})\.oldsite\.net': 'archive-backup.{year}.net', # Continuation
191
-
192
- # r'(?P<subd>[a-zA-Z]+)\.vpn': '{subd}.loop.ts.net',
193
- # r'(?P<subd>[a-zA-Z]+)\.loop\.ts\.net': '{subd}.vpn', # Recursive loop back to .vpn
194
- }
195
-
196
- rewriter = Rewriter.from_data(data)
197
-
198
- tests = [
199
- "sales.vpn",
200
- "marketing.dev.example.com",
201
- "img01.static.cdn.example.com",
202
- "service.dev.example.org",
203
- "legacy.eu.oldsite.com",
204
- "shop.us.example.net",
205
- "alice.mail.example.com",
206
- "app1.cluster1.example.cloud",
207
- "genetics.research.corp.com",
208
- "cdn.v2.content.net",
209
- "corp.secureaccess.com",
210
- "redirect.oldsite.org",
211
- "support.bbb.ts.net",
212
- "support.ccc.ts.net",
213
- "archive.2022.oldsite.net",
214
- "legacy.2022.oldsite.net",
215
- "finance.vpn",
216
- "engineering.dev.example.com",
217
- "img02.static.cdn.example.com",
218
- "service.staging.example.org",
219
- "legacy.apac.oldsite.com",
220
- "shop.uk.example.net",
221
- "bob.mail.example.com",
222
- "app1.cluster2.example.cloud",
223
- "astrophysics.research.corp.com",
224
- "cdn.v3.content.net",
225
- "archive.2021.oldsite.net",
226
- "legacy.2021.oldsite.net",
227
- "quality.bbb.ts.net",
228
- "quality.ccc.ts.net"
229
- ]
230
-
231
- logger.warning('hello?')
232
- for test in tests:
233
- print(test)
234
- text = rewriter.rewrite(test)
235
- text
236
-
237
- tests
172
+
@@ -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
@@ -21,7 +21,6 @@ class SetupPaths(FromCallerMixin):
21
21
  """
22
22
 
23
23
  Use calling module path as default path, if not otherwise specified.
24
- :param org:
25
24
 
26
25
  """
27
26
  if not path:
@@ -30,8 +29,6 @@ class SetupPaths(FromCallerMixin):
30
29
  self.org_name = org
31
30
  self.repo = Path(path)
32
31
 
33
-
34
-
35
32
  @property
36
33
  def readme(self):
37
34
  return self.repo / 'README.md'
@@ -43,12 +40,14 @@ class SetupPaths(FromCallerMixin):
43
40
  @cached_property
44
41
  def path(self):
45
42
 
43
+ from fmtr.tools import setup
44
+
46
45
  if self.org:
47
46
  base = self.org
48
47
  else:
49
48
  base = self.repo
50
49
 
51
- directories = [base / dir for dir in self.find(base)]
50
+ directories = [base / dir for dir in setup.find_packages(base)]
52
51
 
53
52
  if len(directories) != 1:
54
53
  dirs_str = ', '.join([str(dir) for dir in directories])
@@ -74,11 +73,6 @@ class SetupPaths(FromCallerMixin):
74
73
  def name(self) -> str:
75
74
  return self.path.stem
76
75
 
77
- @property
78
- def find(self):
79
- from fmtr.tools import setup
80
- return setup.find_packages
81
-
82
76
 
83
77
  class Setup(FromCallerMixin):
84
78
  AUTHOR = 'Frontmatter'
@@ -209,7 +203,7 @@ class Setup(FromCallerMixin):
209
203
 
210
204
  @property
211
205
  def data(self):
212
- return dict(
206
+ data = dict(
213
207
  name=self.name,
214
208
  version=self.version,
215
209
  author=self.author,
@@ -225,6 +219,7 @@ class Setup(FromCallerMixin):
225
219
  install_requires=self.dependencies.install,
226
220
  extras_require=self.dependencies.extras,
227
221
  ) | self.kwargs
222
+ return data
228
223
 
229
224
  def setup(self):
230
225
 
@@ -233,6 +228,16 @@ class Setup(FromCallerMixin):
233
228
  return setup.setup_setuptools(**self.data)
234
229
 
235
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
+
236
241
 
237
242
 
238
243
  class Dependencies:
@@ -254,7 +259,7 @@ class Dependencies:
254
259
  for value in values:
255
260
  if value == key or value not in self.dependencies:
256
261
  # Add the value directly if it references itself or is not a dependency key.
257
- values_resolved.append(value)
262
+ values_resolved.append(str(value))
258
263
  else:
259
264
  # Recurse into nested dependencies.
260
265
  values_resolved += self.resolve_values(value)
@@ -0,0 +1 @@
1
+ 1.1.26
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fmtr.tools
3
- Version: 1.1.24
3
+ Version: 1.1.26
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: openpyxl; extra == "test"
13
- Requires-Dist: Unidecode; extra == "test"
14
- Requires-Dist: pyyaml; extra == "test"
15
- Requires-Dist: flet-video; extra == "test"
16
- Requires-Dist: dask[bag]; extra == "test"
17
- Requires-Dist: appdirs; extra == "test"
12
+ Requires-Dist: torchaudio; extra == "test"
18
13
  Requires-Dist: semver; extra == "test"
14
+ Requires-Dist: docker; extra == "test"
15
+ Requires-Dist: logfire; extra == "test"
16
+ Requires-Dist: ollama; extra == "test"
17
+ Requires-Dist: openpyxl; extra == "test"
18
+ Requires-Dist: flet[all]; extra == "test"
19
+ Requires-Dist: diskcache; extra == "test"
19
20
  Requires-Dist: pymupdf; extra == "test"
20
- Requires-Dist: bokeh; extra == "test"
21
- Requires-Dist: tabulate; extra == "test"
22
- Requires-Dist: uvicorn[standard]; extra == "test"
23
- Requires-Dist: transformers[sentencepiece]; extra == "test"
24
- Requires-Dist: google-auth-oauthlib; extra == "test"
25
- Requires-Dist: dnspython[doh]; extra == "test"
21
+ Requires-Dist: pydevd-pycharm; extra == "test"
22
+ Requires-Dist: filetype; extra == "test"
26
23
  Requires-Dist: sentence_transformers; extra == "test"
27
- Requires-Dist: pydantic-settings; extra == "test"
28
- Requires-Dist: deepmerge; extra == "test"
29
- Requires-Dist: pydantic; extra == "test"
30
- Requires-Dist: httpx_retries; extra == "test"
31
- Requires-Dist: logfire; extra == "test"
32
- Requires-Dist: google-auth-httplib2; extra == "test"
33
- Requires-Dist: torchvision; extra == "test"
34
- Requires-Dist: pymupdf4llm; extra == "test"
35
- Requires-Dist: torchaudio; extra == "test"
36
- Requires-Dist: contexttimer; extra == "test"
37
- Requires-Dist: distributed; extra == "test"
38
24
  Requires-Dist: peft; extra == "test"
39
- Requires-Dist: httpx; extra == "test"
40
- Requires-Dist: regex; extra == "test"
41
- Requires-Dist: yamlscript; extra == "test"
42
- Requires-Dist: filetype; extra == "test"
43
- Requires-Dist: pydevd-pycharm; extra == "test"
25
+ Requires-Dist: flet-video; extra == "test"
26
+ Requires-Dist: appdirs; extra == "test"
44
27
  Requires-Dist: huggingface_hub; extra == "test"
45
- Requires-Dist: sre_yield; extra == "test"
46
28
  Requires-Dist: flet-webview; extra == "test"
47
- Requires-Dist: json_repair; extra == "test"
29
+ Requires-Dist: httpx; extra == "test"
30
+ Requires-Dist: deepmerge; extra == "test"
48
31
  Requires-Dist: pytest-cov; extra == "test"
49
- Requires-Dist: fastapi; extra == "test"
50
- Requires-Dist: tinynetrc; extra == "test"
51
- Requires-Dist: google-api-python-client; extra == "test"
52
- Requires-Dist: ollama; extra == "test"
53
- Requires-Dist: tokenizers; extra == "test"
54
- Requires-Dist: diskcache; extra == "test"
55
- Requires-Dist: pydantic-ai[logfire,openai]; extra == "test"
32
+ Requires-Dist: dnspython[doh]; extra == "test"
33
+ Requires-Dist: regex; extra == "test"
34
+ Requires-Dist: openai; extra == "test"
56
35
  Requires-Dist: html2text; extra == "test"
36
+ Requires-Dist: yamlscript; extra == "test"
37
+ Requires-Dist: pydantic-settings; extra == "test"
38
+ Requires-Dist: dask[bag]; extra == "test"
39
+ Requires-Dist: tinynetrc; extra == "test"
57
40
  Requires-Dist: pandas; extra == "test"
58
- Requires-Dist: setuptools; extra == "test"
41
+ Requires-Dist: bokeh; extra == "test"
42
+ Requires-Dist: uvicorn[standard]; extra == "test"
43
+ Requires-Dist: torchvision; extra == "test"
44
+ Requires-Dist: logfire[fastapi]; extra == "test"
45
+ Requires-Dist: Unidecode; extra == "test"
46
+ Requires-Dist: tabulate; extra == "test"
47
+ Requires-Dist: distributed; extra == "test"
48
+ Requires-Dist: tokenizers; extra == "test"
59
49
  Requires-Dist: faker; extra == "test"
60
- Requires-Dist: openai; extra == "test"
50
+ Requires-Dist: contexttimer; extra == "test"
51
+ Requires-Dist: google-auth-oauthlib; extra == "test"
52
+ Requires-Dist: fastapi; extra == "test"
53
+ Requires-Dist: google-api-python-client; extra == "test"
61
54
  Requires-Dist: logfire[httpx]; extra == "test"
62
- Requires-Dist: docker; extra == "test"
63
- Requires-Dist: logfire[fastapi]; extra == "test"
64
- Requires-Dist: flet[all]; extra == "test"
55
+ Requires-Dist: json_repair; extra == "test"
56
+ Requires-Dist: pymupdf4llm; extra == "test"
57
+ Requires-Dist: sre_yield; extra == "test"
58
+ Requires-Dist: setuptools; extra == "test"
59
+ Requires-Dist: transformers[sentencepiece]; extra == "test"
60
+ Requires-Dist: pydantic-ai[logfire,openai]; extra == "test"
61
+ Requires-Dist: pydantic; extra == "test"
65
62
  Requires-Dist: google-auth; extra == "test"
63
+ Requires-Dist: pyyaml; extra == "test"
64
+ Requires-Dist: google-auth-httplib2; extra == "test"
65
+ Requires-Dist: httpx_retries; extra == "test"
66
66
  Provides-Extra: yaml
67
67
  Requires-Dist: yamlscript; extra == "yaml"
68
68
  Requires-Dist: pyyaml; extra == "yaml"
@@ -20,6 +20,7 @@ setup.py
20
20
  ./fmtr/tools/hash_tools.py
21
21
  ./fmtr/tools/hfh_tools.py
22
22
  ./fmtr/tools/html_tools.py
23
+ ./fmtr/tools/http_tools.py
23
24
  ./fmtr/tools/import_tools.py
24
25
  ./fmtr/tools/inspection_tools.py
25
26
  ./fmtr/tools/interface_tools.py
@@ -1 +0,0 @@
1
- 1.1.24
File without changes
File without changes
@@ -135,60 +135,60 @@ tabulate
135
135
  openpyxl
136
136
 
137
137
  [test]
138
- openpyxl
139
- Unidecode
140
- pyyaml
141
- flet-video
142
- dask[bag]
143
- appdirs
138
+ torchaudio
144
139
  semver
140
+ docker
141
+ logfire
142
+ ollama
143
+ openpyxl
144
+ flet[all]
145
+ diskcache
145
146
  pymupdf
146
- bokeh
147
- tabulate
148
- uvicorn[standard]
149
- transformers[sentencepiece]
150
- google-auth-oauthlib
151
- dnspython[doh]
147
+ pydevd-pycharm
148
+ filetype
152
149
  sentence_transformers
153
- pydantic-settings
154
- deepmerge
155
- pydantic
156
- httpx_retries
157
- logfire
158
- google-auth-httplib2
159
- torchvision
160
- pymupdf4llm
161
- torchaudio
162
- contexttimer
163
- distributed
164
150
  peft
165
- httpx
166
- regex
167
- yamlscript
168
- filetype
169
- pydevd-pycharm
151
+ flet-video
152
+ appdirs
170
153
  huggingface_hub
171
- sre_yield
172
154
  flet-webview
173
- json_repair
155
+ httpx
156
+ deepmerge
174
157
  pytest-cov
175
- fastapi
176
- tinynetrc
177
- google-api-python-client
178
- ollama
179
- tokenizers
180
- diskcache
181
- pydantic-ai[logfire,openai]
158
+ dnspython[doh]
159
+ regex
160
+ openai
182
161
  html2text
162
+ yamlscript
163
+ pydantic-settings
164
+ dask[bag]
165
+ tinynetrc
183
166
  pandas
184
- setuptools
167
+ bokeh
168
+ uvicorn[standard]
169
+ torchvision
170
+ logfire[fastapi]
171
+ Unidecode
172
+ tabulate
173
+ distributed
174
+ tokenizers
185
175
  faker
186
- openai
176
+ contexttimer
177
+ google-auth-oauthlib
178
+ fastapi
179
+ google-api-python-client
187
180
  logfire[httpx]
188
- docker
189
- logfire[fastapi]
190
- flet[all]
181
+ json_repair
182
+ pymupdf4llm
183
+ sre_yield
184
+ setuptools
185
+ transformers[sentencepiece]
186
+ pydantic-ai[logfire,openai]
187
+ pydantic
191
188
  google-auth
189
+ pyyaml
190
+ google-auth-httplib2
191
+ httpx_retries
192
192
 
193
193
  [tokenization]
194
194
  tokenizers
File without changes
File without changes