fmtr.tools 1.3.37__tar.gz → 1.3.39__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 (96) hide show
  1. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/PKG-INFO +47 -47
  2. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/ai_tools/agentic_tools.py +2 -3
  3. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/google_api_tools.py +15 -4
  4. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/iterator_tools.py +12 -0
  5. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/string_tools.py +60 -6
  6. fmtr_tools-1.3.39/fmtr/tools/version +1 -0
  7. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr.tools.egg-info/PKG-INFO +47 -47
  8. fmtr_tools-1.3.37/fmtr/tools/version +0 -1
  9. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/LICENSE +0 -0
  10. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/README.md +0 -0
  11. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/__init__.py +0 -0
  12. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/ai_tools/__init__.py +0 -0
  13. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/ai_tools/inference_tools.py +0 -0
  14. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/api_tools.py +0 -0
  15. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/async_tools.py +0 -0
  16. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/augmentation_tools.py +0 -0
  17. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/caching_tools.py +0 -0
  18. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/constants.py +0 -0
  19. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/context_tools.py +0 -0
  20. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/data_modelling_tools.py +0 -0
  21. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/dataclass_tools.py +0 -0
  22. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/datatype_tools.py +0 -0
  23. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/debugging_tools.py +0 -0
  24. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/dns_tools/__init__.py +0 -0
  25. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/dns_tools/client.py +0 -0
  26. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/dns_tools/dm.py +0 -0
  27. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/dns_tools/proxy.py +0 -0
  28. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/dns_tools/server.py +0 -0
  29. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/docker_tools.py +0 -0
  30. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/entrypoints/__init__.py +0 -0
  31. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/entrypoints/cache_hfh.py +0 -0
  32. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/entrypoints/ep_test.py +0 -0
  33. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/entrypoints/install_yamlscript.py +0 -0
  34. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/entrypoints/remote_debug_test.py +0 -0
  35. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/entrypoints/shell_debug.py +0 -0
  36. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/environment_tools.py +0 -0
  37. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/function_tools.py +0 -0
  38. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/hash_tools.py +0 -0
  39. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/hfh_tools.py +0 -0
  40. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/html_tools.py +0 -0
  41. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/http_tools.py +0 -0
  42. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/import_tools.py +0 -0
  43. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/inherit_tools.py +0 -0
  44. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/inspection_tools.py +0 -0
  45. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/interface_tools/__init__.py +0 -0
  46. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/interface_tools/controls.py +0 -0
  47. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/interface_tools/interface_tools.py +0 -0
  48. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/json_fix_tools.py +0 -0
  49. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/json_tools.py +0 -0
  50. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/logging_tools.py +0 -0
  51. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/merging_tools.py +0 -0
  52. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/metric_tools.py +0 -0
  53. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/name_tools.py +0 -0
  54. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/netrc_tools.py +0 -0
  55. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/openai_tools.py +0 -0
  56. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/packaging_tools.py +0 -0
  57. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/parallel_tools.py +0 -0
  58. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/path_tools/__init__.py +0 -0
  59. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/path_tools/app_path_tools.py +0 -0
  60. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/path_tools/path_tools.py +0 -0
  61. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/path_tools/type_path_tools.py +0 -0
  62. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/pattern_tools.py +0 -0
  63. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/pdf_tools.py +0 -0
  64. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/platform_tools.py +0 -0
  65. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/process_tools.py +0 -0
  66. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/profiling_tools.py +0 -0
  67. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/random_tools.py +0 -0
  68. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/semantic_tools.py +0 -0
  69. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/settings_tools.py +0 -0
  70. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/setup_tools/__init__.py +0 -0
  71. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/setup_tools/setup_tools.py +0 -0
  72. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/spaces_tools.py +0 -0
  73. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/tabular_tools.py +0 -0
  74. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/tests/__init__.py +0 -0
  75. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/tests/conftest.py +0 -0
  76. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/tests/helpers.py +0 -0
  77. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/tests/test_datatype.py +0 -0
  78. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/tests/test_environment.py +0 -0
  79. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/tests/test_json.py +0 -0
  80. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/tests/test_path.py +0 -0
  81. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/tests/test_yaml.py +0 -0
  82. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/tokenization_tools.py +0 -0
  83. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/tools.py +0 -0
  84. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/unicode_tools.py +0 -0
  85. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/version_tools/__init__.py +0 -0
  86. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/version_tools/version_tools.py +0 -0
  87. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/webhook_tools.py +0 -0
  88. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr/tools/yaml_tools.py +0 -0
  89. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr.tools.egg-info/SOURCES.txt +0 -0
  90. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr.tools.egg-info/dependency_links.txt +0 -0
  91. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr.tools.egg-info/entry_points.txt +0 -0
  92. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr.tools.egg-info/requires.txt +46 -46
  93. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/fmtr.tools.egg-info/top_level.txt +0 -0
  94. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/pyproject.toml +0 -0
  95. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/setup.cfg +0 -0
  96. {fmtr_tools-1.3.37 → fmtr_tools-1.3.39}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fmtr.tools
