fmtr.tools 1.3.2__tar.gz → 1.3.3__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 (89) hide show
  1. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/PKG-INFO +42 -42
  2. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/dns_tools/proxy.py +5 -6
  3. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/pattern_tools.py +44 -44
  4. fmtr_tools-1.3.3/fmtr/tools/version +1 -0
  5. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr.tools.egg-info/PKG-INFO +42 -42
  6. fmtr_tools-1.3.2/fmtr/tools/version +0 -1
  7. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/LICENSE +0 -0
  8. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/README.md +0 -0
  9. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/__init__.py +0 -0
  10. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/ai_tools/__init__.py +0 -0
  11. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/ai_tools/agentic_tools.py +0 -0
  12. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/ai_tools/inference_tools.py +0 -0
  13. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/api_tools.py +0 -0
  14. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/async_tools.py +0 -0
  15. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/augmentation_tools.py +0 -0
  16. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/caching_tools.py +0 -0
  17. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/constants.py +0 -0
  18. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/data_modelling_tools.py +0 -0
  19. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/dataclass_tools.py +0 -0
  20. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/datatype_tools.py +0 -0
  21. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/debugging_tools.py +0 -0
  22. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/dns_tools/__init__.py +0 -0
  23. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/dns_tools/client.py +0 -0
  24. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/dns_tools/dm.py +0 -0
  25. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/dns_tools/server.py +0 -0
  26. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/docker_tools.py +0 -0
  27. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/entrypoints/__init__.py +0 -0
  28. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/entrypoints/cache_hfh.py +0 -0
  29. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/entrypoints/ep_test.py +0 -0
  30. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/entrypoints/remote_debug_test.py +0 -0
  31. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/entrypoints/shell_debug.py +0 -0
  32. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/environment_tools.py +0 -0
  33. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/function_tools.py +0 -0
  34. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/google_api_tools.py +0 -0
  35. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/hash_tools.py +0 -0
  36. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/hfh_tools.py +0 -0
  37. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/html_tools.py +0 -0
  38. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/http_tools.py +0 -0
  39. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/import_tools.py +0 -0
  40. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/inspection_tools.py +0 -0
  41. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/interface_tools.py +0 -0
  42. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/iterator_tools.py +0 -0
  43. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/json_fix_tools.py +0 -0
  44. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/json_tools.py +0 -0
  45. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/logging_tools.py +0 -0
  46. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/merging_tools.py +0 -0
  47. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/metric_tools.py +0 -0
  48. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/name_tools.py +0 -0
  49. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/netrc_tools.py +0 -0
  50. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/openai_tools.py +0 -0
  51. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/packaging_tools.py +0 -0
  52. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/parallel_tools.py +0 -0
  53. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/path_tools/__init__.py +0 -0
  54. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/path_tools/app_path_tools.py +0 -0
  55. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/path_tools/path_tools.py +0 -0
  56. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/path_tools/type_path_tools.py +0 -0
  57. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/pdf_tools.py +0 -0
  58. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/platform_tools.py +0 -0
  59. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/process_tools.py +0 -0
  60. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/profiling_tools.py +0 -0
  61. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/random_tools.py +0 -0
  62. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/semantic_tools.py +0 -0
  63. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/settings_tools.py +0 -0
  64. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/setup_tools/__init__.py +0 -0
  65. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/setup_tools/setup_tools.py +0 -0
  66. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/spaces_tools.py +0 -0
  67. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/string_tools.py +0 -0
  68. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/tabular_tools.py +0 -0
  69. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/tests/__init__.py +0 -0
  70. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/tests/conftest.py +0 -0
  71. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/tests/helpers.py +0 -0
  72. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/tests/test_datatype.py +0 -0
  73. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/tests/test_environment.py +0 -0
  74. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/tests/test_json.py +0 -0
  75. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/tests/test_path.py +0 -0
  76. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/tests/test_yaml.py +0 -0
  77. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/tokenization_tools.py +0 -0
  78. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/tools.py +0 -0
  79. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/unicode_tools.py +0 -0
  80. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/version_tools.py +0 -0
  81. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr/tools/yaml_tools.py +0 -0
  82. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr.tools.egg-info/SOURCES.txt +0 -0
  83. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr.tools.egg-info/dependency_links.txt +0 -0
  84. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr.tools.egg-info/entry_points.txt +0 -0
  85. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr.tools.egg-info/requires.txt +41 -41
  86. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/fmtr.tools.egg-info/top_level.txt +0 -0
  87. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/pyproject.toml +0 -0
  88. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/setup.cfg +0 -0
  89. {fmtr_tools-1.3.2 → fmtr_tools-1.3.3}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fmtr.tools
