fmtr.tools 1.3.12__tar.gz → 1.3.14__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 (91) hide show
  1. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/PKG-INFO +46 -46
  2. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/dns_tools/client.py +12 -7
  3. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/dns_tools/dm.py +28 -3
  4. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/dns_tools/server.py +39 -6
  5. fmtr_tools-1.3.14/fmtr/tools/version +1 -0
  6. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr.tools.egg-info/PKG-INFO +46 -46
  7. fmtr_tools-1.3.12/fmtr/tools/version +0 -1
  8. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/LICENSE +0 -0
  9. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/README.md +0 -0
  10. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/__init__.py +0 -0
  11. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/ai_tools/__init__.py +0 -0
  12. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/ai_tools/agentic_tools.py +0 -0
  13. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/ai_tools/inference_tools.py +0 -0
  14. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/api_tools.py +0 -0
  15. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/async_tools.py +0 -0
  16. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/augmentation_tools.py +0 -0
  17. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/caching_tools.py +0 -0
  18. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/constants.py +0 -0
  19. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/data_modelling_tools.py +0 -0
  20. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/dataclass_tools.py +0 -0
  21. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/datatype_tools.py +0 -0
  22. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/debugging_tools.py +0 -0
  23. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/dns_tools/__init__.py +0 -0
  24. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/dns_tools/proxy.py +0 -0
  25. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/docker_tools.py +0 -0
  26. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/entrypoints/__init__.py +0 -0
  27. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/entrypoints/cache_hfh.py +0 -0
  28. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/entrypoints/ep_test.py +0 -0
  29. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/entrypoints/install_yamlscript.py +0 -0
  30. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/entrypoints/remote_debug_test.py +0 -0
  31. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/entrypoints/shell_debug.py +0 -0
  32. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/environment_tools.py +0 -0
  33. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/function_tools.py +0 -0
  34. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/google_api_tools.py +0 -0
  35. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/hash_tools.py +0 -0
  36. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/hfh_tools.py +0 -0
  37. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/html_tools.py +0 -0
  38. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/http_tools.py +0 -0
  39. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/import_tools.py +0 -0
  40. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/inspection_tools.py +0 -0
  41. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/interface_tools.py +0 -0
  42. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/iterator_tools.py +0 -0
  43. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/json_fix_tools.py +0 -0
  44. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/json_tools.py +0 -0
  45. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/logging_tools.py +0 -0
  46. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/merging_tools.py +0 -0
  47. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/metric_tools.py +0 -0
  48. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/name_tools.py +0 -0
  49. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/netrc_tools.py +0 -0
  50. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/openai_tools.py +0 -0
  51. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/packaging_tools.py +0 -0
  52. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/parallel_tools.py +0 -0
  53. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/path_tools/__init__.py +0 -0
  54. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/path_tools/app_path_tools.py +0 -0
  55. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/path_tools/path_tools.py +0 -0
  56. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/path_tools/type_path_tools.py +0 -0
  57. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/pattern_tools.py +0 -0
  58. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/pdf_tools.py +0 -0
  59. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/platform_tools.py +0 -0
  60. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/process_tools.py +0 -0
  61. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/profiling_tools.py +0 -0
  62. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/random_tools.py +0 -0
  63. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/semantic_tools.py +0 -0
  64. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/settings_tools.py +0 -0
  65. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/setup_tools/__init__.py +0 -0
  66. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/setup_tools/setup_tools.py +0 -0
  67. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/spaces_tools.py +0 -0
  68. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/string_tools.py +0 -0
  69. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/tabular_tools.py +0 -0
  70. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/tests/__init__.py +0 -0
  71. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/tests/conftest.py +0 -0
  72. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/tests/helpers.py +0 -0
  73. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/tests/test_datatype.py +0 -0
  74. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/tests/test_environment.py +0 -0
  75. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/tests/test_json.py +0 -0
  76. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/tests/test_path.py +0 -0
  77. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/tests/test_yaml.py +0 -0
  78. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/tokenization_tools.py +0 -0
  79. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/tools.py +0 -0
  80. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/unicode_tools.py +0 -0
  81. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/version_tools/__init__.py +0 -0
  82. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/version_tools/version_tools.py +0 -0
  83. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr/tools/yaml_tools.py +0 -0
  84. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr.tools.egg-info/SOURCES.txt +0 -0
  85. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr.tools.egg-info/dependency_links.txt +0 -0
  86. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr.tools.egg-info/entry_points.txt +0 -0
  87. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr.tools.egg-info/requires.txt +45 -45
  88. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/fmtr.tools.egg-info/top_level.txt +0 -0
  89. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/pyproject.toml +0 -0
  90. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/setup.cfg +0 -0
  91. {fmtr_tools-1.3.12 → fmtr_tools-1.3.14}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fmtr.tools