3
- Version: 1.3.37
3
+ Version: 1.3.39
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
@@ -133,62 +133,62 @@ Requires-Dist: logfire[httpx]; extra == "webhook"
133
133
  Provides-Extra: browsers
134
134
  Requires-Dist: playwright; extra == "browsers"
135
135
  Provides-Extra: all
136
- Requires-Dist: tokenizers; extra == "all"
137
- Requires-Dist: docker; extra == "all"
138
- Requires-Dist: filetype; extra == "all"
139
- Requires-Dist: pymupdf; extra == "all"
140
- Requires-Dist: logfire[httpx]; extra == "all"
141
- Requires-Dist: logfire[fastapi]; extra == "all"
142
- Requires-Dist: json_repair; extra == "all"
143
- Requires-Dist: logfire; extra == "all"
144
- Requires-Dist: deepmerge; extra == "all"
145
- Requires-Dist: peft; extra == "all"
146
- Requires-Dist: fastapi; extra == "all"
147
- Requires-Dist: google-auth; extra == "all"
148
- Requires-Dist: google-auth-oauthlib; extra == "all"
149
- Requires-Dist: transformers[sentencepiece]; extra == "all"
150
- Requires-Dist: appdirs; extra == "all"
151
- Requires-Dist: tabulate; extra == "all"
152
- Requires-Dist: torchvision; extra == "all"
153
- Requires-Dist: playwright; extra == "all"
154
- Requires-Dist: diskcache; extra == "all"
155
- Requires-Dist: openpyxl; extra == "all"
156
- Requires-Dist: tinynetrc; extra == "all"
157
- Requires-Dist: pymupdf4llm; extra == "all"
158
- Requires-Dist: dnspython[doh]; extra == "all"
159
- Requires-Dist: pydantic-ai[logfire,openai]; extra == "all"
160
- Requires-Dist: sentence_transformers; extra == "all"
161
- Requires-Dist: pydantic-settings; extra == "all"
162
- Requires-Dist: ollama; extra == "all"
163
- Requires-Dist: httpx; extra == "all"
164
- Requires-Dist: setuptools; extra == "all"
165
- Requires-Dist: google-api-python-client; extra == "all"
166
136
  Requires-Dist: distributed; extra == "all"
167
- Requires-Dist: google-auth-httplib2; extra == "all"
168
- Requires-Dist: dask[bag]; extra == "all"
169
- Requires-Dist: yamlscript; extra == "all"
170
137
  Requires-Dist: pyyaml; extra == "all"
171
- Requires-Dist: httpx_retries; extra == "all"
172
- Requires-Dist: huggingface_hub; extra == "all"
173
- Requires-Dist: flet-video; extra == "all"
174
138
  Requires-Dist: flet-webview; extra == "all"
175
- Requires-Dist: semver; extra == "all"
176
- Requires-Dist: pydantic; extra == "all"
177
- Requires-Dist: uvicorn[standard]; extra == "all"
139
+ Requires-Dist: google-api-python-client; extra == "all"
140
+ Requires-Dist: cachetools; extra == "all"
178
141
  Requires-Dist: flet[all]; extra == "all"
