mindtrace 0.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.
Files changed (60) hide show
  1. mindtrace-0.1.0/PKG-INFO +121 -0
  2. mindtrace-0.1.0/README.md +97 -0
  3. mindtrace-0.1.0/mindtrace/apps/mindtrace/apps/__init__.py +0 -0
  4. mindtrace-0.1.0/mindtrace/automation/mindtrace/automation/__init__.py +0 -0
  5. mindtrace-0.1.0/mindtrace/cluster/mindtrace/cluster/__init__.py +0 -0
  6. mindtrace-0.1.0/mindtrace/core/mindtrace/core/__init__.py +34 -0
  7. mindtrace-0.1.0/mindtrace/core/mindtrace/core/base/__init__.py +7 -0
  8. mindtrace-0.1.0/mindtrace/core/mindtrace/core/base/mindtrace_base.py +374 -0
  9. mindtrace-0.1.0/mindtrace/core/mindtrace/core/config/__init__.py +3 -0
  10. mindtrace-0.1.0/mindtrace/core/mindtrace/core/config/config.py +27 -0
  11. mindtrace-0.1.0/mindtrace/core/mindtrace/core/logging/__init__.py +3 -0
  12. mindtrace-0.1.0/mindtrace/core/mindtrace/core/logging/logger.py +112 -0
  13. mindtrace-0.1.0/mindtrace/core/mindtrace/core/observables/context_listener.py +73 -0
  14. mindtrace-0.1.0/mindtrace/core/mindtrace/core/observables/event_bus.py +72 -0
  15. mindtrace-0.1.0/mindtrace/core/mindtrace/core/observables/observable_context.py +140 -0
  16. mindtrace-0.1.0/mindtrace/core/mindtrace/core/types/task_schema.py +11 -0
  17. mindtrace-0.1.0/mindtrace/core/mindtrace/core/utils/__init__.py +12 -0
  18. mindtrace-0.1.0/mindtrace/core/mindtrace/core/utils/checks.py +39 -0
  19. mindtrace-0.1.0/mindtrace/core/mindtrace/core/utils/dynamic.py +57 -0
  20. mindtrace-0.1.0/mindtrace/core/mindtrace/core/utils/lambdas.py +35 -0
  21. mindtrace-0.1.0/mindtrace/core/mindtrace/core/utils/timers.py +291 -0
  22. mindtrace-0.1.0/mindtrace/database/mindtrace/database/__init__.py +13 -0
  23. mindtrace-0.1.0/mindtrace/database/mindtrace/database/backends/local_odm_backend.py +23 -0
  24. mindtrace-0.1.0/mindtrace/database/mindtrace/database/backends/mindtrace_odm_backend.py +27 -0
  25. mindtrace-0.1.0/mindtrace/database/mindtrace/database/backends/mongo_odm_backend.py +20 -0
  26. mindtrace-0.1.0/mindtrace/database/mindtrace/database/backends/redis_odm_backend.py +20 -0
  27. mindtrace-0.1.0/mindtrace/database/mindtrace/database/core/mindtrace_odm.py +24 -0
  28. mindtrace-0.1.0/mindtrace/datalake/mindtrace/datalake/__init__.py +0 -0
  29. mindtrace-0.1.0/mindtrace/hardware/mindtrace/hardware/__init__.py +0 -0
  30. mindtrace-0.1.0/mindtrace/jobs/mindtrace/jobs/__init__.py +0 -0
  31. mindtrace-0.1.0/mindtrace/models/mindtrace/models/__init__.py +0 -0
  32. mindtrace-0.1.0/mindtrace/registry/mindtrace/registry/__init__.py +18 -0
  33. mindtrace-0.1.0/mindtrace/registry/mindtrace/registry/archivers/config_archiver.py +26 -0
  34. mindtrace-0.1.0/mindtrace/registry/mindtrace/registry/backends/__init__.py +0 -0
  35. mindtrace-0.1.0/mindtrace/registry/mindtrace/registry/backends/gcp_registry_backend.py +24 -0
  36. mindtrace-0.1.0/mindtrace/registry/mindtrace/registry/backends/local_registry_backend.py +548 -0
  37. mindtrace-0.1.0/mindtrace/registry/mindtrace/registry/backends/minio_registry_backend.py +647 -0
  38. mindtrace-0.1.0/mindtrace/registry/mindtrace/registry/backends/registry_backend.py +233 -0
  39. mindtrace-0.1.0/mindtrace/registry/mindtrace/registry/core/__init__.py +0 -0
  40. mindtrace-0.1.0/mindtrace/registry/mindtrace/registry/core/archiver.py +33 -0
  41. mindtrace-0.1.0/mindtrace/registry/mindtrace/registry/core/registry.py +1032 -0
  42. mindtrace-0.1.0/mindtrace/services/mindtrace/services/__init__.py +27 -0
  43. mindtrace-0.1.0/mindtrace/services/mindtrace/services/core/__init__.py +0 -0
  44. mindtrace-0.1.0/mindtrace/services/mindtrace/services/core/connection_manager.py +140 -0
  45. mindtrace-0.1.0/mindtrace/services/mindtrace/services/core/launcher.py +72 -0
  46. mindtrace-0.1.0/mindtrace/services/mindtrace/services/core/service.py +456 -0
  47. mindtrace-0.1.0/mindtrace/services/mindtrace/services/core/types.py +104 -0
  48. mindtrace-0.1.0/mindtrace/services/mindtrace/services/core/utils.py +187 -0
  49. mindtrace-0.1.0/mindtrace/services/mindtrace/services/sample/echo_service.py +35 -0
  50. mindtrace-0.1.0/mindtrace/storage/mindtrace/storage/__init__.py +3 -0
  51. mindtrace-0.1.0/mindtrace/storage/mindtrace/storage/base.py +286 -0
  52. mindtrace-0.1.0/mindtrace/storage/mindtrace/storage/gcs.py +196 -0
  53. mindtrace-0.1.0/mindtrace/ui/mindtrace/ui/__init__.py +0 -0
  54. mindtrace-0.1.0/mindtrace.egg-info/PKG-INFO +121 -0
  55. mindtrace-0.1.0/mindtrace.egg-info/SOURCES.txt +58 -0
  56. mindtrace-0.1.0/mindtrace.egg-info/dependency_links.txt +1 -0
  57. mindtrace-0.1.0/mindtrace.egg-info/requires.txt +13 -0
  58. mindtrace-0.1.0/mindtrace.egg-info/top_level.txt +1 -0
  59. mindtrace-0.1.0/pyproject.toml +178 -0
  60. mindtrace-0.1.0/setup.cfg +4 -0