3
- Version: 1.3.12
3
+ Version: 1.3.14
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
@@ -126,61 +126,61 @@ Requires-Dist: logfire[httpx]; extra == "http"
126
126
  Provides-Extra: setup
127
127
  Requires-Dist: setuptools; extra == "setup"
128
128
  Provides-Extra: all
129
- Requires-Dist: fastapi; extra == "all"
130
- Requires-Dist: contexttimer; extra == "all"
131
- Requires-Dist: tinynetrc; extra == "all"
132
- Requires-Dist: ollama; extra == "all"
133
- Requires-Dist: uvicorn[standard]; extra == "all"
134
- Requires-Dist: pymupdf; extra == "all"
135
- Requires-Dist: pymupdf4llm; extra == "all"
136
- Requires-Dist: logfire[fastapi]; extra == "all"
129
+ Requires-Dist: deepmerge; extra == "all"
137
130
  Requires-Dist: google-auth-httplib2; extra == "all"
138
- Requires-Dist: Unidecode; extra == "all"
139
- Requires-Dist: faker; extra == "all"
140
- Requires-Dist: pydantic-ai[logfire,openai]; extra == "all"
131
+ Requires-Dist: fastapi; extra == "all"
132
+ Requires-Dist: bokeh; extra == "all"
133
+ Requires-Dist: pydantic; extra == "all"
141
134
  Requires-Dist: tabulate; extra == "all"
142
- Requires-Dist: pyyaml; extra == "all"
143
- Requires-Dist: html2text; extra == "all"
144
- Requires-Dist: json_repair; extra == "all"
145
- Requires-Dist: flet[all]; extra == "all"
146
- Requires-Dist: httpx; extra == "all"
135
+ Requires-Dist: dask[bag]; extra == "all"
136
+ Requires-Dist: openpyxl; extra == "all"
147
137
  Requires-Dist: filetype; extra == "all"
148
- Requires-Dist: pydantic; extra == "all"
138
+ Requires-Dist: pymupdf; extra == "all"
139
+ Requires-Dist: docker; extra == "all"
140
+ Requires-Dist: flet-webview; extra == "all"
141
+ Requires-Dist: dnspython[doh]; extra == "all"
149
142
  Requires-Dist: logfire; extra == "all"
150
- Requires-Dist: torchaudio; extra == "all"
151
- Requires-Dist: flet-video; extra == "all"
152
- Requires-Dist: pydevd-pycharm~=251.25410.159; extra == "all"
153
- Requires-Dist: distributed; extra == "all"
154
- Requires-Dist: pytest-cov; extra == "all"
155
- Requires-Dist: sentence_transformers; extra == "all"
156
- Requires-Dist: yamlscript; extra == "all"
157
- Requires-Dist: appdirs; extra == "all"
143
+ Requires-Dist: contexttimer; extra == "all"
144
+ Requires-Dist: torchvision; extra == "all"
145
+ Requires-Dist: huggingface_hub; extra == "all"
158
146
  Requires-Dist: transformers[sentencepiece]; extra == "all"
