fmtr.tools 1.1.25__py3-none-any.whl → 1.1.27__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
@@ -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
+
@@ -144,7 +144,7 @@ class Setup(FromCallerMixin):
144
144
  @property
145
145
  def name(self):
146
146
  if self.paths.is_namespace:
147
- return f'{self.paths.org}.{self.paths.name}'
147
+ return f'{self.paths.org_name}.{self.paths.name}'
148
148
  return self.paths.name
149
149
 
150
150
  @property
@@ -199,7 +199,7 @@ class Setup(FromCallerMixin):
199
199
 
200
200
  @property
201
201
  def url(self):
202
- return f'https://github.com/{self.paths.org}/{self.paths.name}'
202
+ return f'https://github.com/{self.org}/{self.paths.name}'
203
203
 
204
204
  @property
205
205
  def data(self):
fmtr/tools/version CHANGED
@@ -1 +1 @@
1
- 1.1.25
1
+ 1.1.27
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fmtr.tools
3
- Version: 1.1.25
3
+ Version: 1.1.27
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: google-auth; extra == "test"
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"
12
+ Requires-Dist: flet[all]; extra == "test"
13
+ Requires-Dist: distributed; extra == "test"
14
+ Requires-Dist: appdirs; extra == "test"
24
15
  Requires-Dist: pydantic-ai[logfire,openai]; extra == "test"
25
- Requires-Dist: uvicorn[standard]; extra == "test"
26
- Requires-Dist: regex; extra == "test"
27
16
  Requires-Dist: docker; extra == "test"
28
- Requires-Dist: logfire[httpx]; extra == "test"
29
- Requires-Dist: transformers[sentencepiece]; extra == "test"
30
17
  Requires-Dist: bokeh; extra == "test"
31
- Requires-Dist: tokenizers; extra == "test"
32
- Requires-Dist: httpx_retries; extra == "test"
33
- Requires-Dist: huggingface_hub; extra == "test"
34
- Requires-Dist: pydantic-settings; extra == "test"
35
- Requires-Dist: google-auth-oauthlib; extra == "test"
36
- Requires-Dist: google-api-python-client; extra == "test"
37
- Requires-Dist: pydantic; extra == "test"
18
+ Requires-Dist: openpyxl; extra == "test"
38
19
  Requires-Dist: tabulate; extra == "test"
39
- Requires-Dist: distributed; extra == "test"
40
- Requires-Dist: logfire; extra == "test"
41
- Requires-Dist: flet-webview; extra == "test"
42
- Requires-Dist: tinynetrc; extra == "test"
43
- Requires-Dist: deepmerge; extra == "test"
20
+ Requires-Dist: ollama; extra == "test"
21
+ Requires-Dist: pydevd-pycharm; extra == "test"
22
+ Requires-Dist: openai; extra == "test"
44
23
  Requires-Dist: pyyaml; extra == "test"
45
- Requires-Dist: contexttimer; extra == "test"
24
+ Requires-Dist: huggingface_hub; extra == "test"
46
25
  Requires-Dist: pytest-cov; extra == "test"
47
- Requires-Dist: filetype; 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"
55
- Requires-Dist: httpx; extra == "test"
26
+ Requires-Dist: pydantic-settings; extra == "test"
27
+ Requires-Dist: pymupdf; extra == "test"
28
+ Requires-Dist: sentence_transformers; extra == "test"
29
+ Requires-Dist: pymupdf4llm; extra == "test"
56
30
  Requires-Dist: yamlscript; extra == "test"
57
- Requires-Dist: pydevd-pycharm; extra == "test"
58
- Requires-Dist: google-auth-httplib2; extra == "test"
59
- Requires-Dist: appdirs; extra == "test"
31
+ Requires-Dist: html2text; extra == "test"
32
+ Requires-Dist: deepmerge; extra == "test"
33
+ Requires-Dist: regex; extra == "test"
34
+ Requires-Dist: fastapi; extra == "test"
35
+ Requires-Dist: httpx; extra == "test"
36
+ Requires-Dist: pandas; extra == "test"
37
+ Requires-Dist: dnspython[doh]; extra == "test"
38
+ Requires-Dist: diskcache; extra == "test"
39
+ Requires-Dist: torchvision; extra == "test"
40
+ Requires-Dist: google-auth; extra == "test"
41
+ Requires-Dist: dask[bag]; extra == "test"
42
+ Requires-Dist: uvicorn[standard]; extra == "test"
60
43
  Requires-Dist: Unidecode; extra == "test"
