fmtr.tools 1.0.54__tar.gz → 1.1.0__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 (72) hide show
  1. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/PKG-INFO +154 -28
  2. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/README.md +9 -1
  3. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/__init__.py +8 -3
  4. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/ai_tools/agentic_tools.py +3 -3
  5. fmtr.tools-1.0.54/fmtr/tools/config.py → fmtr_tools-1.1.0/fmtr/tools/constants.py +1 -3
  6. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/debugging_tools.py +5 -5
  7. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/environment_tools.py +2 -2
  8. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/hash_tools.py +2 -2
  9. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/json_tools.py +2 -2
  10. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/logging_tools.py +4 -4
  11. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/parallel_tools.py +1 -2
  12. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/path_tools.py +113 -33
  13. fmtr_tools-1.1.0/fmtr/tools/settings_tools.py +65 -0
  14. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/tokenization_tools.py +1 -2
  15. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/tools.py +2 -2
  16. fmtr_tools-1.1.0/fmtr/tools/version +1 -0
  17. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/version_tools.py +16 -7
  18. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr.tools.egg-info/PKG-INFO +154 -28
  19. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr.tools.egg-info/SOURCES.txt +2 -2
  20. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr.tools.egg-info/requires.txt +55 -50
  21. fmtr.tools-1.0.54/fmtr/tools/config_tools.py +0 -54
  22. fmtr.tools-1.0.54/fmtr/tools/version +0 -1
  23. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/LICENSE +0 -0
  24. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/ai_tools/__init__.py +0 -0
  25. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/ai_tools/inference_tools.py +0 -0
  26. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/api_tools.py +0 -0
  27. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/async_tools.py +0 -0
  28. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/augmentation_tools.py +0 -0
  29. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/caching_tools.py +0 -0
  30. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/console_script_tools.py +0 -0
  31. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/data_modelling_tools.py +0 -0
  32. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/dataclass_tools.py +0 -0
  33. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/datatype_tools.py +0 -0
  34. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/docker_tools.py +0 -0
  35. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/function_tools.py +0 -0
  36. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/google_api_tools.py +0 -0
  37. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/hfh_tools.py +0 -0
  38. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/html_tools.py +0 -0
  39. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/import_tools.py +0 -0
  40. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/inspection_tools.py +0 -0
  41. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/interface_tools.py +0 -0
  42. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/iterator_tools.py +0 -0
  43. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/json_fix_tools.py +0 -0
  44. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/merging_tools.py +0 -0
  45. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/metric_tools.py +0 -0
  46. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/name_tools.py +0 -0
  47. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/netrc_tools.py +0 -0
  48. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/openai_tools.py +0 -0
  49. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/pdf_tools.py +0 -0
  50. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/platform_tools.py +0 -0
  51. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/process_tools.py +0 -0
  52. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/profiling_tools.py +0 -0
  53. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/random_tools.py +0 -0
  54. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/semantic_tools.py +0 -0
  55. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/spaces_tools.py +0 -0
  56. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/string_tools.py +0 -0
  57. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/tabular_tools.py +0 -0
  58. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/tests/__init__.py +0 -0
  59. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/tests/conftest.py +0 -0
  60. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/tests/helpers.py +0 -0
  61. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/tests/test_datatype.py +0 -0
  62. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/tests/test_environment.py +0 -0
  63. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/tests/test_json.py +0 -0
  64. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/tests/test_path.py +0 -0
  65. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/tests/test_yaml.py +0 -0
  66. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/unicode_tools.py +0 -0
  67. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr/tools/yaml_tools.py +0 -0
  68. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr.tools.egg-info/dependency_links.txt +0 -0
  69. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr.tools.egg-info/entry_points.txt +0 -0
  70. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/fmtr.tools.egg-info/top_level.txt +0 -0
  71. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/setup.cfg +0 -0
  72. {fmtr.tools-1.0.54 → fmtr_tools-1.1.0}/setup.py +0 -0
@@ -1,43 +1,161 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: fmtr.tools
3
- Version: 1.0.54
3
+ Version: 1.1.0
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
7
7
  Author-email: innovative.fowler@mask.pro.fmtr.dev
8
8
  License: Copyright © 2025 Frontmatter. All rights reserved.
9
9
  Description-Content-Type: text/markdown