159
- Requires-Dist: dnspython[doh]; extra == "all"
160
- Requires-Dist: openpyxl; extra == "all"
161
- Requires-Dist: openai; extra == "all"
162
- Requires-Dist: google-auth-oauthlib; extra == "all"
163
- Requires-Dist: sre_yield; extra == "all"
147
+ Requires-Dist: cachetools; extra == "all"
148
+ Requires-Dist: httpx; extra == "all"
164
149
  Requires-Dist: semver; extra == "all"
165
- Requires-Dist: deepmerge; extra == "all"
166
- Requires-Dist: pydantic-settings; extra == "all"
167
- Requires-Dist: tokenizers; extra == "all"
168
- Requires-Dist: peft; extra == "all"
169
- Requires-Dist: flet-webview; extra == "all"
150
+ Requires-Dist: sre_yield; extra == "all"
151
+ Requires-Dist: html2text; extra == "all"
152
+ Requires-Dist: pyyaml; extra == "all"
170
153
  Requires-Dist: google-auth; extra == "all"
171
- Requires-Dist: dask[bag]; extra == "all"
172
- Requires-Dist: docker; extra == "all"
173
- Requires-Dist: bokeh; extra == "all"
154
+ Requires-Dist: regex; extra == "all"
155
+ Requires-Dist: httpx_retries; extra == "all"
156
+ Requires-Dist: tokenizers; extra == "all"
157
+ Requires-Dist: sentence_transformers; extra == "all"
158
+ Requires-Dist: flet-video; extra == "all"
159
+ Requires-Dist: pymupdf4llm; extra == "all"
160
+ Requires-Dist: google-auth-oauthlib; extra == "all"
161
+ Requires-Dist: pytest-cov; extra == "all"
162
+ Requires-Dist: logfire[httpx]; extra == "all"
163
+ Requires-Dist: ollama; extra == "all"
164
+ Requires-Dist: faker; extra == "all"
165
+ Requires-Dist: torchaudio; extra == "all"
174
166
  Requires-Dist: pandas; extra == "all"
175
- Requires-Dist: huggingface_hub; extra == "all"
176
167
  Requires-Dist: google-api-python-client; extra == "all"
177
- Requires-Dist: logfire[httpx]; extra == "all"
178
- Requires-Dist: torchvision; extra == "all"
179
- Requires-Dist: httpx_retries; extra == "all"
180
- Requires-Dist: cachetools; extra == "all"
181
- Requires-Dist: diskcache; extra == "all"
182
- Requires-Dist: regex; extra == "all"
168
+ Requires-Dist: uvicorn[standard]; extra == "all"
169
+ Requires-Dist: appdirs; extra == "all"
170
+ Requires-Dist: flet[all]; extra == "all"
183
171
  Requires-Dist: setuptools; extra == "all"
172
+ Requires-Dist: logfire[fastapi]; extra == "all"
173
+ Requires-Dist: yamlscript; extra == "all"
174
+ Requires-Dist: pydevd-pycharm~=251.25410.159; extra == "all"
175
+ Requires-Dist: tinynetrc; extra == "all"
176
+ Requires-Dist: pydantic-ai[logfire,openai]; extra == "all"
177
+ Requires-Dist: Unidecode; extra == "all"
178
+ Requires-Dist: pydantic-settings; extra == "all"
179
+ Requires-Dist: json_repair; extra == "all"
180
+ Requires-Dist: peft; extra == "all"
181
+ Requires-Dist: distributed; extra == "all"
182
+ Requires-Dist: openai; extra == "all"
183
+ Requires-Dist: diskcache; extra == "all"
184
184
  Dynamic: author
185
185
  Dynamic: author-email
186
186
  Dynamic: description
@@ -1,8 +1,7 @@
1
- from dataclasses import dataclass
2
- from functools import cached_property
3
-
4
1
  import dns as dnspython
2
+ from dataclasses import dataclass
5
3
  from dns import query
4
+ from functools import cached_property
6
5
  from httpx_retries import Retry, RetryTransport
7
6
 