44
+ Requires-Dist: pydantic; extra == "test"
45
+ Requires-Dist: faker; extra == "test"
46
+ Requires-Dist: setuptools; extra == "test"
47
+ Requires-Dist: tokenizers; extra == "test"
61
48
  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"
49
+ Requires-Dist: google-auth-httplib2; extra == "test"
50
+ Requires-Dist: transformers[sentencepiece]; extra == "test"
51
+ Requires-Dist: contexttimer; extra == "test"
52
+ Requires-Dist: logfire[fastapi]; extra == "test"
53
+ Requires-Dist: httpx_retries; extra == "test"
54
+ Requires-Dist: sre_yield; extra == "test"
65
55
  Requires-Dist: peft; extra == "test"
56
+ Requires-Dist: torchaudio; extra == "test"
57
+ Requires-Dist: filetype; extra == "test"
58
+ Requires-Dist: semver; extra == "test"
59
+ Requires-Dist: tinynetrc; extra == "test"
60
+ Requires-Dist: json_repair; extra == "test"
61
+ Requires-Dist: google-api-python-client; extra == "test"
62
+ Requires-Dist: flet-webview; extra == "test"
63
+ Requires-Dist: logfire; extra == "test"
64
+ Requires-Dist: logfire[httpx]; extra == "test"
65
+ Requires-Dist: google-auth-oauthlib; 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=SMYBulUmtwW27eKblcTq1GCZjSOQDPiZBUCd2mRcTGc,5578
1
+ fmtr/tools/__init__.py,sha256=yXBnDJFPfv6qj4_KuLpMXoDZ92aiEzugLs0vcM31D5k,5770
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
@@ -17,6 +17,7 @@ fmtr/tools/google_api_tools.py,sha256=owWE0GlnJjmVbXus8ENxT2PH7Fnd3m_r-14xyR7lAn
17
17
  fmtr/tools/hash_tools.py,sha256=tr4HXpeT6rRrDk6TvMlRPUSrLRRaov96y128OI2tzsc,729
18
18
  fmtr/tools/hfh_tools.py,sha256=DCDIWuWlhtmIGCtp9cLcOTTEw_4yN_NocLX8w5NZsbk,2384
19
19
  fmtr/tools/html_tools.py,sha256=0nN8Nz5HtG9bXyApYfHSKEivLlxjsm3Gn6Mg2TK0brI,394
20
+ fmtr/tools/http_tools.py,sha256=RVwGrBNMyjfbpgAPCSnxEkXfSzXXWARb3ayq981ONQE,464
20
21
  fmtr/tools/import_tools.py,sha256=XJmiWLukRncJAcaGReDn4jIz1_IpVBjfYCQHH1hIg7c,588
21
22
  fmtr/tools/inspection_tools.py,sha256=tLTRvzy9XVomQPi0dfnF_cgwc7KiDVZAr7gPTk4S_bQ,278
22
23
  fmtr/tools/interface_tools.py,sha256=JVYUV7wuMr24BORuUtNaBlTeBFt8VDGJ3HPRajd7Y_4,1341
@@ -31,7 +32,7 @@ fmtr/tools/netrc_tools.py,sha256=PpNpz_mWlQi6VHGromKwFfTyLpHUXsd4LY6-OKLCbeI,376
31
32
  fmtr/tools/openai_tools.py,sha256=6SUgejgzUzmlKKct2_ePXntvMegu3FJgfk9x7aqtqYc,742
32
33
  fmtr/tools/packaging_tools.py,sha256=FlgOTnDRHZWQL2iR-wucTsyGEHRE-MlddKL30MPmUqE,253
33
34
  fmtr/tools/parallel_tools.py,sha256=QEb_gN1StkxsqYaH4HSjiJX8Y3gpb2uKNsOzG4uFpaM,3071
34
- fmtr/tools/pattern_tools.py,sha256=of-a26bRf-DgbzI0xJWSNkAONZozYylE_9E1hmpp6mw,6793
35
+ fmtr/tools/pattern_tools.py,sha256=Tv67jftyfjp04QlRMD4pwS1IV_SIXCtDTD_uIlMZiSM,4229
35
36
  fmtr/tools/pdf_tools.py,sha256=xvv9B84uAF81rFJRnXhSsxYuP42vY9ZdPVFrSMVe8G8,4069
36
37
  fmtr/tools/platform_tools.py,sha256=7p69CmAHe_sF68Fx9uVhns1k5EewTHTWgUYzkl6ZQKA,308