142
+ Requires-Dist: transformers[sentencepiece]; extra == "all"
143
+ Requires-Dist: sentence_transformers; extra == "all"
144
+ Requires-Dist: yamlscript; extra == "all"
179
145
  Requires-Dist: pytest-cov; extra == "all"
180
- Requires-Dist: pandas; extra == "all"
146
+ Requires-Dist: json_repair; extra == "all"
147
+ Requires-Dist: logfire[fastapi]; extra == "all"
181
148
  Requires-Dist: Unidecode; extra == "all"
182
- Requires-Dist: html2text; extra == "all"
183
- Requires-Dist: pydevd-pycharm~=251.25410.159; extra == "all"
149
+ Requires-Dist: pymupdf4llm; extra == "all"
150
+ Requires-Dist: semver; extra == "all"
151
+ Requires-Dist: google-auth-oauthlib; extra == "all"
152
+ Requires-Dist: appdirs; extra == "all"
153
+ Requires-Dist: bokeh; extra == "all"
184
154
  Requires-Dist: sre_yield; extra == "all"
155
+ Requires-Dist: pydevd-pycharm~=251.25410.159; extra == "all"
156
+ Requires-Dist: google-auth; extra == "all"
157
+ Requires-Dist: docker; extra == "all"
158
+ Requires-Dist: httpx_retries; extra == "all"
159
+ Requires-Dist: pandas; extra == "all"
160
+ Requires-Dist: google-auth-httplib2; extra == "all"
161
+ Requires-Dist: filetype; extra == "all"
185
162
  Requires-Dist: torchaudio; extra == "all"
186
- Requires-Dist: regex; extra == "all"
163
+ Requires-Dist: diskcache; extra == "all"
164
+ Requires-Dist: tokenizers; extra == "all"
165
+ Requires-Dist: html2text; extra == "all"
166
+ Requires-Dist: dask[bag]; extra == "all"
167
+ Requires-Dist: flet-video; extra == "all"
187
168
  Requires-Dist: contexttimer; extra == "all"
188
- Requires-Dist: faker; extra == "all"
169
+ Requires-Dist: setuptools; extra == "all"
170
+ Requires-Dist: pydantic; extra == "all"
171
+ Requires-Dist: dnspython[doh]; extra == "all"
189
172
  Requires-Dist: openai; extra == "all"
190
- Requires-Dist: cachetools; extra == "all"
191
- Requires-Dist: bokeh; extra == "all"
173
+ Requires-Dist: huggingface_hub; extra == "all"
174
+ Requires-Dist: logfire[httpx]; extra == "all"
175
+ Requires-Dist: fastapi; extra == "all"
176
+ Requires-Dist: deepmerge; extra == "all"
177
+ Requires-Dist: logfire; extra == "all"
178
+ Requires-Dist: pymupdf; extra == "all"
179
+ Requires-Dist: httpx; extra == "all"
180
+ Requires-Dist: tabulate; extra == "all"
181
+ Requires-Dist: pydantic-settings; extra == "all"
182
+ Requires-Dist: pydantic-ai[logfire,openai]; extra == "all"
183
+ Requires-Dist: regex; extra == "all"
184
+ Requires-Dist: faker; extra == "all"
185
+ Requires-Dist: ollama; extra == "all"
186
+ Requires-Dist: openpyxl; extra == "all"
187
+ Requires-Dist: playwright; extra == "all"
188
+ Requires-Dist: tinynetrc; extra == "all"
189
+ Requires-Dist: uvicorn[standard]; extra == "all"
190
+ Requires-Dist: peft; extra == "all"
191
+ Requires-Dist: torchvision; extra == "all"
192
192
  Dynamic: author
193
193
  Dynamic: author-email
194
194
  Dynamic: description
@@ -1,11 +1,10 @@
1
- from typing import List, Optional, Any, Annotated
2
-
3
1
  import pydantic_ai
4
2
  from pydantic import PlainValidator