8
7
  from fmtr.tools import http_tools as http
@@ -82,8 +81,14 @@ class HTTP:
82
81
 
83
82
  headers = self.HEADERS | dict(Host=self.host)
84
83
  url = self.url.format(host=self.ip)
85
- response_doh = self.CLIENT.post(url, headers=headers, content=exchange.query_last.to_wire())
86
- response_doh.raise_for_status()
87
- response = Response.from_http(response_doh)
88
84
 
89
- exchange.response.message.answer += response.message.answer
85
+ try:
86
+ response_doh = self.CLIENT.post(url, headers=headers, content=exchange.query_last.to_wire())
87
+ response_doh.raise_for_status()
88
+ response = Response.from_http(response_doh)
89
+ exchange.response.message.answer += response.message.answer
90
+
91
+ except Exception as exception:
92
+ exchange.response.message.set_rcode(dnspython.rcode.SERVFAIL)
93
+ exchange.response.is_complete = True
94
+ logger.exception(exception)
@@ -1,6 +1,8 @@
1
1
  import dns
2
2
  import httpx
3
3
  from dataclasses import dataclass
4
+ from dns import rcode as dnsrcode
5
+ from dns import reversename
4
6
  from dns.message import Message, QueryMessage
5
7
  from dns.rrset import RRset
6
8
  from functools import cached_property
@@ -36,6 +38,7 @@ class Response(BaseDNSData):
36
38
 
37
39
  http: Optional[httpx.Response] = None
38
40
  is_complete: bool = False
41
+ blocked_by: Optional[str] = None
39
42
 
40
43
  @classmethod
41
44
  def from_http(cls, response: httpx.Response) -> Self:
@@ -58,6 +61,14 @@ class Response(BaseDNSData):
58
61
  return None
59
62
  return self.message.answer[-1]
60
63
 
64
+ @property
65
+ def rcode(self) -> dnsrcode.Rcode:
66
+ return self.message.rcode()
67
+
68
+ @property
69
+ def rcode_text(self) -> str:
70
+ return dnsrcode.to_text(self.rcode)
71
+
61
72
  def __str__(self):
62
73
  """
63
74
 
@@ -133,14 +144,16 @@ class Exchange:
133
144
 
134
145
  request: Request
135
146
  response: Optional[Response] = None
147
+ is_internal: bool = False
148
+ client_name: Optional[str] = None
149
+
136
150
 
137
151
 
138
152
  @classmethod
139
- def from_wire(cls, wire: bytes, ip: str, port: int) -> Self:
153
+ def from_wire(cls, wire: bytes, **kwargs) -> Self:
140
154
  request = Request(wire)
141
155
  response = Response.from_message(request.get_response_template())
142
-
143
- return cls(request=request, response=response, ip=ip, port=port)
156
+ return cls(request=request, response=response, **kwargs)
144
157
 
145
158
  @cached_property
146
159
  def client(self):
@@ -193,3 +206,15 @@ class Exchange:
193
206
  """
194
207
  data = tuple(self.request.question.to_text().split())
195
208
  return data
209
+
210
+ @cached_property
211
+ def reverse(self) -> Self:
212
+ """
213
+
214
+ Create an Exchange for a reverse lookup of this Exchange's client IP.
215
+
216
+ """
217
+ name = reversename.from_address(self.ip)
218
+ query = dns.message.make_query(name, dns.rdatatype.PTR)
219
+ exchange = self.__class__.from_wire(query.to_wire(), ip=self.ip, port=self.port, is_internal=True)
220
+ return exchange
@@ -68,19 +68,51 @@ class Plain:
68
68
  exchange.response.message.id = exchange.request.message.id
69
69
  exchange.response.is_complete = True
70
70
 
71
- def handle(self, exchange: Exchange):
71
+ def get_span(self, exchange: Exchange):
72
72
  """
73
73
 
74
- Check validity of request, presence in cache and resolve.
74
+ Get handling span
75
75
 
76
76
  """
77
77
  request = exchange.request