3
- Version: 1.3.2
3
+ Version: 1.3.3
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
@@ -130,60 +130,60 @@ Requires-Dist: logfire[httpx]; extra == "http"
130
130
  Provides-Extra: setup
131
131
  Requires-Dist: setuptools; extra == "setup"
132
132
  Provides-Extra: all
133
+ Requires-Dist: pymupdf4llm; extra == "all"
134
+ Requires-Dist: yamlscript; extra == "all"
135
+ Requires-Dist: pydantic-settings; extra == "all"
136
+ Requires-Dist: flet-webview; extra == "all"
137
+ Requires-Dist: json_repair; extra == "all"
138
+ Requires-Dist: openai; extra == "all"
133
139
  Requires-Dist: uvicorn[standard]; extra == "all"
134
- Requires-Dist: openpyxl; extra == "all"
135
- Requires-Dist: sentence_transformers; extra == "all"
136
- Requires-Dist: peft; extra == "all"
137
- Requires-Dist: httpx_retries; extra == "all"
138
- Requires-Dist: sre_yield; extra == "all"
139
- Requires-Dist: faker; extra == "all"
140
- Requires-Dist: ollama; extra == "all"
140
+ Requires-Dist: tinynetrc; extra == "all"
141
+ Requires-Dist: pydantic; extra == "all"
142
+ Requires-Dist: pydevd-pycharm; extra == "all"
143
+ Requires-Dist: tokenizers; extra == "all"
144
+ Requires-Dist: logfire[fastapi]; extra == "all"
145
+ Requires-Dist: tabulate; extra == "all"
146
+ Requires-Dist: google-auth; extra == "all"
147
+ Requires-Dist: google-auth-oauthlib; extra == "all"
141
148
  Requires-Dist: logfire; extra == "all"
142
- Requires-Dist: bokeh; extra == "all"
143
- Requires-Dist: setuptools; extra == "all"
144
- Requires-Dist: dask[bag]; extra == "all"
145
- Requires-Dist: diskcache; extra == "all"
146
149
  Requires-Dist: torchaudio; extra == "all"
147
- Requires-Dist: tokenizers; extra == "all"
148
- Requires-Dist: pydantic; extra == "all"
149
- Requires-Dist: pandas; extra == "all"
150
- Requires-Dist: flet-video; extra == "all"
151
- Requires-Dist: Unidecode; extra == "all"
152
- Requires-Dist: pydantic-settings; extra == "all"
153
- Requires-Dist: dnspython[doh]; extra == "all"
154
- Requires-Dist: logfire[httpx]; extra == "all"
155
- Requires-Dist: yamlscript; extra == "all"
150
+ Requires-Dist: setuptools; extra == "all"
151
+ Requires-Dist: pyyaml; extra == "all"
156
152
  Requires-Dist: fastapi; extra == "all"
157
- Requires-Dist: openai; extra == "all"
158
- Requires-Dist: deepmerge; extra == "all"
153
+ Requires-Dist: pandas; extra == "all"
159
154
  Requires-Dist: html2text; extra == "all"
155
+ Requires-Dist: google-api-python-client; extra == "all"
156
+ Requires-Dist: logfire[httpx]; extra == "all"
157
+ Requires-Dist: flet-video; extra == "all"
158
+ Requires-Dist: peft; extra == "all"
160
159
  Requires-Dist: pydantic-ai[logfire,openai]; extra == "all"