5
3
  from pydantic_ai import RunContext, ModelRetry
6
4
  from pydantic_ai.agent import AgentRunResult, Agent
7
5
  from pydantic_ai.models.openai import OpenAIModel
8
6
  from pydantic_ai.providers.openai import OpenAIProvider
7
+ from typing import List, Optional, Any, Annotated
9
8
 
10
9
  from fmtr.tools import environment_tools as env
11
10
  from fmtr.tools.constants import Constants
@@ -153,7 +152,7 @@ def default_prompt_none_specified(text):
153
152
  return text
154
153
 
155
154
 
156
- StringDefaultNoneSpecified = Annotated[str, PlainValidator(default_prompt_none_specified)]
155
+ StringDefaultNoneSpecified = Annotated[Optional[str], PlainValidator(default_prompt_none_specified)]
157
156
 
158
157
 
159
158
  if __name__ == '__main__':
@@ -1,3 +1,4 @@
1
+ from google.auth.transport.requests import Request
1
2
  from google.oauth2.credentials import Credentials
2
3
  from google_auth_oauthlib.flow import InstalledAppFlow
3
4
  from googleapiclient.discovery import build
@@ -20,8 +21,12 @@ class Authenticator:
20
21
 
21
22
  @classmethod
22
23
  def auth(cls):
23
- msg = f'Doing auth for service {cls.SERVICE} ({cls.VERSION})...'
24
- logger.info(msg)
24
+ """
25
+
26
+ Do initial authentication or refresh token if expired.
27
+
28
+ """
29
+ logger.info(f'Doing auth for service {cls.SERVICE} ({cls.VERSION})...')
25
30
 
26
31
  PATH_CREDS = cls.PATH / 'credentials.json'
27
32
  PATH_TOKEN = cls.PATH / f'{cls.SERVICE}.json'
@@ -29,9 +34,15 @@ class Authenticator:
29
34
  if PATH_TOKEN.exists():
30
35
  data_token = PATH_TOKEN.read_json()
31
36
  credentials = Credentials.from_authorized_user_info(data_token, cls.SCOPES)
37
+ if credentials.expired:
38
+ with logger.span(f'Credentials expired for {cls.SERVICE}. Will refresh...'):
39
+ logger.warning(f'{cls.SERVICE}. {PATH_CREDS.exists()=} {PATH_TOKEN.exists()=} {credentials.valid=} {credentials.expired=} {credentials.expiry=}')
40
+ credentials.refresh(Request())
41
+ PATH_TOKEN.write_text(credentials.to_json())
32
42
  else:
33
43
  flow = InstalledAppFlow.from_client_secrets_file(PATH_CREDS, cls.SCOPES)
44
+ flow.authorization_url(prompt='consent', access_type='offline')
34
45
  credentials = flow.run_local_server(open_browser=False, port=cls.PORT)
35
46
  PATH_TOKEN.write_text(credentials.to_json())
36
- service = build(cls.SERVICE, cls.VERSION, credentials=credentials)
37
- return service
47
+
48
+ return build(cls.SERVICE, cls.VERSION, credentials=credentials)
@@ -1,6 +1,9 @@
1
1
  from itertools import chain, batched
2
+
2
3
  from typing import List, Dict, Any
3
4
 
5
+ from fmtr.tools.datatype_tools import is_none
6
+
4
7
 
5
8
  def enlist(value) -> List[Any]:
6
9
  """
@@ -52,3 +55,12 @@ def rebatch(batches, size: int):
52
55
 
53
56
  """
54
57
  return batched(chain.from_iterable(batches), size)
58
+
59
+
60
+ def strip_none(*items):
61
+ """
62
+
63
+ Remove nones from a list of arguments
64
+
65
+ """
66
+ return [item for item in items if not is_none(item)]
@@ -1,7 +1,8 @@
1
1
  from collections import namedtuple
2
+ from string import Formatter
2
3
 
3
4
  import re
4
- from string import Formatter
5
+ from dataclasses import dataclass
5
6
  from textwrap import dedent
6
7
  from typing import List
7
8
 