78
+ span = logger.span(
79
+ f'Handling request {exchange.client_name=} {request.message.id=} {request.type_text} {request.name_text} {request.question=}...'
80
+ )
81
+ return span
82
+
83
+ def log_response(self, exchange: Exchange):
84
+ """
78
85
 
79
- if not request.is_valid:
80
- raise ValueError(f'Only one question per request is supported. Got {len(request.question)} questions.')
86
+ Log when resolution complete
81
87
 
82
- with logger.span(f'Handling request {request.message.id=} {request.type_text} {request.name_text} {request.question=} {exchange.ip=} {exchange.port=}...'):
88
+ """
89
+ request = exchange.request
90
+ response = exchange.response
83
91
 
92
+ logger.info(
93
+ f'Resolution complete {exchange.client_name=} {request.message.id=} {request.type_text} {request.name_text} {request.question=} {response.is_complete=} {response.rcode=} {response.rcode_text=} {response.answer=} {response.blocked_by=}...'
94
+ )
95
+
96
+
97
+
98
+ def handle(self, exchange: Exchange):
99
+ """
100
+
101
+ Check validity of request, reverse lookup client address, check presence in cache and resolve.
102
+
103
+ """
104
+
105
+ if not exchange.request.is_valid:
106
+ raise ValueError(f'Only one question per request is supported. Got {len(exchange.request.question)} questions.')
107
+
108
+ if not exchange.is_internal:
109
+ self.handle(exchange.reverse)
110
+ client_name = exchange.reverse.question_last.name.to_text()
111
+ if not exchange.reverse.response.answer:
112
+ logger.warning(f'Client name could not be resolved {client_name=}.')
113
+ exchange.client_name = client_name
114
+
115
+ with self.get_span(exchange):
84
116
  with logger.span(f'Checking cache...'):
85
117
  self.check_cache(exchange)
86
118
 
@@ -89,5 +121,6 @@ class Plain:
89
121
  exchange.response.is_complete = True
90
122
 
91
123
  self.cache[exchange.key] = exchange.response
92
- logger.info(f'Resolution complete {request.message.id=} {exchange.response.answer=}')
124
+ self.log_response(exchange)
125
+
93
126
  return exchange
@@ -0,0 +1 @@
1
+ 1.3.14
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fmtr.tools
3
- Version: 1.3.12
3
+ Version: 1.3.14
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
@@ -126,61 +126,61 @@ Requires-Dist: logfire[httpx]; extra == "http"
126
126
  Provides-Extra: setup
127
127
  Requires-Dist: setuptools; extra == "setup"
128
128
  Provides-Extra: all
129
- Requires-Dist: fastapi; extra == "all"
130
- Requires-Dist: contexttimer; extra == "all"
131
- Requires-Dist: tinynetrc; extra == "all"
132
- Requires-Dist: ollama; extra == "all"
133
- Requires-Dist: uvicorn[standard]; extra == "all"
134
- Requires-Dist: pymupdf; extra == "all"
135
- Requires-Dist: pymupdf4llm; extra == "all"
136
- Requires-Dist: logfire[fastapi]; extra == "all"
129
+ Requires-Dist: deepmerge; extra == "all"
137
130
  Requires-Dist: google-auth-httplib2; extra == "all"
138
- Requires-Dist: Unidecode; extra == "all"
139
- Requires-Dist: faker; extra == "all"
140
- Requires-Dist: pydantic-ai[logfire,openai]; extra == "all"
131
+ Requires-Dist: fastapi; extra == "all"
132
+ Requires-Dist: bokeh; extra == "all"
133
+ Requires-Dist: pydantic; extra == "all"
141
134
  Requires-Dist: tabulate; extra == "all"
142
- Requires-Dist: pyyaml; extra == "all"
143
- Requires-Dist: html2text; extra == "all"
144
- Requires-Dist: json_repair; extra == "all"
145
- Requires-Dist: flet[all]; extra == "all"
146
- Requires-Dist: httpx; extra == "all"
135
+ Requires-Dist: dask[bag]; extra == "all"
136
+ Requires-Dist: openpyxl; extra == "all"
147
137
  Requires-Dist: filetype; extra == "all"