161
- Requires-Dist: contexttimer; extra == "all"
160
+ Requires-Dist: diskcache; extra == "all"
162
161
  Requires-Dist: flet[all]; extra == "all"
163
- Requires-Dist: logfire[fastapi]; extra == "all"
164
- Requires-Dist: regex; extra == "all"
165
- Requires-Dist: docker; extra == "all"
166
162
  Requires-Dist: filetype; extra == "all"
167
- Requires-Dist: google-auth-oauthlib; extra == "all"
168
- Requires-Dist: tabulate; extra == "all"
169
- Requires-Dist: pytest-cov; extra == "all"
170
- Requires-Dist: pyyaml; extra == "all"
163
+ Requires-Dist: semver; extra == "all"
171
164
  Requires-Dist: transformers[sentencepiece]; extra == "all"
172
- Requires-Dist: pymupdf; extra == "all"
173
- Requires-Dist: pydevd-pycharm; extra == "all"
165
+ Requires-Dist: deepmerge; extra == "all"
174
166
  Requires-Dist: torchvision; extra == "all"
175
- Requires-Dist: google-auth; extra == "all"
176
- Requires-Dist: flet-webview; extra == "all"
177
- Requires-Dist: huggingface_hub; extra == "all"
178
- Requires-Dist: httpx; extra == "all"
179
- Requires-Dist: semver; extra == "all"
180
- Requires-Dist: json_repair; extra == "all"
181
- Requires-Dist: tinynetrc; extra == "all"
167
+ Requires-Dist: ollama; extra == "all"
168
+ Requires-Dist: faker; extra == "all"
182
169
  Requires-Dist: google-auth-httplib2; extra == "all"
170
+ Requires-Dist: contexttimer; extra == "all"
171
+ Requires-Dist: pymupdf; extra == "all"
172
+ Requires-Dist: dask[bag]; extra == "all"
173
+ Requires-Dist: pytest-cov; extra == "all"
174
+ Requires-Dist: sre_yield; extra == "all"
175
+ Requires-Dist: regex; extra == "all"
176
+ Requires-Dist: dnspython[doh]; extra == "all"
183
177
  Requires-Dist: appdirs; extra == "all"
184
- Requires-Dist: pymupdf4llm; extra == "all"
178
+ Requires-Dist: bokeh; extra == "all"
179
+ Requires-Dist: httpx_retries; extra == "all"
180
+ Requires-Dist: Unidecode; extra == "all"
181
+ Requires-Dist: docker; extra == "all"
182
+ Requires-Dist: httpx; extra == "all"
183
+ Requires-Dist: huggingface_hub; extra == "all"
184
+ Requires-Dist: sentence_transformers; extra == "all"
185
185
  Requires-Dist: distributed; extra == "all"
186
- Requires-Dist: google-api-python-client; extra == "all"
186
+ Requires-Dist: openpyxl; extra == "all"
187
187
  Dynamic: author
188
188
  Dynamic: author-email
189
189
  Dynamic: description
@@ -41,7 +41,7 @@ class Proxy(server.Plain):
41
41
 
42
42
  request = exchange.request
43
43
 
44
- with logger.span(f'Handling request ID {request.message.id} for {request.name_text} from {exchange.client}...'):
44
+ with logger.span(f'Handling request {request.message.id=} {request.question=} {exchange.client=}...'):
45
45
 
46
46
  if not request.is_valid:
47
47
  raise ValueError(f'Only one question per request is supported. Got {len(request.question)} questions.')
@@ -51,7 +51,7 @@ class Proxy(server.Plain):
51
51
  if exchange.response.is_complete:
52
52
  return
53
53
 
54
- with logger.span(f'Making upstream request for {request.name_text}...'):
54
+ with logger.span(f'Making upstream request...'):
55
55
  self.client.resolve(exchange)
56
56
  if exchange.response.is_complete:
57
57
  return
@@ -61,8 +61,7 @@ class Proxy(server.Plain):
61
61
  if exchange.response.is_complete:
62
62
  return
