fmtr.tools 1.3.51__tar.gz → 1.3.53__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 (100) hide show
  1. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/PKG-INFO +47 -47
  2. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/ai_tools/agentic_tools.py +16 -15
  3. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/interface_tools/__init__.py +1 -1
  4. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/interface_tools/interface_tools.py +55 -60
  5. fmtr_tools-1.3.53/fmtr/tools/version +1 -0
  6. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr.tools.egg-info/PKG-INFO +47 -47
  7. fmtr_tools-1.3.51/fmtr/tools/version +0 -1
  8. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/LICENSE +0 -0
  9. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/README.md +0 -0
  10. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/__init__.py +0 -0
  11. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/ai_tools/__init__.py +0 -0
  12. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/ai_tools/inference_tools.py +0 -0
  13. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/api_tools.py +0 -0
  14. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/async_tools.py +0 -0
  15. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/augmentation_tools.py +0 -0
  16. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/caching_tools.py +0 -0
  17. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/constants.py +0 -0
  18. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/context_tools.py +0 -0
  19. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/data_modelling_tools.py +0 -0
  20. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/database_tools/__init__.py +0 -0
  21. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/database_tools/document.py +0 -0
  22. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/dataclass_tools.py +0 -0
  23. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/datatype_tools.py +0 -0
  24. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/datetime_tools.py +0 -0
  25. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/debugging_tools.py +0 -0
  26. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/dns_tools/__init__.py +0 -0
  27. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/dns_tools/client.py +0 -0
  28. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/dns_tools/dm.py +0 -0
  29. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/dns_tools/proxy.py +0 -0
  30. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/dns_tools/server.py +0 -0
  31. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/docker_tools.py +0 -0
  32. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/entrypoints/__init__.py +0 -0
  33. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/entrypoints/cache_hfh.py +0 -0
  34. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/entrypoints/ep_test.py +0 -0
  35. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/entrypoints/install_yamlscript.py +0 -0
  36. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/entrypoints/remote_debug_test.py +0 -0
  37. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/entrypoints/shell_debug.py +0 -0
  38. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/environment_tools.py +0 -0
  39. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/function_tools.py +0 -0
  40. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/google_api_tools.py +0 -0
  41. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/hash_tools.py +0 -0
  42. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/hfh_tools.py +0 -0
  43. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/html_tools.py +0 -0
  44. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/http_tools.py +0 -0
  45. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/import_tools.py +0 -0
  46. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/inherit_tools.py +0 -0
  47. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/inspection_tools.py +0 -0
  48. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/interface_tools/context.py +0 -0
  49. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/interface_tools/controls.py +0 -0
  50. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/iterator_tools.py +0 -0
  51. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/json_fix_tools.py +0 -0
  52. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/json_tools.py +0 -0
  53. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/logging_tools.py +0 -0
  54. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/merging_tools.py +0 -0
  55. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/metric_tools.py +0 -0
  56. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/name_tools.py +0 -0
  57. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/netrc_tools.py +0 -0
  58. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/openai_tools.py +0 -0
  59. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/packaging_tools.py +0 -0
  60. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/parallel_tools.py +0 -0
  61. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/path_tools/__init__.py +0 -0
  62. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/path_tools/app_path_tools.py +0 -0
  63. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/path_tools/path_tools.py +0 -0
  64. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/path_tools/type_path_tools.py +0 -0
  65. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/pattern_tools.py +0 -0
  66. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/pdf_tools.py +0 -0
  67. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/platform_tools.py +0 -0
  68. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/process_tools.py +0 -0
  69. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/profiling_tools.py +0 -0
  70. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/random_tools.py +0 -0
  71. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/semantic_tools.py +0 -0
  72. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/settings_tools.py +0 -0
  73. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/setup_tools/__init__.py +0 -0
  74. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/setup_tools/setup_tools.py +0 -0
  75. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/spaces_tools.py +0 -0
  76. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/string_tools.py +0 -0
  77. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/tabular_tools.py +0 -0
  78. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/tests/__init__.py +0 -0
  79. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/tests/conftest.py +0 -0
  80. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/tests/helpers.py +0 -0
  81. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/tests/test_datatype.py +0 -0
  82. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/tests/test_environment.py +0 -0
  83. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/tests/test_json.py +0 -0
  84. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/tests/test_path.py +0 -0
  85. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/tests/test_yaml.py +0 -0
  86. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/tokenization_tools.py +0 -0
  87. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/tools.py +0 -0
  88. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/unicode_tools.py +0 -0
  89. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/version_tools/__init__.py +0 -0
  90. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/version_tools/version_tools.py +0 -0
  91. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/webhook_tools.py +0 -0
  92. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr/tools/yaml_tools.py +0 -0
  93. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr.tools.egg-info/SOURCES.txt +0 -0
  94. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr.tools.egg-info/dependency_links.txt +0 -0
  95. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr.tools.egg-info/entry_points.txt +0 -0
  96. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr.tools.egg-info/requires.txt +46 -46
  97. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/fmtr.tools.egg-info/top_level.txt +0 -0
  98. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/pyproject.toml +0 -0
  99. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/setup.cfg +0 -0
  100. {fmtr_tools-1.3.51 → fmtr_tools-1.3.53}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fmtr.tools