10
- Provides-Extra: ai
11
- Provides-Extra: ai.client
12
- Provides-Extra: api
13
- Provides-Extra: augmentation
14
- Provides-Extra: caching
15
- Provides-Extra: debug
16
- Provides-Extra: dm
17
- Provides-Extra: docker.api
18
- Provides-Extra: google.api
19
- Provides-Extra: hfh
20
- Provides-Extra: html
21
- Provides-Extra: interface
22
- Provides-Extra: json-fix
10
+ License-File: LICENSE
11
+ Provides-Extra: test
12
+ Requires-Dist: flet-webview; extra == "test"
13
+ Requires-Dist: uvicorn; extra == "test"
14
+ Requires-Dist: pymupdf4llm; extra == "test"
15
+ Requires-Dist: pyyaml; extra == "test"
16
+ Requires-Dist: pytest-cov; extra == "test"
17
+ Requires-Dist: logfire; extra == "test"
18
+ Requires-Dist: google-auth-httplib2; extra == "test"
19
+ Requires-Dist: tinynetrc; extra == "test"
20
+ Requires-Dist: sre_yield; extra == "test"
21
+ Requires-Dist: bokeh; extra == "test"
22
+ Requires-Dist: html2text; extra == "test"
23
+ Requires-Dist: sentence_transformers; extra == "test"
24
+ Requires-Dist: docker; extra == "test"
25
+ Requires-Dist: peft; extra == "test"
26
+ Requires-Dist: google-auth; extra == "test"
27
+ Requires-Dist: fastapi; extra == "test"
28
+ Requires-Dist: pydantic; extra == "test"
29
+ Requires-Dist: pydantic-settings; extra == "test"
30
+ Requires-Dist: pydantic-ai[logfire,openai]; extra == "test"
31
+ Requires-Dist: torchvision; extra == "test"
32
+ Requires-Dist: google-api-python-client; extra == "test"
33
+ Requires-Dist: distributed; extra == "test"
34
+ Requires-Dist: openpyxl; extra == "test"
35
+ Requires-Dist: contexttimer; extra == "test"
36
+ Requires-Dist: huggingface_hub; extra == "test"
37
+ Requires-Dist: dask[bag]; extra == "test"
38
+ Requires-Dist: tabulate; extra == "test"
39
+ Requires-Dist: tokenizers; extra == "test"
40
+ Requires-Dist: ollama; extra == "test"
41
+ Requires-Dist: pandas; extra == "test"
42
+ Requires-Dist: flet-video; extra == "test"
43
+ Requires-Dist: flet[all]; extra == "test"
44
+ Requires-Dist: transformers[sentencepiece]; extra == "test"
45
+ Requires-Dist: semver; extra == "test"
46
+ Requires-Dist: openai; extra == "test"
47
+ Requires-Dist: google-auth-oauthlib; extra == "test"
48
+ Requires-Dist: pydevd-pycharm; extra == "test"
49
+ Requires-Dist: faker; extra == "test"
50
+ Requires-Dist: pymupdf; extra == "test"
51
+ Requires-Dist: deepmerge; extra == "test"
52
+ Requires-Dist: diskcache; extra == "test"
53
+ Requires-Dist: json_repair; extra == "test"
54
+ Requires-Dist: Unidecode; extra == "test"
55
+ Requires-Dist: torchaudio; extra == "test"
56
+ Provides-Extra: yaml
57
+ Requires-Dist: pyyaml; extra == "yaml"
23
58
  Provides-Extra: logging
24
- Provides-Extra: merging
25
- Provides-Extra: metric
26
- Provides-Extra: netrc
27
- Provides-Extra: openai.api
59
+ Requires-Dist: logfire; extra == "logging"
60
+ Requires-Dist: semver; extra == "logging"
28
61
  Provides-Extra: parallel
29
- Provides-Extra: pdf
62
+ Requires-Dist: dask[bag]; extra == "parallel"
63
+ Requires-Dist: distributed; extra == "parallel"
64
+ Requires-Dist: bokeh; extra == "parallel"
65
+ Provides-Extra: tokenization
66
+ Requires-Dist: tokenizers; extra == "tokenization"
67
+ Provides-Extra: augmentation
68
+ Requires-Dist: faker; extra == "augmentation"
69
+ Requires-Dist: sre_yield; extra == "augmentation"
30
70
  Provides-Extra: process