63
63
 
64
- if exchange.response:
65
- return
66
-
67
64
  exchange.response.is_complete = True
68
- return
65
+
66
+ logger.info(f'Resolution complete {request.message.id=} {exchange.response.answer=}')
67
+ return
@@ -1,8 +1,9 @@
1
- import regex as re
2
1
  from dataclasses import dataclass, asdict
3
2
  from functools import cached_property
4
3
  from typing import List, Any
5
4
 
5
+ import regex as re
6
+
6
7
  from fmtr.tools.logging_tools import logger
7
8
  from fmtr.tools.string_tools import join
8
9
 
@@ -25,11 +26,6 @@ def alt(*patterns):
25
26
  pattern = MASK_GROUP.format(pattern=pattern)
26
27
  return pattern
27
28
 
28
-
29
-
30
-
31
-
32
-
33
29
  @dataclass
34
30
  class Key:
35
31
  RECORD_SEP = '␞'
@@ -93,17 +89,18 @@ class Item:
93
89
  Key-value pair
94
90
 
95
91
  """
96
- key: Key
97
- value: Key
92
+ source: Key
93
+ target: Key
98
94
 
99
95
  @dataclass
100
- class Mapper:
96
+ class Transformer:
101
97
  """
102
98
 
103
99
  Pattern-based, dictionary-like mapper.
104
- Compiles a single regex pattern from a list of rules, and determines which rule matched.
105
- It supports initialization from structured rule data, execution of a single lookup pass, and
106
- recursive lookups until a stable state is reached.
100
+ Compiles an complex set of rules into single regex pattern, and determines which rule matched.
101
+ Inputs are then transformed according to the matching rule.
102
+ Works like a pattern-based dictionary when is_recursive==False.
103
+ Works something like an FSA/transducer when is_recursive=True.
107
104
 
108
105
  """
109
106
  PREFIX_GROUP = '__'
@@ -112,21 +109,21 @@ class Mapper:
112
109
  is_recursive: bool = False
113
110
 
114
111
  @cached_property
115
- def pattern(self):
112
+ def pattern(self) -> str:
116
113
  """
117
114
 
118
- Provides a dynamically generated regex pattern based on the rules provided.
115
+ Dynamically generated regex pattern based on the rules provided.
119
116
 
120
117
  """
121
118
  patterns = [
122
- MASK_NAMED.format(key=f'{self.PREFIX_GROUP}{i}', pattern=item.key.pattern)
119
+ MASK_NAMED.format(key=f'{self.PREFIX_GROUP}{i}', pattern=item.source.pattern)
123
120
  for i, item in enumerate(self.items)
124
121
  ]
125
122
  pattern = alt(*patterns)
126
123
  return pattern
127
124
 
128
125
  @cached_property
129
- def rx(self):
126
+ def rx(self) -> re.Pattern:
130
127
  """
131
128
 
132
129
  Regex object.
@@ -134,24 +131,26 @@ class Mapper:
134
131
  """
135
132
  return re.compile(self.pattern)
136
133
 
137
- def get_default(self, key: Key):
134
+ def get_default(self, key: Key) -> Any:
138
135
  if self.is_recursive:
139
136
  return key
140
137
  else:
141
138
  return self.default
142
139
 
143
- def get(self, key: Key) -> Key:
140
+ def get(self, key: Key) -> Key | Any:
144
141
  """
145
142
 
146
143
  Use recursive or single lookup pass, depending on whether recursive lookups have been specified.
147
144
 
148
145
  """
149
146
  if self.is_recursive:
150
- return self.get_recursive(key)
147
+ with logger.span(f'Transforming recursively {key=}...'):
148
+ return self.get_recursive(key)
151
149
  else:
152
- return self.get_one(key)
150
+ with logger.span(f'Transforming linearly {key=}...'):
151
+ return self.get_one(key)
153
152
 
154
- def get_one(self, key: Key):
153
+ def get_one(self, key: Key) -> Key | Any:
155
154
  """
156
155
 
157
156
  Single lookup pass.