@@ -84,17 +85,70 @@ def sanitize(*strings, sep: str = '-') -> str:
84
85
  return string
85
86
 
86
87
 
87
- def truncate_mid(text, length=None, sep=ELLIPSIS):
88
+ @dataclass
89
+ class Truncation:
90
+ """
91
+
92
+ Result type for truncation functions
93
+
94
+ """
95
+ text: str
96
+ text_without_sep: str | None
97
+ original: str
98
+ remainder: str | None
99
+ sep: str
100
+
101
+
102
+ def truncate(text, length=None, sep=ELLIPSIS, return_type=str):
103
+ """
104
+
105
+ Truncate a string to length characters
106
+
88
107
  """
108
+ text = flatten(text)
109
+ if len(text) <= length or not length:
110
+ return text if return_type is str else Truncation(text, text, text, None, sep)
111
+
112
+ cutoff = length - len(sep)
113
+ truncated = text[:cutoff] + sep
114
+
115
+ if return_type is str:
116
+ return truncated
117
+ else:
118
+ return Truncation(
119
+ text=truncated,
120
+ text_without_sep=text[:cutoff],
121
+ original=text,
122
+ remainder=text[cutoff:] or None,
123
+ sep=sep
124
+ )
89
125
 
90
- Truncate a string to `length` characters in the middle
126
+
127
+ def truncate_mid(text, length=None, sep=ELLIPSIS, return_type=str):
128
+ """
129
+
130
+ Truncate a string to `length` characters in the middle.
91
131
 
92
132
  """
93
133
  text = flatten(text)
94
134
  if len(text) <= length or not length:
95
- return text
96
- half_length = (length - 3) // 2
97
- return text[:half_length] + sep + text[-half_length:]
135
+ return text if return_type is str else Truncation(text, text, text, '', sep)
136
+
137
+ half = (length - len(sep)) // 2
138
+ left = text[:half]
139
+ right = text[-half:]
140
+ truncated = left + sep + right
141
+
142
+ if return_type is str:
143
+ return truncated
144
+ else:
145
+ return Truncation(
146
+ text=truncated,
147
+ text_without_sep=None,
148
+ original=text,
149
+ remainder=None,
150
+ sep=sep
151
+ )
98
152
 
99
153
 
100
154
  def flatten(raw):
@@ -0,0 +1 @@
1
+ 1.3.39
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fmtr.tools
3
- Version: 1.3.37
3
+ Version: 1.3.39
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
@@ -133,62 +133,62 @@ Requires-Dist: logfire[httpx]; extra == "webhook"
133
133
  Provides-Extra: browsers
134
134
  Requires-Dist: playwright; extra == "browsers"
135
135
  Provides-Extra: all
136
- Requires-Dist: tokenizers; extra == "all"
137
- Requires-Dist: docker; extra == "all"
138
- Requires-Dist: filetype; extra == "all"
139
- Requires-Dist: pymupdf; extra == "all"
140
- Requires-Dist: logfire[httpx]; extra == "all"
141
- Requires-Dist: logfire[fastapi]; extra == "all"
142
- Requires-Dist: json_repair; extra == "all"
143
- Requires-Dist: logfire; extra == "all"
144
- Requires-Dist: deepmerge; extra == "all"
145
- Requires-Dist: peft; extra == "all"
146
- Requires-Dist: fastapi; extra == "all"
147
- Requires-Dist: google-auth; extra == "all"
148
- Requires-Dist: google-auth-oauthlib; extra == "all"
149
- Requires-Dist: transformers[sentencepiece]; extra == "all"
150
- Requires-Dist: appdirs; extra == "all"
151
- Requires-Dist: tabulate; extra == "all"
152
- Requires-Dist: torchvision; extra == "all"
153
- Requires-Dist: playwright; extra == "all"
154
- Requires-Dist: diskcache; extra == "all"
155
- Requires-Dist: openpyxl; extra == "all"
156
- Requires-Dist: tinynetrc; extra == "all"
157
- Requires-Dist: pymupdf4llm; extra == "all"
158
- Requires-Dist: dnspython[doh]; extra == "all"
159
- Requires-Dist: pydantic-ai[logfire,openai]; extra == "all"
160
- Requires-Dist: sentence_transformers; extra == "all"
161
- Requires-Dist: pydantic-settings; extra == "all"
162
- Requires-Dist: ollama; extra == "all"
163
- Requires-Dist: httpx; extra == "all"
164
- Requires-Dist: setuptools; extra == "all"
165
- Requires-Dist: google-api-python-client; extra == "all"
166
136
  Requires-Dist: distributed; extra == "all"