71
+ Requires-Dist: logfire; extra == "process"
72
+ Requires-Dist: semver; extra == "process"
31
73
  Provides-Extra: profiling
32
- Provides-Extra: semantic
33
- Provides-Extra: spaces
34
- Provides-Extra: tabular
35
- Provides-Extra: test
36
- Provides-Extra: tokenization
74
+ Requires-Dist: contexttimer; extra == "profiling"
75
+ Provides-Extra: docker-api
76
+ Requires-Dist: docker; extra == "docker-api"
37
77
  Provides-Extra: unicode
78
+ Requires-Dist: Unidecode; extra == "unicode"
38
79
  Provides-Extra: version
39
- Provides-Extra: yaml
40
- License-File: LICENSE
80
+ Requires-Dist: semver; extra == "version"
81
+ Provides-Extra: spaces
82
+ Requires-Dist: tinynetrc; extra == "spaces"
83
+ Provides-Extra: netrc
84
+ Requires-Dist: tinynetrc; extra == "netrc"
85
+ Provides-Extra: hfh
86
+ Requires-Dist: huggingface_hub; extra == "hfh"
87
+ Provides-Extra: merging
88
+ Requires-Dist: deepmerge; extra == "merging"
89
+ Provides-Extra: api
90
+ Requires-Dist: fastapi; extra == "api"
91
+ Requires-Dist: uvicorn; extra == "api"
92
+ Requires-Dist: logfire; extra == "api"
93
+ Requires-Dist: semver; extra == "api"
94
+ Requires-Dist: pydantic; extra == "api"
95
+ Provides-Extra: ai
96
+ Requires-Dist: peft; extra == "ai"
97
+ Requires-Dist: transformers[sentencepiece]; extra == "ai"
98
+ Requires-Dist: torchvision; extra == "ai"
99
+ Requires-Dist: torchaudio; extra == "ai"
100
+ Requires-Dist: pydantic; extra == "ai"
101
+ Provides-Extra: dm
102
+ Requires-Dist: pydantic; extra == "dm"
103
+ Provides-Extra: openai-api
104
+ Requires-Dist: openai; extra == "openai-api"
105
+ Provides-Extra: ai-client
106
+ Requires-Dist: logfire; extra == "ai-client"
107
+ Requires-Dist: semver; extra == "ai-client"
108
+ Requires-Dist: pydantic; extra == "ai-client"
109
+ Requires-Dist: openai; extra == "ai-client"
110
+ Requires-Dist: pydantic-ai[logfire,openai]; extra == "ai-client"
111
+ Requires-Dist: ollama; extra == "ai-client"
112
+ Provides-Extra: json-fix
113
+ Requires-Dist: json_repair; extra == "json-fix"
114
+ Provides-Extra: semantic
115
+ Requires-Dist: sentence_transformers; extra == "semantic"
116
+ Requires-Dist: pandas; extra == "semantic"
117
+ Requires-Dist: tabulate; extra == "semantic"
118
+ Requires-Dist: openpyxl; extra == "semantic"
119
+ Provides-Extra: metric
120
+ Requires-Dist: pandas; extra == "metric"
121
+ Requires-Dist: tabulate; extra == "metric"
122
+ Requires-Dist: openpyxl; extra == "metric"
123
+ Provides-Extra: tabular
124
+ Requires-Dist: pandas; extra == "tabular"
125
+ Requires-Dist: tabulate; extra == "tabular"
126
+ Requires-Dist: openpyxl; extra == "tabular"
127
+ Provides-Extra: html
128
+ Requires-Dist: html2text; extra == "html"
129
+ Provides-Extra: interface
130
+ Requires-Dist: flet[all]; extra == "interface"
131
+ Requires-Dist: flet-video; extra == "interface"
132
+ Requires-Dist: flet-webview; extra == "interface"
133
+ Requires-Dist: pydantic; extra == "interface"
134
+ Provides-Extra: google-api
135
+ Requires-Dist: google-auth; extra == "google-api"
136
+ Requires-Dist: google-auth-oauthlib; extra == "google-api"
137
+ Requires-Dist: google-auth-httplib2; extra == "google-api"
138
+ Requires-Dist: google-api-python-client; extra == "google-api"
139
+ Provides-Extra: caching
140
+ Requires-Dist: diskcache; extra == "caching"
141
+ Provides-Extra: pdf
142
+ Requires-Dist: pymupdf; extra == "pdf"
143
+ Requires-Dist: pydantic; extra == "pdf"
144
+ Requires-Dist: pymupdf4llm; extra == "pdf"
145
+ Provides-Extra: debug
146
+ Requires-Dist: pydevd-pycharm; extra == "debug"
147
+ Provides-Extra: sets
148
+ Requires-Dist: pydantic-settings; extra == "sets"
149
+ Requires-Dist: pydantic; extra == "sets"
150
+ Dynamic: author
151
+ Dynamic: author-email
152
+ Dynamic: description
153
+ Dynamic: description-content-type
154
+ Dynamic: home-page
155
+ Dynamic: license
156
+ Dynamic: license-file
157
+ Dynamic: provides-extra
158
+ Dynamic: summary
41
159
 