148
- Requires-Dist: pydantic; extra == "all"
138
+ Requires-Dist: pymupdf; extra == "all"
139
+ Requires-Dist: docker; extra == "all"
140
+ Requires-Dist: flet-webview; extra == "all"
141
+ Requires-Dist: dnspython[doh]; extra == "all"
149
142
  Requires-Dist: logfire; extra == "all"
150
- Requires-Dist: torchaudio; extra == "all"
151
- Requires-Dist: flet-video; extra == "all"
152
- Requires-Dist: pydevd-pycharm~=251.25410.159; extra == "all"
153
- Requires-Dist: distributed; extra == "all"
154
- Requires-Dist: pytest-cov; extra == "all"
155
- Requires-Dist: sentence_transformers; extra == "all"
156
- Requires-Dist: yamlscript; extra == "all"
157
- Requires-Dist: appdirs; extra == "all"
143
+ Requires-Dist: contexttimer; extra == "all"
144
+ Requires-Dist: torchvision; extra == "all"
145
+ Requires-Dist: huggingface_hub; extra == "all"
158
146
  Requires-Dist: transformers[sentencepiece]; extra == "all"
159
- Requires-Dist: dnspython[doh]; extra == "all"
160
- Requires-Dist: openpyxl; extra == "all"
161
- Requires-Dist: openai; extra == "all"
162
- Requires-Dist: google-auth-oauthlib; extra == "all"
163
- Requires-Dist: sre_yield; extra == "all"
147
+ Requires-Dist: cachetools; extra == "all"
148
+ Requires-Dist: httpx; extra == "all"
164
149
  Requires-Dist: semver; extra == "all"
165
- Requires-Dist: deepmerge; extra == "all"
166
- Requires-Dist: pydantic-settings; extra == "all"
167
- Requires-Dist: tokenizers; extra == "all"
168
- Requires-Dist: peft; extra == "all"
169
- Requires-Dist: flet-webview; extra == "all"
150
+ Requires-Dist: sre_yield; extra == "all"
151
+ Requires-Dist: html2text; extra == "all"
152
+ Requires-Dist: pyyaml; extra == "all"
170
153
  Requires-Dist: google-auth; extra == "all"
171
- Requires-Dist: dask[bag]; extra == "all"
172
- Requires-Dist: docker; extra == "all"
173
- Requires-Dist: bokeh; extra == "all"
154
+ Requires-Dist: regex; extra == "all"
155
+ Requires-Dist: httpx_retries; extra == "all"
156
+ Requires-Dist: tokenizers; extra == "all"
157
+ Requires-Dist: sentence_transformers; extra == "all"
158
+ Requires-Dist: flet-video; extra == "all"
159
+ Requires-Dist: pymupdf4llm; extra == "all"
160
+ Requires-Dist: google-auth-oauthlib; extra == "all"
161
+ Requires-Dist: pytest-cov; extra == "all"
162
+ Requires-Dist: logfire[httpx]; extra == "all"
163
+ Requires-Dist: ollama; extra == "all"
164
+ Requires-Dist: faker; extra == "all"
165
+ Requires-Dist: torchaudio; extra == "all"
174
166
  Requires-Dist: pandas; extra == "all"
175
- Requires-Dist: huggingface_hub; extra == "all"
176
167
  Requires-Dist: google-api-python-client; extra == "all"
177
- Requires-Dist: logfire[httpx]; extra == "all"
178
- Requires-Dist: torchvision; extra == "all"
179
- Requires-Dist: httpx_retries; extra == "all"
180
- Requires-Dist: cachetools; extra == "all"
181
- Requires-Dist: diskcache; extra == "all"
182
- Requires-Dist: regex; extra == "all"
168
+ Requires-Dist: uvicorn[standard]; extra == "all"
169
+ Requires-Dist: appdirs; extra == "all"
170
+ Requires-Dist: flet[all]; extra == "all"
183
171
  Requires-Dist: setuptools; extra == "all"