3
- Version: 1.3.51
3
+ Version: 1.3.53
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
@@ -154,68 +154,68 @@ Provides-Extra: db-document
154
154
  Requires-Dist: beanie[odm]; extra == "db-document"
155
155
  Requires-Dist: motor; extra == "db-document"
156
156
  Provides-Extra: all
157
- Requires-Dist: httpx_retries; extra == "all"
158
- Requires-Dist: contexttimer; extra == "all"
159
- Requires-Dist: tinynetrc; extra == "all"
160
- Requires-Dist: pydantic-extra-types; extra == "all"
161
- Requires-Dist: transformers[sentencepiece]; extra == "all"
162
- Requires-Dist: pyyaml; extra == "all"
157
+ Requires-Dist: dask[bag]; extra == "all"
158
+ Requires-Dist: peft; extra == "all"
159
+ Requires-Dist: cachetools; extra == "all"
163
160
  Requires-Dist: pymupdf4llm; extra == "all"
164
- Requires-Dist: flet-webview; extra == "all"
165
- Requires-Dist: deepmerge; extra == "all"
166
- Requires-Dist: pydevd-pycharm~=251.25410.159; extra == "all"
167
- Requires-Dist: semver; extra == "all"
168
- Requires-Dist: logfire; extra == "all"
169
- Requires-Dist: docker; extra == "all"
170
- Requires-Dist: fastapi; extra == "all"
161
+ Requires-Dist: google-auth-httplib2; extra == "all"
171
162
  Requires-Dist: google-auth-oauthlib; extra == "all"
163
+ Requires-Dist: odfpy; extra == "all"
164
+ Requires-Dist: filetype; extra == "all"
172
165
  Requires-Dist: pydantic; extra == "all"
173
- Requires-Dist: playwright; extra == "all"
174
- Requires-Dist: google-auth-httplib2; extra == "all"
166
+ Requires-Dist: logfire; extra == "all"
167
+ Requires-Dist: transformers[sentencepiece]; extra == "all"
168
+ Requires-Dist: semver; extra == "all"
169
+ Requires-Dist: logfire[fastapi]; extra == "all"
170
+ Requires-Dist: fastapi; extra == "all"
175
171
  Requires-Dist: torchvision; extra == "all"
176
- Requires-Dist: deepdiff; extra == "all"
172
+ Requires-Dist: sentence_transformers; extra == "all"
173
+ Requires-Dist: pandas; extra == "all"
174
+ Requires-Dist: pydevd-pycharm~=251.25410.159; extra == "all"
175
+ Requires-Dist: contexttimer; extra == "all"
177
176
  Requires-Dist: openpyxl; extra == "all"
178
- Requires-Dist: cachetools; extra == "all"
179
177
  Requires-Dist: pydantic-settings; extra == "all"
180
- Requires-Dist: Unidecode; extra == "all"
181
- Requires-Dist: sentence_transformers; extra == "all"
182
- Requires-Dist: odfpy; extra == "all"
183
- Requires-Dist: json_repair; extra == "all"
184
- Requires-Dist: ollama; extra == "all"
185
- Requires-Dist: dask[bag]; extra == "all"
186
- Requires-Dist: pydantic-ai[logfire,openai]; extra == "all"
187
- Requires-Dist: html2text; extra == "all"
178
+ Requires-Dist: deepdiff; extra == "all"
188
179
  Requires-Dist: setuptools; extra == "all"