42
160
  # `fmtr.tools`
43
161
 
@@ -125,6 +243,10 @@ The included modules, plus any extra requirements, are as follows:
125
243
  - Extras: `ai`
126
244
  - `tools.config`: Base config class with overridable field processors.
127
245
  - Extras: None
246
+ -
247
+ `tools.settings`: A base configuration system built on Pydantic Settings that provides a flexible way to manage application settings from multiple sources, based on a standard
248
+ `path.PackagePaths` project layout.
249
+ - Extras: `sets`
128
250
  - `tools.dataclass`: Utilities for extracting and filtering fields and metadata from dataclasses, with support for applying filters and retrieving enabled fields based on metadata attributes.
129
251
  - Extras: None
130
252
  - `tools.datatype`
@@ -155,8 +277,12 @@ The included modules, plus any extra requirements, are as follows:
155
277
  - Extras: None
156
278
  - `tools.openai`: Utilities for interacting with the OpenAI API, simple text-to-text output, etc.
157
279
  - Extras: `openai.api`
158
- - `tools.Path`: Enhanced `pathlib.Path` object with additional functionality for Windows-to-Unix path conversion, reading/writing JSON and YAML files, and convenient directory creation with parent directories. Includes methods for obtaining paths to modules and temporary directories.
280
+ - `tools.Path`: Enhanced
281
+ `pathlib.Path` object with additional functionality for Windows-to-Unix path conversion in WSL environments, reading/writing JSON and YAML files with proper encoding.
159
282
  - Extras: None
283
+ -
284
+ `tools.PackagePaths` class for managing canonical package paths, like settings files, artifact directories, version files.
285
+ - Extras: None
160
286
  - `tools.platform`: Detecting if host is WSL, Docker etc.
161
287
  - Extras: None
162
288
  - `tools.ContextProcess`: Manages a function running in a separate process using a context manager. Provides methods to start, stop, and restart the process, with configurable restart delays. Useful for ensuring clean process management and automatic stopping when the context manager exits.
@@ -84,6 +84,10 @@ The included modules, plus any extra requirements, are as follows:
84
84
  - Extras: `ai`
85
85
  - `tools.config`: Base config class with overridable field processors.
86
86
  - Extras: None
87
+ -
88
+ `tools.settings`: A base configuration system built on Pydantic Settings that provides a flexible way to manage application settings from multiple sources, based on a standard
89
+ `path.PackagePaths` project layout.
90
+ - Extras: `sets`
87
91
  - `tools.dataclass`: Utilities for extracting and filtering fields and metadata from dataclasses, with support for applying filters and retrieving enabled fields based on metadata attributes.
88
92
  - Extras: None
89
93
  - `tools.datatype`
@@ -114,8 +118,12 @@ The included modules, plus any extra requirements, are as follows:
114
118
  - Extras: None
115
119
  - `tools.openai`: Utilities for interacting with the OpenAI API, simple text-to-text output, etc.
116
120
  - Extras: `openai.api`
117
- - `tools.Path`: Enhanced `pathlib.Path` object with additional functionality for Windows-to-Unix path conversion, reading/writing JSON and YAML files, and convenient directory creation with parent directories. Includes methods for obtaining paths to modules and temporary directories.
121
+ - `tools.Path`: Enhanced
122
+ `pathlib.Path` object with additional functionality for Windows-to-Unix path conversion in WSL environments, reading/writing JSON and YAML files with proper encoding.
118
123
  - Extras: None
124
+ -
125
+ `tools.PackagePaths` class for managing canonical package paths, like settings files, artifact directories, version files.
126
+ - Extras: None
119
127
  - `tools.platform`: Detecting if host is WSL, Docker etc.