172
+ Requires-Dist: logfire[fastapi]; extra == "all"
173
+ Requires-Dist: yamlscript; extra == "all"
174
+ Requires-Dist: pydevd-pycharm~=251.25410.159; extra == "all"
175
+ Requires-Dist: tinynetrc; extra == "all"
176
+ Requires-Dist: pydantic-ai[logfire,openai]; extra == "all"
177
+ Requires-Dist: Unidecode; extra == "all"
178
+ Requires-Dist: pydantic-settings; extra == "all"
179
+ Requires-Dist: json_repair; extra == "all"
180
+ Requires-Dist: peft; extra == "all"
181
+ Requires-Dist: distributed; extra == "all"
182
+ Requires-Dist: openai; extra == "all"
183
+ Requires-Dist: diskcache; extra == "all"
184
184
  Dynamic: author
185
185
  Dynamic: author-email
186
186
  Dynamic: description
@@ -1 +0,0 @@
1
- 1.3.12
File without changes
File without changes
@@ -14,61 +14,61 @@ pydantic-ai[logfire,openai]
14
14
  ollama
15
15
 
16
16
  [all]
17
- fastapi
18
- contexttimer
19
- tinynetrc
20
- ollama
21
- uvicorn[standard]
22
- pymupdf
23
- pymupdf4llm
24
- logfire[fastapi]
17
+ deepmerge
25
18
  google-auth-httplib2
26
- Unidecode
27
- faker
28
- pydantic-ai[logfire,openai]
19
+ fastapi
20
+ bokeh
21
+ pydantic
29
22
  tabulate
30
- pyyaml
31
- html2text
32
- json_repair
33
- flet[all]
34
- httpx
23
+ dask[bag]
24
+ openpyxl
35
25
  filetype
36
- pydantic
26
+ pymupdf
27
+ docker
28
+ flet-webview
29
+ dnspython[doh]
37
30
  logfire
38
- torchaudio
39
- flet-video
40
- pydevd-pycharm~=251.25410.159
41
- distributed
42
- pytest-cov
43
- sentence_transformers
44
- yamlscript
45
- appdirs
31
+ contexttimer
32
+ torchvision
33
+ huggingface_hub
46
34
  transformers[sentencepiece]
47
- dnspython[doh]
48
- openpyxl
49
- openai
50
- google-auth-oauthlib
51
- sre_yield
35
+ cachetools
36
+ httpx
52
37
  semver
53
- deepmerge
54
- pydantic-settings
55
- tokenizers
56
- peft
57
- flet-webview
38
+ sre_yield
39
+ html2text
40
+ pyyaml
58
41
  google-auth
59
- dask[bag]
60
- docker
61
- bokeh
42
+ regex
43
+ httpx_retries
44
+ tokenizers
45
+ sentence_transformers
46
+ flet-video
47
+ pymupdf4llm
48
+ google-auth-oauthlib
49
+ pytest-cov
50
+ logfire[httpx]
51
+ ollama
52
+ faker
53
+ torchaudio
62
54
  pandas
63
- huggingface_hub
64
55
  google-api-python-client
65
- logfire[httpx]
66
- torchvision
67
- httpx_retries
68
- cachetools
69
- diskcache
70
- regex
56
+ uvicorn[standard]
57
+ appdirs
58
+ flet[all]
71
59
  setuptools
60
+ logfire[fastapi]
61
+ yamlscript
62
+ pydevd-pycharm~=251.25410.159
63
+ tinynetrc
64
+ pydantic-ai[logfire,openai]
65
+ Unidecode
66
+ pydantic-settings
67
+ json_repair
68
+ peft
69
+ distributed
70
+ openai
71
+ diskcache
72
72
 
73
73
  [api]
74
74
  fastapi
File without changes
File without changes
File without changes