167
- Requires-Dist: google-auth-httplib2; extra == "all"
168
- Requires-Dist: dask[bag]; extra == "all"
169
- Requires-Dist: yamlscript; extra == "all"
170
137
  Requires-Dist: pyyaml; extra == "all"
171
- Requires-Dist: httpx_retries; extra == "all"
172
- Requires-Dist: huggingface_hub; extra == "all"
173
- Requires-Dist: flet-video; extra == "all"
174
138
  Requires-Dist: flet-webview; extra == "all"
175
- Requires-Dist: semver; extra == "all"
176
- Requires-Dist: pydantic; extra == "all"
177
- Requires-Dist: uvicorn[standard]; extra == "all"
139
+ Requires-Dist: google-api-python-client; extra == "all"
140
+ Requires-Dist: cachetools; extra == "all"
178
141
  Requires-Dist: flet[all]; extra == "all"
142
+ Requires-Dist: transformers[sentencepiece]; extra == "all"
143
+ Requires-Dist: sentence_transformers; extra == "all"
144
+ Requires-Dist: yamlscript; extra == "all"
179
145
  Requires-Dist: pytest-cov; extra == "all"
180
- Requires-Dist: pandas; extra == "all"
146
+ Requires-Dist: json_repair; extra == "all"
147
+ Requires-Dist: logfire[fastapi]; extra == "all"
181
148
  Requires-Dist: Unidecode; extra == "all"
182
- Requires-Dist: html2text; extra == "all"
183
- Requires-Dist: pydevd-pycharm~=251.25410.159; extra == "all"
149
+ Requires-Dist: pymupdf4llm; extra == "all"
150
+ Requires-Dist: semver; extra == "all"
151
+ Requires-Dist: google-auth-oauthlib; extra == "all"
152
+ Requires-Dist: appdirs; extra == "all"
153
+ Requires-Dist: bokeh; extra == "all"
184
154
  Requires-Dist: sre_yield; extra == "all"
155
+ Requires-Dist: pydevd-pycharm~=251.25410.159; extra == "all"
156
+ Requires-Dist: google-auth; extra == "all"
157
+ Requires-Dist: docker; extra == "all"
158
+ Requires-Dist: httpx_retries; extra == "all"
159
+ Requires-Dist: pandas; extra == "all"
160
+ Requires-Dist: google-auth-httplib2; extra == "all"
161
+ Requires-Dist: filetype; extra == "all"
185
162
  Requires-Dist: torchaudio; extra == "all"
186
- Requires-Dist: regex; extra == "all"
163
+ Requires-Dist: diskcache; extra == "all"
164
+ Requires-Dist: tokenizers; extra == "all"
165
+ Requires-Dist: html2text; extra == "all"
166
+ Requires-Dist: dask[bag]; extra == "all"
167
+ Requires-Dist: flet-video; extra == "all"
187
168
  Requires-Dist: contexttimer; extra == "all"
188
- Requires-Dist: faker; extra == "all"
169
+ Requires-Dist: setuptools; extra == "all"
170
+ Requires-Dist: pydantic; extra == "all"
171
+ Requires-Dist: dnspython[doh]; extra == "all"
189
172
  Requires-Dist: openai; extra == "all"