120
128
  - Extras: None
121
129
  - `tools.ContextProcess`: Manages a function running in a separate process using a context manager. Provides methods to start, stop, and restart the process, with configurable restart delays. Useful for ensuring clean process management and automatic stopping when the context manager exits.
@@ -2,7 +2,7 @@ from fmtr.tools import version_tools as version
2
2
 
3
3
  __version__ = version.read()
4
4
 
5
- import fmtr.tools.config_tools as config
5
+
6
6
  import fmtr.tools.dataclass_tools as dataclass
7
7
  import fmtr.tools.datatype_tools as datatype
8
8
  import fmtr.tools.environment_tools as env
@@ -22,7 +22,8 @@ import fmtr.tools.async_tools as asyncio
22
22
  from fmtr.tools.logging_tools import logger
23
23
 
24
24
  from fmtr.tools.import_tools import MissingExtraMockModule
25
- from fmtr.tools.path_tools import Path
25
+ from fmtr.tools.path_tools import Path, PackagePaths
26
+ from fmtr.tools.constants import Constants
26
27
 
27
28
  try:
28
29
  from fmtr.tools import augmentation_tools as augmentation
@@ -158,9 +159,13 @@ try:
158
159
  except ImportError as exception:
159
160
  debug = MissingExtraMockModule('debug', exception)
160
161
 
162
+ try:
163
+ from fmtr.tools import settings_tools as sets
164
+ except ImportError as exception:
165
+ sets = MissingExtraMockModule('sets', exception)
166
+
161
167
 