@@ -0,0 +1,121 @@
1
+ Metadata-Version: 2.4
2
+ Name: mindtrace
3
+ Version: 0.1.0
4
+ Summary: Mindtrace monorepo with modular packages
5
+ Author: Mindtrace Team
6
+ License-Expression: Apache-2.0
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: Programming Language :: Python :: 3.12
9
+ Requires-Python: >=3.12
10
+ Description-Content-Type: text/markdown
11
+ Requires-Dist: mindtrace-core>=0.1.0
12
+ Requires-Dist: mindtrace-jobs>=0.1.0
13
+ Requires-Dist: mindtrace-registry>=0.1.0
14
+ Requires-Dist: mindtrace-database>=0.1.0
15
+ Requires-Dist: mindtrace-services>=0.1.0
16
+ Requires-Dist: mindtrace-hardware>=0.1.0
17
+ Requires-Dist: mindtrace-cluster>=0.1.0
18
+ Requires-Dist: mindtrace-models>=0.1.0
19
+ Requires-Dist: mindtrace-automation>=0.1.0
20
+ Requires-Dist: mindtrace-apps>=0.1.0
21
+ Requires-Dist: mindtrace-ui>=0.1.0
22
+ Requires-Dist: mindtrace-datalake>=0.1.0
23
+ Requires-Dist: mindtrace-storage>=0.1.0
24
+
25
+ # Mindtrace Module Dependency Structure
26
+
27
+ Mindtrace is organized into a layered workspace to support ML components as Python modules with clearly defined boundaries and dependencies.
28
+
29
+ ---
30
+
31
+ ## 📐 Layered Architecture
32
+
33
+ We use a level-based system for organizing modules based on dependency direction and build order.
34
+
35
+ ### **Level 1: Core**
36
+ - `core`: Foundational utilities and base classes used across all other modules.
37
+
38
+ ### **Level 2: Core Consumers**
39
+ - `jobs`: Job execution and backend interfaces.
40
+ - `registry`: Artifact and metadata management.
41
+ - `database`: Redis, Mongo, and DB access layers.
42
+ - `services`: Service base classes, authentication, and gateways.
43
+ - `ui`: Optional UI libraries and components.
44
+
45
+ ### **Level 3: Infrastructure Modules**
46
+ - `hardware`: Interfaces for cameras, PLCs, scanners, etc.
47
+ - `cluster`: Runtime cluster management, nodes, and workers.
48
+ - `datalake`: Dataset interfaces for HuggingFace and Mindtrace datasets.
49
+ - `models`: Core model definitions and leaderboard utilities.
50
+
51
+ ### **Level 4: Automation**
52
+ - `automation`: Integration of pipelines and orchestration using level 2–3 modules.
53
+
54
+ ### **Level 5: Applications**
55
+ - `apps`: End-user applications composed of all previous levels.
56
+ - E.g., Demo pipelines
57
+
58
+ ---
59
+
60
+ ## 🔄 Dependency Flow
61
+
62
+ Each layer only depends on modules in lower levels.
63
+
64
+ | Module | Depends On |
65
+ |------------|------------------------------------------------------|
66
+ | `core` | – |
67
+ | `jobs` | `core`, `services` |
68
+ | `registry` | `core` |
69
+ | `database` | `core` |
70
+ | `services` | `core` |
71
+ | `ui` | `core` |
72
+ | `cluster` | `jobs`, `registry`, `database`, `services` |
73
+ | `datalake` | `registry`, `database`, `services` |
74
+ | `models` | `registry`, `services` |
75
+ | `automation` | `jobs`, `registry`, `database`, `services`, `datalake`, `models`, `cluster` |
76
+ | `apps` | Everything |
77
+
78
+ ---
79
+
80
+
81
+ ## 🛠️ Build
82
+
83
+ Building wheels and source distributions, from the root of the repo:
84
+ ```bash
85
+ uv build --all-packages
86
+ ls dist/
87
+ ```
88
+ For building only wheels:
89
+ ```bash
90
+ uv build --all-packages --wheel
91
+ ls dist/
92
+ ```
93
+ They may then be installed in a new venv (the entire `mindtrace` package or any submodule `mindtrace-core`) via:
94
+ ```bash
95
+ uv pip install mindtrace --find-links /path/to/dist
96
+ # or
97
+ uv pip install /path/to/dist/mindtrace.whl
98
+ ```
99
+ Note: You may need to use `uv pip install --force-reinstall` in case you encounter `ModuleNotFoundError`.
100
+ Checking the installation:
101
+ ```bash
102
+ uv run python -c "from mindtrace.core import Mindtrace; print('OK')"
103
+ ```
104
+
105
+
106
+ ## 🛠️ Usage Examples
107
+
108
+ Installing the full Mindtrace package:
109
+ ```bash
110
+ uv add mindtrace
111
+ ```
112
+ Installing a minimal dependency chain (e.g., for Datalake development):
113
+ ```bash
114
+ uv add mindtrace-datalake
115
+ ```
116
+ Python Imports
117
+ ```python
118
+ from mindtrace import core, registry, database, services
119
+ ```
120
+
121
+
@@ -0,0 +1,97 @@
1
+ # Mindtrace Module Dependency Structure
2
+
3
+ Mindtrace is organized into a layered workspace to support ML components as Python modules with clearly defined boundaries and dependencies.
4
+
5
+ ---
6
+
7
+ ## 📐 Layered Architecture
8
+
9
+ We use a level-based system for organizing modules based on dependency direction and build order.
10
+
11
+ ### **Level 1: Core**
12
+ - `core`: Foundational utilities and base classes used across all other modules.
13
+
14
+ ### **Level 2: Core Consumers**
15
+ - `jobs`: Job execution and backend interfaces.
16
+ - `registry`: Artifact and metadata management.
17
+ - `database`: Redis, Mongo, and DB access layers.
18
+ - `services`: Service base classes, authentication, and gateways.
19
+ - `ui`: Optional UI libraries and components.
20
+
21
+ ### **Level 3: Infrastructure Modules**
22
+ - `hardware`: Interfaces for cameras, PLCs, scanners, etc.
23
+ - `cluster`: Runtime cluster management, nodes, and workers.
24
+ - `datalake`: Dataset interfaces for HuggingFace and Mindtrace datasets.
25
+ - `models`: Core model definitions and leaderboard utilities.
26
+
27
+ ### **Level 4: Automation**
28
+ - `automation`: Integration of pipelines and orchestration using level 2–3 modules.
29
+
30
+ ### **Level 5: Applications**
31
+ - `apps`: End-user applications composed of all previous levels.
32
+ - E.g., Demo pipelines
33
+
34
+ ---
35
+
36
+ ## 🔄 Dependency Flow
37
+
38
+ Each layer only depends on modules in lower levels.
39
+
40
+ | Module | Depends On |
41
+ |------------|------------------------------------------------------|
42
+ | `core` | – |
43
+ | `jobs` | `core`, `services` |
44
+ | `registry` | `core` |
45
+ | `database` | `core` |
46
+ | `services` | `core` |
47
+ | `ui` | `core` |
48
+ | `cluster` | `jobs`, `registry`, `database`, `services` |
49
+ | `datalake` | `registry`, `database`, `services` |
50
+ | `models` | `registry`, `services` |
51
+ | `automation` | `jobs`, `registry`, `database`, `services`, `datalake`, `models`, `cluster` |
52
+ | `apps` | Everything |
53
+
54
+ ---
55
+
56
+
57
+ ## 🛠️ Build
58
+
59
+ Building wheels and source distributions, from the root of the repo:
60
+ ```bash
61
+ uv build --all-packages
62
+ ls dist/
63
+ ```
64
+ For building only wheels:
65
+ ```bash
66
+ uv build --all-packages --wheel
67
+ ls dist/
68
+ ```
69
+ They may then be installed in a new venv (the entire `mindtrace` package or any submodule `mindtrace-core`) via:
70
+ ```bash
71
+ uv pip install mindtrace --find-links /path/to/dist
72
+ # or
73
+ uv pip install /path/to/dist/mindtrace.whl
74
+ ```
75
+ Note: You may need to use `uv pip install --force-reinstall` in case you encounter `ModuleNotFoundError`.
76
+ Checking the installation:
77
+ ```bash
78
+ uv run python -c "from mindtrace.core import Mindtrace; print('OK')"
79
+ ```
80
+
81
+
82
+ ## 🛠️ Usage Examples
83
+
84
+ Installing the full Mindtrace package:
85
+ ```bash
86
+ uv add mindtrace
87
+ ```
88
+ Installing a minimal dependency chain (e.g., for Datalake development):
89
+ ```bash
90
+ uv add mindtrace-datalake
91
+ ```
92
+ Python Imports
93
+ ```python
94
+ from mindtrace import core, registry, database, services
95
+ ```
96
+
97
+
@@ -0,0 +1,34 @@
1
+ from mindtrace.core.base import Mindtrace, MindtraceABC, MindtraceMeta
2
+ from mindtrace.core.config import Config
3
+ from mindtrace.core.logging.logger import setup_logger
4
+ from mindtrace.core.observables.context_listener import ContextListener
5
+ from mindtrace.core.observables.event_bus import EventBus
6
+ from mindtrace.core.observables.observable_context import ObservableContext
7
+ from mindtrace.core.types.task_schema import TaskSchema
8
+ from mindtrace.core.utils.checks import check_libs, first_not_none, ifnone, ifnone_url
9
+ from mindtrace.core.utils.dynamic import get_class, instantiate_target
10
+ from mindtrace.core.utils.lambdas import named_lambda
11
+ from mindtrace.core.utils.timers import Timeout, Timer, TimerCollection
12
+
13
+ setup_logger() # Initialize the default logger
14
+
15
+ __all__ = [
16
+ "check_libs",
17
+ "ContextListener",
18
+ "Config",
19
+ "EventBus",
20
+ "first_not_none",
21
+ "get_class",
22
+ "ifnone",
23
+ "ifnone_url",
24
+ "instantiate_target",
25
+ "Mindtrace",
26
+ "MindtraceABC",
27
+ "MindtraceMeta",
28
+ "named_lambda",
29
+ "ObservableContext",
30
+ "TaskSchema",
31
+ "Timer",
32
+ "TimerCollection",
33
+ "Timeout",
34
+ ]
@@ -0,0 +1,7 @@
1
+ from mindtrace.core.base.mindtrace_base import Mindtrace, MindtraceABC, MindtraceMeta
2
+
3
+ __all__ = [
4
+ "Mindtrace",
5
+ "MindtraceABC",
6
+ "MindtraceMeta",
7
+ ]
@@ -0,0 +1,374 @@
1
+ """Mindtrace class. Provides unified configuration, logging and context management."""
2
+
3
+ import inspect
4
+ import logging
5
+ import traceback
6
+ from abc import ABC, ABCMeta
7
+ from functools import wraps
8
+ from typing import Callable, Optional
9
+
10
+ from mindtrace.core.config import Config
11
+ from mindtrace.core.logging.logger import get_logger
12
+ from mindtrace.core.utils import ifnone
13
+
14
+
15
+ class MindtraceMeta(type):
16
+ """Metaclass for Mindtrace class.
17
+
18
+ The MindtraceMeta metaclass enables classes deriving from Mindtrace to automatically use the same default logger within
19
+ class methods as it does within instance methods. I.e. consider the following class:
20
+
21
+ Example, logging in both class methods and instance methods::
22
+
23
+ from mindtrace.core import Mindtrace
24
+
25
+ class MyClass(Mindtrace):
26
+ def __init__(self):
27
+ super().__init__()
28
+
29
+ def instance_method(self):
30
+ self.logger.info(f"Using logger: {self.logger.name}") # Using logger: mindtrace.my_module.MyClass
31
+
32
+ @classmethod
33
+ def class_method(cls):
34
+ cls.logger.info(f"Using logger: {cls.logger.name}") # Using logger: mindtrace.my_module.MyClass
35
+ """
36
+
37
+ def __init__(cls, name, bases, attr_dict):
38
+ super().__init__(name, bases, attr_dict)
39
+ cls._logger = None
40
+
41
+ @property
42
+ def logger(cls):
43
+ if cls._logger is None:
44
+ cls._logger = get_logger(cls.unique_name)
45
+ return cls._logger
46
+
47
+ @logger.setter
48
+ def logger(cls, new_logger):
49
+ cls._logger = new_logger
50
+
51
+ @property
52
+ def unique_name(self) -> str:
53
+ return self.__module__ + "." + self.__name__
54
+
55
+
56
+ class Mindtrace(metaclass=MindtraceMeta):
57
+ """Base class for all Mindtrace package core classes.
58
+
59
+ The Mindtrace class adds default context manager and logging methods. All classes that derive from Mindtrace can be
60
+ used as context managers and will use a unified logging format.
61
+
62
+ The class automatically provides logging capabilities for both class methods and instance methods.
63
+ For example:
64
+
65
+ .. code-block:: python
66
+
67
+ from mindtrace.core import Mindtrace
68
+
69
+ class MyClass(Mindtrace):
70
+ def __init__(self):
71
+ super().__init__()
72
+
73
+ def instance_method(self):
74
+ self.logger.info(f"Using logger: {self.logger.name}") # Using logger: mindtrace.my_module.MyClass
75
+
76
+ @classmethod
77
+ def class_method(cls):
78
+ cls.logger.info(f"Using logger: {cls.logger.name}") # Using logger: mindtrace.my_module.MyClass
79
+
80
+ The logging functionality is automatically provided through the MindtraceMeta metaclass,
81
+ which ensures consistent logging behavior across all method types.
82
+ """
83
+
84
+ config = Config()
85
+
86
+ def __init__(self, suppress: bool = False, **kwargs):
87
+ """
88
+ Initialize the Mindtrace object.
89
+
90
+ Args:
91
+ suppress (bool): Whether to suppress exceptions in context manager use.
92
+ **kwargs: Additional keyword arguments. Logger-related kwargs are passed to `get_logger`.
93
+ Valid logger kwargs: log_dir, logger_level, stream_level, file_level,
94
+ file_mode, propagate, max_bytes, backup_count
95
+ """
96
+ # Initialize parent classes first (cooperative inheritance)
97
+ try:
98
+ super().__init__(**kwargs)
99
+ except TypeError:
100
+ # If parent classes don't accept some kwargs, try without logger-specific ones
101
+ logger_param_names = {
102
+ "log_dir",
103
+ "logger_level",
104
+ "stream_level",
105
+ "file_level",
106
+ "file_mode",
107
+ "propagate",
108
+ "max_bytes",
109
+ "backup_count",
110
+ }
111
+ remaining_kwargs = {k: v for k, v in kwargs.items() if k not in logger_param_names}
112
+ try:
113
+ super().__init__(**remaining_kwargs)
114
+ except TypeError:
115
+ # If that still fails, try with no kwargs
116
+ super().__init__()
117
+
118
+ # Set Mindtrace-specific attributes
119
+ self.suppress = suppress
120
+
121
+ # Filter logger-specific kwargs for logger setup
122
+ logger_param_names = {
123
+ "log_dir",
124
+ "logger_level",
125
+ "stream_level",
126
+ "file_level",
127
+ "file_mode",
128
+ "propagate",
129
+ "max_bytes",
130
+ "backup_count",
131
+ }
132
+ logger_kwargs = {k: v for k, v in kwargs.items() if k in logger_param_names}
133
+
134
+ # Set up the logger
135
+ self.logger = get_logger(self.unique_name, **logger_kwargs)
136
+
137
+ @property
138
+ def unique_name(self) -> str:
139
+ return self.__module__ + "." + type(self).__name__
140
+
141
+ @property
142
+ def name(self) -> str:
143
+ return type(self).__name__
144
+
145
+ def __enter__(self):
146
+ self.logger.debug(f"Initializing {self.name} as a context manager.")
147
+ return self
148
+
149
+ def __exit__(self, exc_type, exc_val, exc_tb):
150
+ self.logger.debug(f"Exiting context manager for {self.name}.")
151
+ if exc_type is not None:
152
+ info = (exc_type, exc_val, exc_tb)
153
+ self.logger.exception("Exception occurred", exc_info=info)
154
+ return self.suppress
155
+ return False
156
+
157
+ @classmethod
158
+ def autolog(
159
+ cls,
160
+ log_level=logging.DEBUG,
161
+ prefix_formatter: Optional[Callable] = None,
162
+ suffix_formatter: Optional[Callable] = None,
163
+ exception_formatter: Optional[Callable] = None,
164
+ self: Optional["Mindtrace"] = None,
165
+ ):
166
+ """Decorator that adds logger.log calls to the decorated method before and after the method is called.
167
+
168
+ By default, the autolog decorator will log the method name, arguments and keyword arguments before the method
169
+ is called, and the method name and result after the method completes. This behavior can be modified by passing
170
+ in prefix and suffix formatters.
171
+
172
+ The autolog decorator will also catch and log all Exceptions, re-raising any exception after logging it. The
173
+ behavior for autologging exceptions can be modified by passing in an exception_formatter.
174
+
175
+ The autolog decorator expects a logger to exist at self.logger, and hence can only be used by Mindtrace
176
+ subclasses or classes that have a logger attribute.
177
+
178
+ Args:
179
+ log_level: The log_level passed to logger.log().
180
+ prefix_formatter: The formatter used to log the command before the wrapped method runs. The prefix_formatter
181
+ will be given (and must accept) three arguments, in the following order:
182
+ - function: The function being wrapped.
183
+ - args: The args passed into the function.
184
+ - kwargs: The kwargs passed into the function.
185
+ suffix_formatter: The formatter used to log the command after the wrapped method runs. The suffix_formatter
186
+ will be given (and must accept) two arguments, in the following order:
187
+ - function: The function being wrapped.
188
+ - result: The result returned from the wrapped method.
189
+ exception_formatter: The formatter used to log any errors. The exception_formatter will be given (and must
190
+ accept) three arguments, in the following order:
191
+ - function: The function being wrapped.
192
+ - error: The caught Exception.
193
+ - stack trace: The stack trace, as provided by traceback.format_exc().
194
+ self: The instance of the class that the method is being called on. Self only needs to be passed in if the
195
+ wrapped method does not have self as the first argument. Refer to the example below for more details.
196
+
197
+ Example::
198
+
199
+ from mindtrace.core import Mindtrace
200
+
201
+ class MyClass(Mindtrace):
202
+ def __init__(self):
203
+ super().__init__()
204
+
205
+ @Mindtrace.autolog()
206
+ def divide(self, arg1, arg2):
207
+ self.logger.info("We are about to divide")
208
+ result = arg1 / arg2
209
+ self.logger.info("We have divided")
210
+ return result
211
+
212
+ my_instance = MyClass()
213
+ my_instance.divide(1, 2)
214
+ my_instance.divide(1, 0)
215
+
216
+ The resulting log file should contain something similar to the following:
217
+
218
+ .. code-block:: text
219
+
220
+ MyClass - DEBUG - Calling divide with args: (1, 2) and kwargs: {}
221
+ MyClass - INFO - We are about to divide
222
+ MyClass - INFO - We have divided
223
+ MyClass - DEBUG - Finished divide with result: 0.5
224
+ MyClass - DEBUG - Calling divide with args: (1, 0) and kwargs: {}
225
+ MyClass - INFO - We are about to divide
226
+ MyClass - ERROR - division by zero
227
+ Traceback (most recent call last):
228
+ ...
229
+
230
+ If the wrapped method does not have self as the first argument, self must be passed in as an argument to the
231
+ autolog decorator.
232
+
233
+ .. code-block:: python
234
+
235
+ from fastapi import FastAPI
236
+ from mindtrace.core import Mindtrace
237
+
238
+ class MyClass(Mindtrace):
239
+ def __init__():
240
+ super().__init__()
241
+
242
+ def create_app(self):
243
+ app_ = FastAPI()
244
+
245
+ @Mindtrace.autolog(self=self) # self must be passed in as an argument as it is not captured in status()
246
+ @app_.post("/status")
247
+ def status():
248
+ return {"status": "Available"}
249
+
250
+ return app_
251
+
252
+ """
253
+ prefix_formatter = ifnone(
254
+ prefix_formatter,
255
+ default=lambda function,
256
+ args,
257
+ kwargs: f"Calling {function.__name__} with args: {args} and kwargs: {kwargs}",
258
+ )
259
+ suffix_formatter = ifnone(
260
+ suffix_formatter, default=lambda function, result: f"Finished {function.__name__} with result: {result}"
261
+ )
262
+ exception_formatter = ifnone(
263
+ exception_formatter,
264
+ default=lambda function,
265
+ e,
266
+ stack_trace: f"{function.__name__} failed to complete with the following error: {e}\n{stack_trace}",
267
+ )
268
+
269
+ def decorator(function):
270
+ is_async = inspect.iscoroutinefunction(function)
271
+
272
+ if self is None:
273
+ if is_async:
274
+
275
+ @wraps(function)
276
+ async def wrapper(self, *args, **kwargs):
277
+ self.logger.log(log_level, prefix_formatter(function, args, kwargs))
278
+ try:
279
+ result = await function(self, *args, **kwargs)
280
+ except Exception as e:
281
+ self.logger.error(exception_formatter(function, e, traceback.format_exc()))
282
+ raise
283
+ else:
284
+ self.logger.log(log_level, suffix_formatter(function, result))
285
+ return result
286
+ else:
287
+
288
+ @wraps(function)
289
+ def wrapper(self, *args, **kwargs):
290
+ self.logger.log(log_level, prefix_formatter(function, args, kwargs))
291
+ try:
292
+ result = function(self, *args, **kwargs)
293
+ except Exception as e:
294
+ self.logger.error(exception_formatter(function, e, traceback.format_exc()))
295
+ raise
296
+ else:
297
+ self.logger.log(log_level, suffix_formatter(function, result))
298
+ return result
299
+
300
+ else:
301
+ if is_async:
302
+
303
+ @wraps(function)
304
+ async def wrapper(*args, **kwargs):
305
+ self.logger.log(log_level, prefix_formatter(function, args, kwargs))
306
+ try:
307
+ result = await function(*args, **kwargs)
308
+ except Exception as e:
309
+ self.logger.error(exception_formatter(function, e, traceback.format_exc()))
310
+ raise
311
+ else:
312
+ self.logger.log(log_level, suffix_formatter(function, result))
313
+ return result
314
+ else:
315
+
316
+ @wraps(function)
317
+ def wrapper(*args, **kwargs):
318
+ self.logger.log(log_level, prefix_formatter(function, args, kwargs))
319
+ try:
320
+ result = function(*args, **kwargs)
321
+ except Exception as e:
322
+ self.logger.error(exception_formatter(function, e, traceback.format_exc()))
323
+ raise
324
+ else:
325
+ self.logger.log(log_level, suffix_formatter(function, result))
326
+ return result
327
+
328
+ return wrapper
329
+
330
+ return decorator
331
+
332
+
333
+ class MindtraceABCMeta(MindtraceMeta, ABCMeta):
334
+ """Metaclass that combines MindtraceMeta and ABC metaclasses.
335
+
336
+ This metaclass resolves metaclass conflicts when creating classes that need to be both
337
+ abstract (using ABC) and have MindtraceMeta functionality. Python only allows a class to
338
+ have one metaclass, so this combined metaclass allows classes to inherit from both
339
+ Mindtrace class and ABC simultaneously.
340
+
341
+ Without this combined metaclass, trying to create a class that inherits from both Mindtrace class
342
+ and ABC would raise a metaclass conflict error since they each have different metaclasses.
343
+ """
344
+
345
+ pass
346
+
347
+
348
+ class MindtraceABC(Mindtrace, ABC, metaclass=MindtraceABCMeta):
349
+ """Abstract base class combining Mindtrace class functionality with ABC support.
350
+
351
+ This class enables creating abstract classes that also have access to all Mindtrace features
352
+ such as logging, configuration, and context management. Use this class instead of
353
+ Mindtrace when you need to define abstract methods or properties in your class.
354
+
355
+ Example:
356
+ from mindtrace.core import MindtraceABC
357
+ from abc import abstractmethod
358
+
359
+ class MyAbstractService(MindtraceABC):
360
+ def __init__(self):
361
+ super().__init__()
362
+
363
+ @abstractmethod
364
+ def process_data(self, data):
365
+ '''Must be implemented by concrete subclasses.'''
366
+ pass
367
+
368
+ Note:
369
+ Without this class, attempting to create a class that inherits from both Mindtrace class and ABC
370
+ would fail due to metaclass conflicts. MindtraceABC resolves this by using the CombinedABCMeta.
371
+ """
372
+
373
+ def __init__(self, *args, **kwargs):
374
+ super().__init__(*args, **kwargs)
@@ -0,0 +1,3 @@
1
+ from mindtrace.core.config.config import Config
2
+
3
+ __all__ = ["Config"]
@@ -0,0 +1,27 @@
1
+ import os
2
+
3
+
4
+ class Config(dict):
5
+ """Template Config class."""
6
+
7
+ def __init__(self, **kwargs):
8
+ default_config = {
9
+ "MINDTRACE_TEMP_DIR": "~/.cache/mindtrace/temp",
10
+ "MINDTRACE_DEFAULT_REGISTRY_DIR": "~/.cache/mindtrace/registry",
11
+ "MINDTRACE_DEFAULT_HOST_URLS": {
12
+ "Service": "http://localhost:8000",
13
+ },
14
+ "MINDTRACE_MINIO_REGISTRY_URI": "~/.cache/mindtrace/minio-registry",
15
+ "MINDTRACE_MINIO_ENDPOINT": "localhost:9000",
16
+ "MINDTRACE_MINIO_ACCESS_KEY": "minioadmin",
17
+ "MINDTRACE_MINIO_SECRET_KEY": "minioadmin",
18
+ "MINDTRACE_SERVER_PIDS_DIR_PATH": "~/.cache/mindtrace/pids",
19
+ "MINDTRACE_LOGGER_DIR": "~/.cache/mindtrace/logs",
20
+ }
21
+ # Update defaults with any provided kwargs
22
+ default_config.update(kwargs)
23
+ # Expand ~ only if it is at the start of the string
24
+ for k, v in default_config.items():
25
+ if isinstance(v, str) and v.startswith("~/"):
26
+ default_config[k] = os.path.expanduser(v)
27
+ super().__init__(default_config)
@@ -0,0 +1,3 @@
1
+ from mindtrace.core.logging.logger import Logger
2
+
3
+ __all__ = ["Logger"]