189
- Requires-Dist: diskcache; extra == "all"
190
- Requires-Dist: logfire[fastapi]; extra == "all"
191
- Requires-Dist: huggingface_hub; extra == "all"
192
- Requires-Dist: regex; extra == "all"
193
- Requires-Dist: torchaudio; extra == "all"
194
- Requires-Dist: httpx; extra == "all"
180
+ Requires-Dist: beanie[odm]; extra == "all"
195
181
  Requires-Dist: flet-video; extra == "all"
196
- Requires-Dist: sre_yield; extra == "all"
182
+ Requires-Dist: regex; extra == "all"
183
+ Requires-Dist: ollama; extra == "all"
184
+ Requires-Dist: tinynetrc; extra == "all"
185
+ Requires-Dist: huggingface_hub; extra == "all"
197
186
  Requires-Dist: tokenizers; extra == "all"
198
- Requires-Dist: tabulate; extra == "all"
199
- Requires-Dist: google-auth; extra == "all"
200
- Requires-Dist: yamlscript; extra == "all"
201
- Requires-Dist: beanie[odm]; extra == "all"
187
+ Requires-Dist: flet[all]; extra == "all"
202
188
  Requires-Dist: appdirs; extra == "all"
203
- Requires-Dist: google-api-python-client; extra == "all"
189
+ Requires-Dist: logfire[httpx]; extra == "all"
190
+ Requires-Dist: json_repair; extra == "all"
191
+ Requires-Dist: torchaudio; extra == "all"
204
192
  Requires-Dist: uvicorn[standard]; extra == "all"
205
- Requires-Dist: pandas; extra == "all"
193
+ Requires-Dist: motor; extra == "all"
206
194
  Requires-Dist: bokeh; extra == "all"
195
+ Requires-Dist: flet-webview; extra == "all"
196
+ Requires-Dist: httpx; extra == "all"
197
+ Requires-Dist: playwright; extra == "all"
198
+ Requires-Dist: yamlscript; extra == "all"
207
199
  Requires-Dist: distributed; extra == "all"
200
+ Requires-Dist: faker; extra == "all"
208
201
  Requires-Dist: pycountry; extra == "all"
209
- Requires-Dist: filetype; extra == "all"
210
- Requires-Dist: pytest-cov; extra == "all"
202
+ Requires-Dist: tabulate; extra == "all"
203
+ Requires-Dist: pydantic-ai[logfire,openai]; extra == "all"
204
+ Requires-Dist: html2text; extra == "all"
205
+ Requires-Dist: google-auth; extra == "all"
211
206
  Requires-Dist: openai; extra == "all"
212
- Requires-Dist: faker; extra == "all"
213
- Requires-Dist: pymupdf; extra == "all"
214
- Requires-Dist: peft; extra == "all"
215
- Requires-Dist: flet[all]; extra == "all"
216
- Requires-Dist: motor; extra == "all"
207
+ Requires-Dist: Unidecode; extra == "all"
208
+ Requires-Dist: google-api-python-client; extra == "all"
209
+ Requires-Dist: diskcache; extra == "all"
217
210
  Requires-Dist: dnspython[doh]; extra == "all"
218
- Requires-Dist: logfire[httpx]; extra == "all"
211
+ Requires-Dist: pydantic-extra-types; extra == "all"
212
+ Requires-Dist: pytest-cov; extra == "all"
213
+ Requires-Dist: httpx_retries; extra == "all"
214
+ Requires-Dist: pyyaml; extra == "all"
215
+ Requires-Dist: docker; extra == "all"
216
+ Requires-Dist: sre_yield; extra == "all"
217
+ Requires-Dist: deepmerge; extra == "all"
218
+ Requires-Dist: pymupdf; extra == "all"
219
219
  Dynamic: author
220
220
  Dynamic: author-email
221
221
  Dynamic: description
@@ -1,10 +1,12 @@
1
1
  import pydantic_ai
2
2
  from pydantic import PlainValidator
3
3
  from pydantic_ai import RunContext, ModelRetry
4
+ from pydantic_ai._output import OutputDataT
4
5
  from pydantic_ai.agent import AgentRunResult, Agent
5
6
  from pydantic_ai.models.openai import OpenAIModel
6
7
  from pydantic_ai.providers.openai import OpenAIProvider
7
- from typing import List, Optional, Any, Annotated
8
+ from pydantic_ai.tools import AgentDepsT
9
+ from typing import List, Optional, Any, Annotated, Generic
8
10
 