@@ -163,7 +162,7 @@ class Mapper:
163
162
 
164
163
  if not match:
165
164
  value = self.get_default(key)
166
- logger.debug(f'No match for {key=}.')
165
+ logger.debug(f'No match for {key=}. Returning {self.default=}')
167
166
  else:
168
167
 
169
168
  match_ids = {name: v for name, v in match.groupdict().items() if v}
@@ -179,19 +178,21 @@ class Mapper:
179
178
  rule_id = next(iter(rule_ids))
180
179
  rule = self.items[rule_id]
181
180
 
182
- if isinstance(rule.value, Key):
183
- value = rule.value.transform(match)
181
+ logger.debug(f'Matched using {rule_id=}: {rule.source=}')
182
+
183
+ if isinstance(rule.target, Key):
184
+ value = rule.target.transform(match)
184
185
  else:
185
- value = rule.value
186
+ value = rule.target
186
187
 
187
- logger.debug(f'Matched using {rule_id=}: {key=} → {value=}')
188
+ logger.debug(f'Transformed using {rule_id=}: {key=} → {value=}')
188
189
 
189
190
  return value
190
191
 
191
- def get_recursive(self, key: Key) -> Key:
192
+ def get_recursive(self, key: Key) -> Key | Any:
192
193
  """
193
194
 
194
- Lookup the provided text by continuously applying lookup rules until no changes are made
195
+ Lookup the provided key by continuously applying transforms until no changes are made
195
196
  or a circular loop is detected.
196
197
 
197
198
  """
@@ -201,29 +202,28 @@ class Mapper:
201
202
  def get_history_str():
202
203
  return join(history, sep=' → ')
203
204
 
204
- with logger.span(f'Matching {key=}...'):
205
- while True:
206
- if previous in history:
207
- history.append(previous)
208
- msg = f'Loop detected on node "{previous}": {get_history_str()}'
209
- raise RewriteCircularLoopError(msg)
210
-
205
+ while True:
206
+ if previous in history:
211
207
  history.append(previous)
208
+ msg = f'Loop detected on node "{previous}": {get_history_str()}'
209
+ raise RewriteCircularLoopError(msg)
212
210
 
213
- new = previous
211
+ history.append(previous)
212
+ new = previous
213
+ new = self.get_one(new)
214
+ if new == previous:
215
+ break
216
+ previous = new
214
217
 
215
- new = self.get_one(new)
216
-
217
- if new == previous:
218
- break
219
-
220
- previous = new
218
+ if not isinstance(new, Key):
219
+ history.append(previous)
220
+ break
221
221
 
222
222
  if len(history) == 1:
223
- history_str = 'No matching performed.'
223
+ history_str = 'No transforms performed.'
224
224
  else:
225
225
  history_str = get_history_str()
226
- logger.debug(f'Finished matching: {history_str}')
226
+ logger.debug(f'Finished transforming: {history_str}')
227
227
 
228
228
  return previous
229
229
 
@@ -0,0 +1 @@
1
+ 1.3.3
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fmtr.tools
3
- Version: 1.3.2
3
+ Version: 1.3.3
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
@@ -130,60 +130,60 @@ Requires-Dist: logfire[httpx]; extra == "http"
130
130
  Provides-Extra: setup
131
131
  Requires-Dist: setuptools; extra == "setup"
132
132
  Provides-Extra: all
133
+ Requires-Dist: pymupdf4llm; extra == "all"
134
+ Requires-Dist: yamlscript; extra == "all"
135
+ Requires-Dist: pydantic-settings; extra == "all"
136
+ Requires-Dist: flet-webview; extra == "all"
137
+ Requires-Dist: json_repair; extra == "all"
138
+ Requires-Dist: openai; extra == "all"
133
139
  Requires-Dist: uvicorn[standard]; extra == "all"