190
- Requires-Dist: cachetools; extra == "all"
191
- Requires-Dist: bokeh; extra == "all"
173
+ Requires-Dist: huggingface_hub; extra == "all"
174
+ Requires-Dist: logfire[httpx]; extra == "all"
175
+ Requires-Dist: fastapi; extra == "all"
176
+ Requires-Dist: deepmerge; extra == "all"
177
+ Requires-Dist: logfire; extra == "all"
178
+ Requires-Dist: pymupdf; extra == "all"
179
+ Requires-Dist: httpx; extra == "all"
180
+ Requires-Dist: tabulate; extra == "all"
181
+ Requires-Dist: pydantic-settings; extra == "all"
182
+ Requires-Dist: pydantic-ai[logfire,openai]; extra == "all"
183
+ Requires-Dist: regex; extra == "all"
184
+ Requires-Dist: faker; extra == "all"
185
+ Requires-Dist: ollama; extra == "all"
186
+ Requires-Dist: openpyxl; extra == "all"
187
+ Requires-Dist: playwright; extra == "all"
188
+ Requires-Dist: tinynetrc; extra == "all"
189
+ Requires-Dist: uvicorn[standard]; extra == "all"
190
+ Requires-Dist: peft; extra == "all"
191
+ Requires-Dist: torchvision; extra == "all"
192
192
  Dynamic: author
193
193
  Dynamic: author-email
194
194
  Dynamic: description
@@ -1 +0,0 @@
1
- 1.3.37
File without changes
File without changes
@@ -14,62 +14,62 @@ pydantic-ai[logfire,openai]
14
14
  ollama
15
15
 
16
16
  [all]
17
- tokenizers
18
- docker
19
- filetype
20
- pymupdf
21
- logfire[httpx]
22
- logfire[fastapi]
23
- json_repair
24
- logfire
25
- deepmerge
26
- peft
27
- fastapi
28
- google-auth
29
- google-auth-oauthlib
30
- transformers[sentencepiece]
31
- appdirs
32
- tabulate
33
- torchvision
34
- playwright
35
- diskcache
36
- openpyxl
37
- tinynetrc
38
- pymupdf4llm
39
- dnspython[doh]
40
- pydantic-ai[logfire,openai]
41
- sentence_transformers
42
- pydantic-settings
43
- ollama
44
- httpx
45
- setuptools
46
- google-api-python-client
47
17
  distributed
48
- google-auth-httplib2
49
- dask[bag]
50
- yamlscript
51
18
  pyyaml
52
- httpx_retries
53
- huggingface_hub
54
- flet-video
55
19
  flet-webview
56
- semver
57
- pydantic
58
- uvicorn[standard]
20
+ google-api-python-client
21
+ cachetools
59
22
  flet[all]
23
+ transformers[sentencepiece]
24
+ sentence_transformers
25
+ yamlscript
60
26
  pytest-cov
61
- pandas
27
+ json_repair
28
+ logfire[fastapi]
62
29
  Unidecode
63
- html2text
64
- pydevd-pycharm~=251.25410.159
30
+ pymupdf4llm
31
+ semver
32
+ google-auth-oauthlib
33
+ appdirs
34
+ bokeh
65
35
  sre_yield
36
+ pydevd-pycharm~=251.25410.159
37
+ google-auth
38
+ docker
39
+ httpx_retries
40
+ pandas
41
+ google-auth-httplib2
42
+ filetype
66
43
  torchaudio
67
- regex
44
+ diskcache
45
+ tokenizers
46
+ html2text
47
+ dask[bag]
48
+ flet-video
68
49
  contexttimer
69
- faker
50
+ setuptools
51
+ pydantic
52
+ dnspython[doh]
70
53
  openai
71
- cachetools
72
- bokeh
54
+ huggingface_hub
55
+ logfire[httpx]
56
+ fastapi
57
+ deepmerge
58
+ logfire
59
+ pymupdf
60
+ httpx
61
+ tabulate
62
+ pydantic-settings
63
+ pydantic-ai[logfire,openai]
64
+ regex
65
+ faker
66
+ ollama
67
+ openpyxl
68
+ playwright
69
+ tinynetrc
70
+ uvicorn[standard]
71
+ peft
72
+ torchvision
73
73
 
74
74
  [api]
75
75
  fastapi
File without changes
File without changes
File without changes