9
11
  from fmtr.tools import environment_tools as env
10
12
  from fmtr.tools.constants import Constants
@@ -25,15 +27,16 @@ class Validator:
25
27
  raise NotImplementedError()
26
28
 
27
29
 
28
-
29
-
30
- class Task:
30
+ class Task(Generic[AgentDepsT, OutputDataT]):
31
31
  """
32
32
 
33
33
  Linear task definition, as Agent configuration and typing, plus state history.
34
34
 
35
35
  """
36
36
 
37
+ TypeDeps = str
38
+ TypeOutput = str
39
+
37
40
  PROVIDER = OpenAIProvider(api_key=env.get(Constants.FMTR_OPENAI_API_KEY_KEY))
38
41
 
39
42
  API_HOST_FMTR = env.get(Constants.FMTR_AI_HOST_KEY, Constants.FMTR_AI_HOST_DEFAULT)
@@ -43,8 +46,6 @@ class Task:
43
46
  MODEL_ID = 'gpt-4o'
44
47
  MODEL_ID_FMTR = 'qwen2.5-coder:14b'
45
48
  SYSTEM_PROMPT_STATIC = None
46
- DEPS_TYPE = str
47
- RESULT_TYPE = str
48
49
  RESULT_RETRIES = 5
49
50
  VALIDATORS: List[Validator] = []
50
51
 
@@ -56,13 +57,13 @@ class Task:
56
57
  """
57
58
 
58
59
  self.model = OpenAIModel(self.MODEL_ID, provider=self.PROVIDER)
59
- self.agent = Agent(
60
+ self.agent = Agent[AgentDepsT, OutputDataT](
60
61
  *args,
61
62
  model=self.model,
62
63
  system_prompt=self.SYSTEM_PROMPT_STATIC or [],
63
- deps_type=self.DEPS_TYPE,
64
- result_type=self.RESULT_TYPE,
65
- result_retries=self.RESULT_RETRIES,
64
+ deps_type=self.TypeDeps,
65
+ output_type=self.TypeOutput,
66
+ output_retries=self.RESULT_RETRIES,
66
67
  **kwargs
67
68
  )
68
69
 
@@ -80,7 +81,7 @@ class Task:
80
81
  import asyncio
81
82
  return asyncio.run
82
83
 
83
- async def run(self, *args, deps=None, **kwargs) -> AgentRunResult[RESULT_TYPE]:
84
+ async def run(self, *args, deps=None, **kwargs) -> AgentRunResult[OutputDataT]:
84
85
  """
85
86
 
86
87
  Run Agent with deps-relative user prompt and while storing history
@@ -90,7 +91,7 @@ class Task:
90
91
  self.history = result.all_messages()
91
92
  return result
92
93
 
93
- async def validate(self, ctx: RunContext[DEPS_TYPE], output: RESULT_TYPE) -> RESULT_TYPE:
94
+ async def validate(self, ctx: RunContext[AgentDepsT], output: OutputDataT) -> OutputDataT:
94
95
  """
95
96
 
96
97
  Aggregate any validation failures and combine them into a single ModelRetry exception
@@ -107,7 +108,7 @@ class Task:
107
108
 
108
109
  return output
109
110
 
110
- def get_prompt(self, deps: Optional[DEPS_TYPE]) -> Optional[str]:
111
+ def get_prompt(self, deps: Optional[AgentDepsT]) -> Optional[str]:
111
112
  """
112
113
 
113
114
  Dummy prompt generator
@@ -115,7 +116,7 @@ class Task:
115
116
  """
116
117
  return None
117
118
 
118
- def add_system_prompt(self, ctx: RunContext[DEPS_TYPE]) -> str | List[str]:
119
+ def add_system_prompt(self, ctx: RunContext[AgentDepsT]) -> str | List[str]:
119
120
  """
120
121
 
121
122
  Dummy system prompt append
@@ -181,7 +182,7 @@ if __name__ == '__main__':
181
182
  class TaskTest(Task):
182
183
  # PROVIDER = Task.PROVIDER_FMTR
183
184
  # MODEL_ID = 'qwen2.5-coder:14b'
184
- RESULT_TYPE = TestOutput
185
+ TypeOutput = TestOutput
185
186
  SYSTEM_PROMPT_STATIC = 'Tell the user jokes.'
186
187
 
187
188
  def add_system_prompt(self, ctx: RunContext[TestDeps]) -> str:
@@ -1,7 +1,7 @@
1
1
  from fmtr.tools.import_tools import MissingExtraMockModule
2
2
 
3
3
  try:
4
- from fmtr.tools.interface_tools.interface_tools import Interface, update, progress
4
+ from fmtr.tools.interface_tools.interface_tools import Base, update, progress
5
5
  from fmtr.tools.interface_tools import controls
6
6
  from fmtr.tools.interface_tools.context import Context
7
7
  except ModuleNotFoundError as exception:
@@ -1,8 +1,9 @@
1
+ from typing import TypeVar, Generic, Type
2
+
1
3
  import flet as ft
4
+ from flet.core.control_event import ControlEvent
2
5
  from flet.core.types import AppView
3
6
  from flet.core.view import View
4
- from functools import cached_property
5
- from typing import TypeVar, Generic, Type, Self
6
7
 
7
8
  from fmtr.tools import environment_tools
8
9
  from fmtr.tools.constants import Constants
@@ -18,7 +19,7 @@ class update(MethodDecorator):
18
19
 
19
20
  """
20
21
 
21
- def stop(self, instance):
22
+ def stop(self, instance, *args, **kwargs):
22
23
  instance.page.update()
23
24
 
24
25
 
@@ -37,7 +38,7 @@ class progress(update):
37
38
  """
38
39
  return instance.context
39
40
 
40
- def start(self, instance):
41
+ def start(self, instance, *args, **kwargs):
41
42
  """
42
43
 
43
44
  Make progress visible and update.
@@ -46,7 +47,7 @@ class progress(update):
46
47
  instance.progress.visible = True
47
48
  instance.page.update()
48
49
 
49
- def stop(self, instance):
50
+ def stop(self, instance, *args, **kwargs):
50
51
  """
51
52
 
52
53
  Make progress not visible and update.
@@ -59,7 +60,7 @@ class progress(update):
59
60
  T = TypeVar('T', bound=Context)
60
61
 
61
62
 
62
- class Interface(Generic[T], ft.Column):
63
+ class Base(Generic[T], ft.Column):
63
64
  """
64
65
 
65
66
  Simple interface base class.
@@ -76,58 +77,31 @@ class Interface(Generic[T], ft.Column):
76
77
 
77
78
  TypeContext: Type[T] = Context
78
79
 
79
- def __init__(self, context: T, *args, **kwargs):
80
- """
81
-
82
- Instantiate and apply interface config
83
-
84
- """
85
- self.context = context
86
- super().__init__(*args, **kwargs, scroll=self.SCROLL)
87
-
88
80
  @classmethod
89
- async def render(cls, page: ft.Page):
90
- """
91
-
92
- Interface entry point. Set relevant callbacks, and add instantiated self to page views
93
-
81
+ async def new(cls, page: ft.Page):
94
82
  """
95
- if not page.on_route_change:
96
- page.title = cls.TITLE
97
- page.theme = cls.get_theme()
98
- page.views.clear()
99
- context = cls.TypeContext(page=page)
100
-
101
- self = await cls.create(context)
102
83
 
103
- view = self.view
104
- if not view:
105
- view = self
106
- page.views.append(view)
107
- page.on_route_change = cls.route
108
- page.on_view_pop = cls.pop
84
+ Interface entry point/async constructor. Set relevant callbacks, and add instantiated self to page views.
109
85
 
110
- page.go(cls.ROUTE_ROOT)
86
+ Override this to work with `Context`, do async setup. Otherwise, override __init__ (which is regular Column __init__) for a simple interface.
111
87
 
112
- @classmethod
113
- async def create(cls, context: T) -> Self:
114
88
  """
89
+ page.scroll = cls.SCROLL
90
+ page.title = cls.TITLE
91
+ page.on_connect = cls.on_connect
92
+ page.on_disconnect = cls.on_disconnect
93
+ page.on_route_change = cls.route
94
+ page.on_view_pop = cls.pop
95
+ page.theme = cls.get_theme()
115
96
 
116
- Overridable async interface constructor.
117
-
118
- """
119
- self = cls(context)
120
- return self
121
-
122
-
123
- @cached_property
124
- def view(self):
125
- """
97
+ context = cls.TypeContext(page=page)
98
+ self = cls()
99
+ self.context = context
126
100
 
127
- Overridable view definition.
101
+ page.controls.append(self)
102
+ page.update()
128
103
 