134
- Requires-Dist: openpyxl; extra == "all"
135
- Requires-Dist: sentence_transformers; extra == "all"
136
- Requires-Dist: peft; extra == "all"
137
- Requires-Dist: httpx_retries; extra == "all"
138
- Requires-Dist: sre_yield; extra == "all"
139
- Requires-Dist: faker; extra == "all"
140
- Requires-Dist: ollama; extra == "all"
140
+ Requires-Dist: tinynetrc; extra == "all"
141
+ Requires-Dist: pydantic; extra == "all"
142
+ Requires-Dist: pydevd-pycharm; extra == "all"
143
+ Requires-Dist: tokenizers; extra == "all"
144
+ Requires-Dist: logfire[fastapi]; extra == "all"
145
+ Requires-Dist: tabulate; extra == "all"
146
+ Requires-Dist: google-auth; extra == "all"
147
+ Requires-Dist: google-auth-oauthlib; extra == "all"
141
148
  Requires-Dist: logfire; extra == "all"
142
- Requires-Dist: bokeh; extra == "all"
143
- Requires-Dist: setuptools; extra == "all"
144
- Requires-Dist: dask[bag]; extra == "all"
145
- Requires-Dist: diskcache; extra == "all"
146
149
  Requires-Dist: torchaudio; extra == "all"
147
- Requires-Dist: tokenizers; extra == "all"
148
- Requires-Dist: pydantic; extra == "all"
149
- Requires-Dist: pandas; extra == "all"
150
- Requires-Dist: flet-video; extra == "all"
151
- Requires-Dist: Unidecode; extra == "all"
152
- Requires-Dist: pydantic-settings; extra == "all"
153
- Requires-Dist: dnspython[doh]; extra == "all"
154
- Requires-Dist: logfire[httpx]; extra == "all"
155
- Requires-Dist: yamlscript; extra == "all"
150
+ Requires-Dist: setuptools; extra == "all"
151
+ Requires-Dist: pyyaml; extra == "all"
156
152
  Requires-Dist: fastapi; extra == "all"
157
- Requires-Dist: openai; extra == "all"
158
- Requires-Dist: deepmerge; extra == "all"
153
+ Requires-Dist: pandas; extra == "all"
159
154
  Requires-Dist: html2text; extra == "all"
155
+ Requires-Dist: google-api-python-client; extra == "all"
156
+ Requires-Dist: logfire[httpx]; extra == "all"
157
+ Requires-Dist: flet-video; extra == "all"
158
+ Requires-Dist: peft; extra == "all"
160
159
  Requires-Dist: pydantic-ai[logfire,openai]; extra == "all"
161
- Requires-Dist: contexttimer; extra == "all"
160
+ Requires-Dist: diskcache; extra == "all"
162
161
  Requires-Dist: flet[all]; extra == "all"
163
- Requires-Dist: logfire[fastapi]; extra == "all"
164
- Requires-Dist: regex; extra == "all"
165
- Requires-Dist: docker; extra == "all"
166
162
  Requires-Dist: filetype; extra == "all"
167
- Requires-Dist: google-auth-oauthlib; extra == "all"
168
- Requires-Dist: tabulate; extra == "all"
169
- Requires-Dist: pytest-cov; extra == "all"
170
- Requires-Dist: pyyaml; extra == "all"
163
+ Requires-Dist: semver; extra == "all"
171
164
  Requires-Dist: transformers[sentencepiece]; extra == "all"
172
- Requires-Dist: pymupdf; extra == "all"
173
- Requires-Dist: pydevd-pycharm; extra == "all"
165
+ Requires-Dist: deepmerge; extra == "all"
174
166
  Requires-Dist: torchvision; extra == "all"
175
- Requires-Dist: google-auth; extra == "all"
176
- Requires-Dist: flet-webview; extra == "all"
177
- Requires-Dist: huggingface_hub; extra == "all"
178
- Requires-Dist: httpx; extra == "all"
179
- Requires-Dist: semver; extra == "all"
180
- Requires-Dist: json_repair; extra == "all"
181
- Requires-Dist: tinynetrc; extra == "all"
167
+ Requires-Dist: ollama; extra == "all"
168
+ Requires-Dist: faker; extra == "all"
182
169
  Requires-Dist: google-auth-httplib2; extra == "all"