37
38
  fmtr/tools/process_tools.py,sha256=Ysh5Dk2QFBhXQerArjKdt7xZd3JrN5Ho02AaOjH0Nnw,1425
@@ -45,7 +46,7 @@ fmtr/tools/tabular_tools.py,sha256=tpIpZzYku1HcJrHZJL6BC39LmN3WUWVhFbK2N7nDVmE,1
45
46
  fmtr/tools/tokenization_tools.py,sha256=me-IBzSLyNYejLybwjO9CNB6Mj2NYfKPaOVThXyaGNg,4268
46
47
  fmtr/tools/tools.py,sha256=CAsApa1YwVdNE6H66Vjivs_mXYvOas3rh7fPELAnTpk,795
47
48
  fmtr/tools/unicode_tools.py,sha256=yS_9wpu8ogNoiIL7s1G_8bETFFO_YQlo4LNPv1NLDeY,52
48
- fmtr/tools/version,sha256=MXtcMHPDkm9DBt901I2qwVZouqD5wzakzj7n9M5gDCI,6
49
+ fmtr/tools/version,sha256=3SA3oLPh-vp_vGTc_mzfNjE9OmkTp3EXKAk4qaV1MYo,6
49
50
  fmtr/tools/version_tools.py,sha256=yNs_CGqWpqE4jbK9wsPIi14peJVXYbhIcMqHAFOw3yE,1480
50
51
  fmtr/tools/yaml_tools.py,sha256=9kuYChqJelWQIjGlSnK4iDdOWWH06P0gp9jIcRrC3UI,1903
51
52
  fmtr/tools/ai_tools/__init__.py,sha256=JZrLuOFNV1A3wvJgonxOgz_4WS-7MfCuowGWA5uYCjs,372
@@ -56,7 +57,7 @@ fmtr/tools/path_tools/app_path_tools.py,sha256=JrJvtTDd_gkCKcZtBCDTMktsM77PZwGV_
56
57
  fmtr/tools/path_tools/path_tools.py,sha256=8WBzNctpds5tVT1-FcizAORrBCGlkUbPcfOel-Js7ps,7878
57
58
  fmtr/tools/path_tools/type_path_tools.py,sha256=Zgs-ek-GXRKDIlVDGdg3muB0PIxTg2ba0NeHw6y8FWQ,40
58
59
  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
+ fmtr/tools/setup_tools/setup_tools.py,sha256=hvlYfm9W3tXnM0UhFuOZO6EaIgadj9EaFtMQLlY1kM8,7802
60
61
  fmtr/tools/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
61
62
  fmtr/tools/tests/conftest.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
62
63
  fmtr/tools/tests/helpers.py,sha256=N5sf9YoZV93a7tf_UxpLeyQ9vp6Ec0teNIimFDvc054,1091
@@ -65,9 +66,9 @@ fmtr/tools/tests/test_environment.py,sha256=iHaiMQfECYZPkPKwfuIZV9uHuWe3aE-p_dN_
65
66
  fmtr/tools/tests/test_json.py,sha256=IeSP4ziPvRcmS8kq7k9tHonC9rN5YYq9GSNT2ul6Msk,287
66
67
  fmtr/tools/tests/test_path.py,sha256=AkZQa6_8BQ-VaCyL_J-iKmdf2ZaM-xFYR37Kun3k4_g,2188
67
68
  fmtr/tools/tests/test_yaml.py,sha256=jc0TwwKu9eC0LvFGNMERdgBue591xwLxYXFbtsRwXVM,287
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,,
69
+ fmtr_tools-1.1.27.dist-info/licenses/LICENSE,sha256=FW9aa6vVN5IjRQWLT43hs4_koYSmpcbIovlKeAJ0_cI,10757
70
+ fmtr_tools-1.1.27.dist-info/METADATA,sha256=_irRCFwJjtpxuZdhIt7TscAz5ntKMSwjyT0axSRjGmk,15735
71
+ fmtr_tools-1.1.27.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
72
+ fmtr_tools-1.1.27.dist-info/entry_points.txt,sha256=e-eOW1Ml13tbxHC6Er1MnVOEDePeWw7DKwlE-l-gCY0,205
73
+ fmtr_tools-1.1.27.dist-info/top_level.txt,sha256=LXem9xCgNOD72tE2gRKESdiQTL902mfFkwWb6-dlwEE,5
74
+ fmtr_tools-1.1.27.dist-info/RECORD,,