129
- """
130
- return None
104
+ return self
131
105
 
132
106
  @classmethod
133
107
  def route(cls, event: ft.RouteChangeEvent):
@@ -148,20 +122,25 @@ class Interface(Generic[T], ft.Column):
148
122
  logger.debug(f'View popped: {page.route=} {len(page.views)=} {view=}')
149
123
 
150
124
  @classmethod
151
- def launch(cls):
125
+ def on_connect(cls, event: ControlEvent):
152
126
  """
153
127
 
154
- Launch via render method
128
+ Log connections
155
129
 
156
130
  """
131
+ page = event.control
132
+ logger.warning(f'Connect: {page.client_user_agent=} {page.platform.name=}')
157
133
 
158
- if cls.URL:
159
- url = cls.URL
160
- else:
161
- url = f'http://{cls.HOST}:{cls.PORT}'
134
+ @classmethod
135
+ def on_disconnect(cls, event: ControlEvent):
136
+ """
137
+
138
+ Log disconnections
139
+
140
+ """
141
+ page = event.control
142
+ logger.warning(f'Disconnect {page.client_user_agent=} {page.platform.name=}')
162
143
 
163
- logger.info(f"Launching {cls.TITLE} at {url}")
164
- ft.app(cls.render, view=cls.APPVIEW, host=cls.HOST, port=cls.PORT, assets_dir=cls.PATH_ASSETS)
165
144
 
166
145
  @classmethod
167
146
  def get_theme(self):
@@ -176,8 +155,24 @@ class Interface(Generic[T], ft.Column):
176
155
  )
177
156
  return theme
178
157
 
158
+ @classmethod
159
+ def launch(cls):
160
+ """
161
+
162
+ Launch via async constructor method
163
+
164
+ """
165
+
166
+ if cls.URL:
167
+ url = cls.URL
168
+ else:
169
+ url = f'http://{cls.HOST}:{cls.PORT}'
170
+
171
+ logger.info(f"Launching {cls.TITLE} at {url}")
172
+ ft.app(cls.new, view=cls.APPVIEW, host=cls.HOST, port=cls.PORT, assets_dir=cls.PATH_ASSETS, )
173
+
179
174
 
180
- class Test(Interface[Context]):
175
+ class Test(Base[Context]):
181
176
  """
182
177
 
183
178
  Simple test interface, showing typing example.
@@ -187,9 +182,9 @@ class Test(Interface[Context]):
187
182
 
188
183
  TITLE = 'Test Interface'
189
184
 
190
- def __init__(self, context: Context):
185
+ def __init__(self):
191
186
  controls = [ft.Text(self.TITLE)]
192
- super().__init__(context=context, controls=controls)
187
+ super().__init__(controls=controls)
193
188
 
194
189
  if __name__ == "__main__":
195
190
  Test.launch()
@@ -0,0 +1 @@
1
+ 1.3.53
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fmtr.tools
3
- Version: 1.3.51
3
+ Version: 1.3.53
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
@@ -154,68 +154,68 @@ Provides-Extra: db-document
154
154
  Requires-Dist: beanie[odm]; extra == "db-document"
155
155
  Requires-Dist: motor; extra == "db-document"
156
156
  Provides-Extra: all
157
- Requires-Dist: httpx_retries; extra == "all"
158
- Requires-Dist: contexttimer; extra == "all"
159
- Requires-Dist: tinynetrc; extra == "all"
160
- Requires-Dist: pydantic-extra-types; extra == "all"
161
- Requires-Dist: transformers[sentencepiece]; extra == "all"
162
- Requires-Dist: pyyaml; extra == "all"
157
+ Requires-Dist: dask[bag]; extra == "all"
158
+ Requires-Dist: peft; extra == "all"
159
+ Requires-Dist: cachetools; extra == "all"
163
160
  Requires-Dist: pymupdf4llm; extra == "all"
164
- Requires-Dist: flet-webview; extra == "all"
165
- Requires-Dist: deepmerge; extra == "all"
166
- Requires-Dist: pydevd-pycharm~=251.25410.159; extra == "all"
167
- Requires-Dist: semver; extra == "all"
168
- Requires-Dist: logfire; extra == "all"
169
- Requires-Dist: docker; extra == "all"
170
- Requires-Dist: fastapi; extra == "all"
161
+ Requires-Dist: google-auth-httplib2; extra == "all"
171
162
  Requires-Dist: google-auth-oauthlib; extra == "all"