170
+ Requires-Dist: contexttimer; extra == "all"
171
+ Requires-Dist: pymupdf; extra == "all"
172
+ Requires-Dist: dask[bag]; extra == "all"
173
+ Requires-Dist: pytest-cov; extra == "all"
174
+ Requires-Dist: sre_yield; extra == "all"
175
+ Requires-Dist: regex; extra == "all"
176
+ Requires-Dist: dnspython[doh]; extra == "all"
183
177
  Requires-Dist: appdirs; extra == "all"
184
- Requires-Dist: pymupdf4llm; extra == "all"
178
+ Requires-Dist: bokeh; extra == "all"
179
+ Requires-Dist: httpx_retries; extra == "all"
180
+ Requires-Dist: Unidecode; extra == "all"
181
+ Requires-Dist: docker; extra == "all"
182
+ Requires-Dist: httpx; extra == "all"
183
+ Requires-Dist: huggingface_hub; extra == "all"
184
+ Requires-Dist: sentence_transformers; extra == "all"
185
185
  Requires-Dist: distributed; extra == "all"
186
- Requires-Dist: google-api-python-client; extra == "all"
186
+ Requires-Dist: openpyxl; extra == "all"
187
187
  Dynamic: author
188
188
  Dynamic: author-email
189
189
  Dynamic: description
@@ -1 +0,0 @@
1
- 1.3.2
File without changes
File without changes
@@ -15,60 +15,60 @@ pydantic-ai[logfire,openai]
15
15
  ollama
16
16
 
17
17
  [all]
18
+ pymupdf4llm
19
+ yamlscript
20
+ pydantic-settings
21
+ flet-webview
22
+ json_repair
23
+ openai
18
24
  uvicorn[standard]
19
- openpyxl
20
- sentence_transformers
21
- peft
22
- httpx_retries
23
- sre_yield
24
- faker
25
- ollama
25
+ tinynetrc
26
+ pydantic
27
+ pydevd-pycharm
28
+ tokenizers
29
+ logfire[fastapi]
30
+ tabulate
31
+ google-auth
32
+ google-auth-oauthlib
26
33
  logfire
27
- bokeh
28
- setuptools
29
- dask[bag]
30
- diskcache
31
34
  torchaudio
32
- tokenizers
33
- pydantic
34
- pandas
35
- flet-video
36
- Unidecode
37
- pydantic-settings
38
- dnspython[doh]
39
- logfire[httpx]
40
- yamlscript
35
+ setuptools
36
+ pyyaml
41
37
  fastapi
42
- openai
43
- deepmerge
38
+ pandas
44
39
  html2text
40
+ google-api-python-client
41
+ logfire[httpx]
42
+ flet-video
43
+ peft
45
44
  pydantic-ai[logfire,openai]
46
- contexttimer
45
+ diskcache
47
46
  flet[all]
48
- logfire[fastapi]
49
- regex
50
- docker
51
47
  filetype
52
- google-auth-oauthlib
53
- tabulate
54
- pytest-cov
55
- pyyaml
48
+ semver
56
49
  transformers[sentencepiece]
57
- pymupdf
58
- pydevd-pycharm
50
+ deepmerge
59
51
  torchvision
60
- google-auth
61
- flet-webview
62
- huggingface_hub
63
- httpx
64
- semver
65
- json_repair
66
- tinynetrc
52
+ ollama
53
+ faker
67
54
  google-auth-httplib2
55
+ contexttimer
56
+ pymupdf
57
+ dask[bag]
58
+ pytest-cov
59
+ sre_yield
60
+ regex
61
+ dnspython[doh]
68
62
  appdirs
69
- pymupdf4llm
63
+ bokeh
64
+ httpx_retries
65
+ Unidecode
66
+ docker
67
+ httpx
68
+ huggingface_hub
69
+ sentence_transformers
70
70
  distributed
71
- google-api-python-client
71
+ openpyxl
72
72
 
73
73
  [api]
74
74
  fastapi
File without changes
File without changes
File without changes