162
168
  __all__ = [
163
- 'config',
164
169
  'dataclass',
165
170
  'datatype',
166
171
  'environment',
@@ -6,7 +6,7 @@ from pydantic_ai.models.openai import OpenAIModel
6
6
  from pydantic_ai.providers.openai import OpenAIProvider
7
7
 
8
8
  from fmtr.tools import environment_tools as env
9
- from fmtr.tools.config import ToolsConfig
9
+ from fmtr.tools.constants import Constants
10
10
 
11
11
  pydantic_ai.Agent.instrument_all()
12
12
 
@@ -17,9 +17,9 @@ class Task:
17
17
 
18
18
  """
19
19
 
20
- PROVIDER = OpenAIProvider(api_key=env.get(ToolsConfig.FMTR_OPENAI_API_KEY_KEY))
20
+ PROVIDER = OpenAIProvider(api_key=env.get(Constants.FMTR_OPENAI_API_KEY_KEY))
21
21
 
22
- API_HOST_FMTR = env.get(ToolsConfig.FMTR_AI_HOST_KEY, ToolsConfig.FMTR_AI_HOST_DEFAULT)
22
+ API_HOST_FMTR = env.get(Constants.FMTR_AI_HOST_KEY, Constants.FMTR_AI_HOST_DEFAULT)
23
23
  API_URL_FMTR = f'https://{API_HOST_FMTR}/v1'
24
24
  PROVIDER_FMTR = OpenAIProvider(base_url=API_URL_FMTR)
25
25
 
@@ -1,9 +1,7 @@
1
1
  import datetime
2
2
 
3
- from fmtr.tools.config_tools import ConfigClass
4
3
 
5
-
6
- class ToolsConfig(ConfigClass):
4
+ class Constants:
7
5
  ENCODING = 'UTF-8'
8
6
  ORG_NAME = 'fmtr'
9
7
  LIBRARY_NAME = f'{ORG_NAME}.tools'
@@ -1,7 +1,7 @@
1
1
  import pydevd_pycharm
2
2
 
3
3
  from fmtr.tools import environment_tools as env
4
- from fmtr.tools.config import ToolsConfig
4
+ from fmtr.tools.constants import Constants
5
5
 
6
6
  MASK = 'Starting debugger at tcp://{host}:{port}...'
7
7
 
@@ -12,16 +12,16 @@ def trace(is_debug=None, host=None, port=None, stdoutToServer=True, stderrToServ
12
12
 
13
13
  """
14
14
  if not is_debug:
15
- is_debug = env.get_bool(ToolsConfig.FMTR_REMOTE_DEBUG_ENABLED_KEY, False)
15
+ is_debug = env.get_bool(Constants.FMTR_REMOTE_DEBUG_ENABLED_KEY, False)
16
16
 
17
17
  if not is_debug:
18
18
  return
19
19
 
20
20
  if is_debug is True and not host:
21
- host = ToolsConfig.FMTR_REMOTE_DEBUG_HOST_DEFAULT
21
+ host = Constants.FMTR_REMOTE_DEBUG_HOST_DEFAULT
22
22
 
23
- host = host or env.get(ToolsConfig.FMTR_REMOTE_DEBUG_HOST_KEY, ToolsConfig.FMTR_REMOTE_DEBUG_HOST_DEFAULT)
24
- port = port or ToolsConfig.FMTR_REMOTE_DEBUG_PORT_DEFAULT
23
+ host = host or env.get(Constants.FMTR_REMOTE_DEBUG_HOST_KEY, Constants.FMTR_REMOTE_DEBUG_HOST_DEFAULT)
24
+ port = port or Constants.FMTR_REMOTE_DEBUG_PORT_DEFAULT
25
25
 
26
26
  from fmtr.tools import logger
27
27
 
@@ -8,7 +8,7 @@ from collections.abc import Callable
8
8
  from datetime import date, datetime
9
9
  from typing import Any, Dict
10
10
 
11
- from fmtr.tools.config import ToolsConfig
11
+ from fmtr.tools.constants import Constants
12
12
  from fmtr.tools.datatype_tools import to_bool
13
13
  from fmtr.tools.path_tools import Path
14
14
  from fmtr.tools.tools import identity, EMPTY
@@ -76,4 +76,4 @@ get_date = get_getter(date.fromisoformat)
76
76
  get_datetime = get_getter(datetime.fromisoformat)
77
77
  get_path = get_getter(Path)
78
78
 
79
- IS_DEBUG = get(ToolsConfig.FMTR_LOG_LEVEL_KEY, None, converter=str.upper) == 'DEBUG'
79
+ IS_DEBUG = get(Constants.FMTR_LOG_LEVEL_KEY, None, converter=str.upper) == 'DEBUG'
@@ -2,7 +2,7 @@ import base64
2
2
  import hashlib
3
3
  from zlib import crc32
4
4
 
5
- from fmtr.tools.config import ToolsConfig
5
+ from fmtr.tools.constants import Constants
6
6
 
7
7
  SPECIALS = {'O': '9', '=': '9', 'I': '9'}
8
8
 
@@ -12,7 +12,7 @@ def hash_unit(value: str) -> float:
12
12
  Hash the input string to a value between 0.0 and 1.0 (not secure).
13
13
 
14
14
  """
15
- value = str(value).encode(ToolsConfig.ENCODING)
15
+ value = str(value).encode(Constants.ENCODING)
16
16
  return float(crc32(value) & 0xffffffff) / 2 ** 32
17
17
 
18
18
 
@@ -1,6 +1,6 @@
1
1
  import json
2
2
 
3
- from fmtr.tools.config import ToolsConfig
3
+ from fmtr.tools.constants import Constants
4
4
 
5
5
 
6
6
  def to_json(obj):
@@ -9,7 +9,7 @@ def to_json(obj):
9
9
  Serialise to JSON
10
10
 
11
11
  """
12
- json_str = json.dumps(obj, indent=ToolsConfig.SERIALIZATION_INDENT, ensure_ascii=False)
12
+ json_str = json.dumps(obj, indent=Constants.SERIALIZATION_INDENT, ensure_ascii=False)
13
13
  return json_str
14
14
 
15
15
 
@@ -2,7 +2,7 @@ import logging
2
2
  import os
3
3
 
4
4
  from fmtr.tools import environment_tools
5
- from fmtr.tools.config import ToolsConfig
5
+ from fmtr.tools.constants import Constants
6
6
 
7
7
  DEVELOPMENT = "development"
8
8
  PRODUCTION = "production"
@@ -12,7 +12,7 @@ ENVIRONMENT_DEFAULT = DEVELOPMENT
12
12
  LEVEL_DEFAULT = logging.DEBUG if environment_tools.IS_DEBUG else logging.INFO
13
13
 
14
14
 
15
- def get_logger(name, version=None, host=ToolsConfig.FMTR_OBS_HOST, key=None, org=ToolsConfig.ORG_NAME,
15
+ def get_logger(name, version=None, host=Constants.FMTR_OBS_HOST, key=None, org=Constants.ORG_NAME,
16
16
  stream=STREAM_DEFAULT,
17
17
  environment=ENVIRONMENT_DEFAULT, level=LEVEL_DEFAULT):
18
18
  """
@@ -31,7 +31,7 @@ def get_logger(name, version=None, host=ToolsConfig.FMTR_OBS_HOST, key=None, org
31
31
  return logger
32
32
 
33
33
  if key is None:
34
- key = environment_tools.get(ToolsConfig.FMTR_OBS_API_KEY_KEY)
34
+ key = environment_tools.get(Constants.FMTR_OBS_API_KEY_KEY)
35
35
  url = f"https://{host}/api/{org}/v1/traces"
36
36
  headers = f"Authorization=Basic {key},stream-name={stream}"
37
37
 
@@ -57,7 +57,7 @@ def get_logger(name, version=None, host=ToolsConfig.FMTR_OBS_HOST, key=None, org
57
57
  return logger
58
58
 
59
59
 
60
- logger = get_logger(name=ToolsConfig.LIBRARY_NAME)
60
+ logger = get_logger(name=Constants.LIBRARY_NAME)
61
61
 
62
62
  if __name__ == '__main__':
63
63
  logger.info('Hello World')
@@ -6,13 +6,12 @@ from contextlib import nullcontext as NullContext
6
6
  from dask.diagnostics import ProgressBar
7
7
  from typing import List, Callable, Any, Union
8
8
 
9
- from fmtr.tools.config_tools import ConfigClass
10
9
  from fmtr.tools.iterator_tools import dict_records_to_lists
11
10
  from fmtr.tools.logging_tools import logger
12
11
  from fmtr.tools.path_tools import Path
13
12
 
14
13
 
15
- class ParallelConfig(ConfigClass):
14
+ class ParallelConfig:
16
15
  """
17
16
 
18
17
  Configuration values.
@@ -1,11 +1,10 @@
1
1
  import re
2
2
  import subprocess
3
- from inspect import stack
4
3
  from pathlib import Path
5
4
  from tempfile import gettempdir
6
5
  from typing import Union, Any
7
6
 
8
- from fmtr.tools.config import ToolsConfig
7
+ from fmtr.tools.constants import Constants
9
8
  from fmtr.tools.platform_tools import is_wsl
10
9
 
11
10
  WIN_PATH_PATTERN = r'''([a-z]:(\\|$)|\\\\)'''
@@ -72,8 +71,8 @@ class Path(type(Path())):
72
71
  Get path to originating module (e.g. directory containing .py file).
73
72
 
74
73
  """
75
- frame_called = stack()[1]
76
- path = cls(frame_called.filename).absolute().parent
74
+ from fmtr.tools.inspection_tools import get_call_path
75
+ path = get_call_path(offset=2).absolute().parent
77
76
  return path
78
77
 
79
78
  @classmethod
@@ -83,8 +82,8 @@ class Path(type(Path())):
83
82
  Get path to originating module (i.e. .py file).
84
83
 
85
84
  """
86
- frame_called = stack()[1]
87
- path = cls(frame_called.filename).absolute()
85
+ from fmtr.tools.inspection_tools import get_call_path
86
+ path = get_call_path(offset=2).absolute()
88
87
  return path
89
88
 
90
89
  @classmethod
@@ -96,29 +95,6 @@ class Path(type(Path())):
96
95
  """
97
96
  return cls(gettempdir())
98
97
 
99
- @classmethod
100
- def data(cls, name='data') -> 'Path':
101
- """
102
-
103
- Fetch canonical "data"/"artifacts" path, whether calling package is regular or namespace package.
104
-
105
- """
106
- from fmtr.tools.inspection_tools import get_call_path
107
- path = get_call_path()
108
- path = path.absolute().parent.parent
109
-
110
- path /= name
111
-
112
- if path.exists():
113
- return path
114
-
115
- path = path.parent.parent / name
116
-
117
- if path.exists():
118
- return path
119
-
120
- raise FileNotFoundError(f'No "{name}" directory found at "{path}"')
121
-
122
98
  def write_json(self, obj) -> int:
123
99
  """
124
100
 
@@ -127,7 +103,7 @@ class Path(type(Path())):
127
103
  """
128
104
  from fmtr.tools import json
129
105
  json_str = json.to_json(obj)
130
- return self.write_text(json_str, encoding=ToolsConfig.ENCODING)
106
+ return self.write_text(json_str, encoding=Constants.ENCODING)
131
107
 
132
108
  def read_json(self) -> Any:
133
109
  """
@@ -136,7 +112,7 @@ class Path(type(Path())):
136
112
 
137
113
  """
138
114
  from fmtr.tools import json
139
- json_str = self.read_text(encoding=ToolsConfig.ENCODING)
115
+ json_str = self.read_text(encoding=Constants.ENCODING)
140
116
  obj = json.from_json(json_str)
141
117
  return obj
142
118
 
@@ -148,7 +124,7 @@ class Path(type(Path())):
148
124
  """
149
125
  from fmtr.tools import yaml
150
126
  yaml_str = yaml.to_yaml(obj)
151
- return self.write_text(yaml_str, encoding=ToolsConfig.ENCODING)
127
+ return self.write_text(yaml_str, encoding=Constants.ENCODING)
152
128
 
153
129
  def read_yaml(self) -> Any:
154
130
  """
@@ -157,7 +133,7 @@ class Path(type(Path())):
157
133
 
158
134
  """
159
135
  from fmtr.tools import yaml
160
- yaml_str = self.read_text(encoding=ToolsConfig.ENCODING)
136
+ yaml_str = self.read_text(encoding=Constants.ENCODING)
161
137
  obj = yaml.from_yaml(yaml_str)
162
138
  return obj
163
139
 
@@ -170,3 +146,107 @@ class Path(type(Path())):
170
146
  return self.mkdir(parents=True, exist_ok=True)
171
147
 
172
148
 
149
+ class PackagePaths:
150
+ """
151
+
152
+ Canonical paths for a package.
153
+
154
+ """
155
+
156
+ FILENAME_CONFIG = 'settings.yaml'
157
+ DIR_NAME_ARTIFACTS = 'artifacts'
158
+ FILENAME_VERSION = 'version'
159
+
160
+ def __init__(self, path=None, org_singleton=None, dir_name_artifacts=DIR_NAME_ARTIFACTS, filename_config=FILENAME_CONFIG, file_version=FILENAME_VERSION):
161
+
162
+ """
163
+
164
+ Use calling module path as default path, if not otherwise specified.
165
+
166
+ """
167
+ if not path:
168
+ from fmtr.tools.inspection_tools import get_call_path
169
+ path = get_call_path(offset=2).parent
170
+
171
+ self.path = Path(path)
172
+ self.org_singleton = org_singleton
173
+ self.dir_name_artifacts = dir_name_artifacts
174
+ self.filename_config = filename_config
175
+ self.filename_version = file_version
176
+
177
+ @property
178
+ def is_namespace(self) -> bool:
179
+ """
180
+
181
+ If organization is not hard-specified, then the package is a namespace.
182
+
183
+ """
184
+ return not bool(self.org_singleton)
185
+
186
+ @property
187
+ def name(self) -> str:
188
+ """
189
+
190
+ Name of package.
191
+
192
+ """
193
+ return self.path.stem
194
+
195
+ @property
196
+ def org(self) -> str:
197
+ """
198
+
199
+ Name of organization.
200
+
201
+ """
202
+ if not self.is_namespace:
203
+ return self.org_singleton
204
+ else:
205
+ return self.path.parent.stem
206
+
207
+ @property
208
+ def repo(self) -> Path:
209
+ """
210
+
211
+ Path of repo (i.e. parent of package base directory).
212
+
213
+ """
214
+ if self.is_namespace:
215
+ return self.path.parent.parent
216
+ else:
217
+ return self.path.parent
218
+
219
+ @property
220
+ def version(self) -> Path:
221
+ """
222
+
223
+ Path of version file.
224
+
225
+ """
226
+ return self.path / self.filename_version
227
+
228
+ @property
229
+ def artifacts(self) -> Path:
230
+ """
231
+
232
+ Path of artifacts directory.
233
+
234
+ """
235
+ return self.repo / self.dir_name_artifacts
236
+
237
+ @property
238
+ def settings(self) -> Path:
239
+ """
240
+
241
+ Path of settings file.
242
+
243
+ """
244
+ return self.artifacts / self.filename_config
245
+
246
+ def __repr__(self) -> str:
247
+ """
248
+
249
+ Show base path in repr.
250
+
251
+ """
252
+ return f'{self.__class__.__name__}("{self.path}")'