163
+ Requires-Dist: odfpy; extra == "all"
164
+ Requires-Dist: filetype; extra == "all"
172
165
  Requires-Dist: pydantic; extra == "all"
173
- Requires-Dist: playwright; extra == "all"
174
- Requires-Dist: google-auth-httplib2; extra == "all"
166
+ Requires-Dist: logfire; extra == "all"
167
+ Requires-Dist: transformers[sentencepiece]; extra == "all"
168
+ Requires-Dist: semver; extra == "all"
169
+ Requires-Dist: logfire[fastapi]; extra == "all"
170
+ Requires-Dist: fastapi; extra == "all"
175
171
  Requires-Dist: torchvision; extra == "all"
176
- Requires-Dist: deepdiff; extra == "all"
172
+ Requires-Dist: sentence_transformers; extra == "all"
173
+ Requires-Dist: pandas; extra == "all"
174
+ Requires-Dist: pydevd-pycharm~=251.25410.159; extra == "all"
175
+ Requires-Dist: contexttimer; extra == "all"
177
176
  Requires-Dist: openpyxl; extra == "all"
178
- Requires-Dist: cachetools; extra == "all"
179
177
  Requires-Dist: pydantic-settings; extra == "all"
180
- Requires-Dist: Unidecode; extra == "all"
181
- Requires-Dist: sentence_transformers; extra == "all"
182
- Requires-Dist: odfpy; extra == "all"
183
- Requires-Dist: json_repair; extra == "all"
184
- Requires-Dist: ollama; extra == "all"
185
- Requires-Dist: dask[bag]; extra == "all"
186
- Requires-Dist: pydantic-ai[logfire,openai]; extra == "all"
187
- Requires-Dist: html2text; extra == "all"
178
+ Requires-Dist: deepdiff; extra == "all"
188
179
  Requires-Dist: setuptools; extra == "all"
189
- Requires-Dist: diskcache; extra == "all"
190
- Requires-Dist: logfire[fastapi]; extra == "all"
191
- Requires-Dist: huggingface_hub; extra == "all"
192
- Requires-Dist: regex; extra == "all"
193
- Requires-Dist: torchaudio; extra == "all"
194
- Requires-Dist: httpx; extra == "all"
180
+ Requires-Dist: beanie[odm]; extra == "all"
195
181
  Requires-Dist: flet-video; extra == "all"
196
- Requires-Dist: sre_yield; extra == "all"
182
+ Requires-Dist: regex; extra == "all"
183
+ Requires-Dist: ollama; extra == "all"
184
+ Requires-Dist: tinynetrc; extra == "all"
185
+ Requires-Dist: huggingface_hub; extra == "all"
197
186
  Requires-Dist: tokenizers; extra == "all"
198
- Requires-Dist: tabulate; extra == "all"
199
- Requires-Dist: google-auth; extra == "all"
200
- Requires-Dist: yamlscript; extra == "all"
201
- Requires-Dist: beanie[odm]; extra == "all"
187
+ Requires-Dist: flet[all]; extra == "all"
202
188
  Requires-Dist: appdirs; extra == "all"
203
- Requires-Dist: google-api-python-client; extra == "all"
189
+ Requires-Dist: logfire[httpx]; extra == "all"
190
+ Requires-Dist: json_repair; extra == "all"
191
+ Requires-Dist: torchaudio; extra == "all"
204
192
  Requires-Dist: uvicorn[standard]; extra == "all"
205
- Requires-Dist: pandas; extra == "all"
193
+ Requires-Dist: motor; extra == "all"
206
194
  Requires-Dist: bokeh; extra == "all"
195
+ Requires-Dist: flet-webview; extra == "all"
196
+ Requires-Dist: httpx; extra == "all"
197
+ Requires-Dist: playwright; extra == "all"
198
+ Requires-Dist: yamlscript; extra == "all"
207
199
  Requires-Dist: distributed; extra == "all"
200
+ Requires-Dist: faker; extra == "all"
208
201
  Requires-Dist: pycountry; extra == "all"
209
- Requires-Dist: filetype; extra == "all"
210
- Requires-Dist: pytest-cov; extra == "all"
202
+ Requires-Dist: tabulate; extra == "all"
203
+ Requires-Dist: pydantic-ai[logfire,openai]; extra == "all"
204
+ Requires-Dist: html2text; extra == "all"
205
+ Requires-Dist: google-auth; extra == "all"
211
206
  Requires-Dist: openai; extra == "all"
212
- Requires-Dist: faker; extra == "all"
213
- Requires-Dist: pymupdf; extra == "all"
214
- Requires-Dist: peft; extra == "all"
215
- Requires-Dist: flet[all]; extra == "all"
216
- Requires-Dist: motor; extra == "all"
207
+ Requires-Dist: Unidecode; extra == "all"
208
+ Requires-Dist: google-api-python-client; extra == "all"
209
+ Requires-Dist: diskcache; extra == "all"
217
210
  Requires-Dist: dnspython[doh]; extra == "all"
218
- Requires-Dist: logfire[httpx]; extra == "all"
211
+ Requires-Dist: pydantic-extra-types; extra == "all"
212
+ Requires-Dist: pytest-cov; extra == "all"
213
+ Requires-Dist: httpx_retries; extra == "all"
214
+ Requires-Dist: pyyaml; extra == "all"
215
+ Requires-Dist: docker; extra == "all"
216
+ Requires-Dist: sre_yield; extra == "all"
217
+ Requires-Dist: deepmerge; extra == "all"
218
+ Requires-Dist: pymupdf; extra == "all"
219
219
  Dynamic: author
220
220
  Dynamic: author-email
221
221
  Dynamic: description
@@ -1 +0,0 @@
1
- 1.3.51
File without changes
File without changes
@@ -18,68 +18,68 @@ pydantic-ai[logfire,openai]
18
18
  ollama
19
19
 
20
20
  [all]
21
- httpx_retries
22
- contexttimer
23
- tinynetrc
24
- pydantic-extra-types
25
- transformers[sentencepiece]
26
- pyyaml
21
+ dask[bag]
22
+ peft
23
+ cachetools
27
24
  pymupdf4llm
28
- flet-webview
29
- deepmerge
30
- pydevd-pycharm~=251.25410.159
31
- semver
32
- logfire
33
- docker
34
- fastapi
25
+ google-auth-httplib2
35
26
  google-auth-oauthlib
27
+ odfpy
28
+ filetype
36
29
  pydantic
37
- playwright
38
- google-auth-httplib2
30
+ logfire
31
+ transformers[sentencepiece]
32
+ semver
33
+ logfire[fastapi]
34
+ fastapi
39
35
  torchvision
40
- deepdiff
36
+ sentence_transformers
37
+ pandas
38
+ pydevd-pycharm~=251.25410.159
39
+ contexttimer
41
40
  openpyxl
42
- cachetools
43
41
  pydantic-settings
44
- Unidecode
45
- sentence_transformers
46
- odfpy
47
- json_repair
48
- ollama
49
- dask[bag]
50
- pydantic-ai[logfire,openai]
51
- html2text
42
+ deepdiff
52
43
  setuptools
53
- diskcache
54
- logfire[fastapi]
55
- huggingface_hub
56
- regex
57
- torchaudio
58
- httpx
44
+ beanie[odm]
59
45
  flet-video
60
- sre_yield
46
+ regex
47
+ ollama
48
+ tinynetrc
49
+ huggingface_hub
61
50
  tokenizers
62
- tabulate
63
- google-auth
64
- yamlscript
65
- beanie[odm]
51
+ flet[all]
66
52
  appdirs
67
- google-api-python-client
53
+ logfire[httpx]
54
+ json_repair
55
+ torchaudio
68
56
  uvicorn[standard]
69
- pandas
57
+ motor
70
58
  bokeh
59
+ flet-webview
60
+ httpx
61
+ playwright
62
+ yamlscript
71
63
  distributed
64
+ faker
72
65
  pycountry
73
- filetype
74
- pytest-cov
66
+ tabulate
67
+ pydantic-ai[logfire,openai]
68
+ html2text
69
+ google-auth
75
70
  openai
76
- faker
77
- pymupdf
78
- peft
79
- flet[all]
80
- motor
71
+ Unidecode
72
+ google-api-python-client
73
+ diskcache
81
74
  dnspython[doh]
82
- logfire[httpx]
75
+ pydantic-extra-types
76
+ pytest-cov
77
+ httpx_retries
78
+ pyyaml
79
+ docker
80
+ sre_yield
81
+ deepmerge
82
+ pymupdf
83
83
 
84
84
  [api]
85
85
  fastapi
File without changes
File without changes
File without changes