rats-apps 0.1.3__py3-none-any.whl → 0.1.3.dev8__py3-none-any.whl
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.
- rats/apps/__init__.py +10 -33
- rats/apps/_annotations.py +136 -46
- rats/apps/_composite_container.py +1 -3
- rats/apps/_container.py +8 -104
- rats/apps/_ids.py +7 -3
- rats/apps/_plugin_container.py +2 -17
- rats/apps/_scoping.py +2 -6
- {rats_apps-0.1.3.dist-info → rats_apps-0.1.3.dev8.dist-info}/METADATA +1 -3
- rats_apps-0.1.3.dev8.dist-info/RECORD +13 -0
- rats_apps-0.1.3.dev8.dist-info/entry_points.txt +3 -0
- rats/annotations/__init__.py +0 -25
- rats/annotations/_functions.py +0 -145
- rats/annotations/py.typed +0 -0
- rats/apps/_executables.py +0 -34
- rats/apps/_plugins.py +0 -23
- rats/apps/_runtimes.py +0 -41
- rats/apps/_simple_apps.py +0 -163
- rats/cli/__init__.py +0 -22
- rats/cli/_annotations.py +0 -40
- rats/cli/_click.py +0 -38
- rats/cli/_executable.py +0 -23
- rats/cli/_plugin.py +0 -68
- rats/cli/_plugins.py +0 -81
- rats/cli/py.typed +0 -0
- rats/logs/__init__.py +0 -8
- rats/logs/_plugin.py +0 -63
- rats_apps-0.1.3.dist-info/RECORD +0 -29
- rats_apps-0.1.3.dist-info/entry_points.txt +0 -4
- {rats_apps-0.1.3.dist-info → rats_apps-0.1.3.dev8.dist-info}/WHEEL +0 -0
rats/apps/__init__.py
CHANGED
@@ -1,62 +1,39 @@
|
|
1
1
|
"""
|
2
|
-
|
2
|
+
Provides a small set of libraries to help create new applications.
|
3
3
|
|
4
4
|
Applications give you the ability to define a development experience to match your project's
|
5
5
|
domain.
|
6
6
|
"""
|
7
7
|
|
8
8
|
from ._annotations import (
|
9
|
-
|
10
|
-
|
9
|
+
AnnotatedContainer,
|
10
|
+
config,
|
11
|
+
container,
|
12
|
+
fallback_config,
|
11
13
|
fallback_group,
|
12
14
|
fallback_service,
|
13
15
|
group,
|
14
16
|
service,
|
15
17
|
)
|
16
|
-
from .
|
17
|
-
from .
|
18
|
-
AnnotatedContainer, # type: ignore[reportDeprecated]
|
19
|
-
Container,
|
20
|
-
DuplicateServiceError,
|
21
|
-
ServiceNotFoundError,
|
22
|
-
ServiceProvider,
|
23
|
-
container,
|
24
|
-
)
|
25
|
-
from ._executables import App, Executable
|
26
|
-
from ._ids import ServiceId, T_ExecutableType
|
18
|
+
from ._container import Container, DuplicateServiceError, ServiceNotFoundError
|
19
|
+
from ._ids import ConfigId, ServiceId
|
27
20
|
from ._namespaces import ProviderNamespaces
|
28
|
-
from ._plugin_container import PluginContainers
|
29
|
-
from ._plugins import PluginRunner
|
30
|
-
from ._runtimes import NullRuntime, Runtime
|
31
21
|
from ._scoping import autoscope
|
32
|
-
from ._simple_apps import AppServices, SimpleApplication, StandardRuntime
|
33
22
|
|
34
23
|
__all__ = [
|
35
24
|
"AnnotatedContainer",
|
36
|
-
"
|
37
|
-
"CompositeContainer",
|
25
|
+
"ConfigId",
|
38
26
|
"Container",
|
39
27
|
"DuplicateServiceError",
|
40
|
-
"Executable",
|
41
|
-
"PluginContainers",
|
42
28
|
"ProviderNamespaces",
|
43
|
-
"ServiceProvider",
|
44
29
|
"ServiceId",
|
45
30
|
"ServiceNotFoundError",
|
46
|
-
"autoid_service",
|
47
31
|
"autoscope",
|
32
|
+
"config",
|
48
33
|
"container",
|
49
|
-
"
|
34
|
+
"fallback_config",
|
50
35
|
"fallback_group",
|
51
36
|
"fallback_service",
|
52
37
|
"group",
|
53
|
-
"autoid",
|
54
38
|
"service",
|
55
|
-
"T_ExecutableType",
|
56
|
-
"Runtime",
|
57
|
-
"NullRuntime",
|
58
|
-
"AppServices",
|
59
|
-
"StandardRuntime",
|
60
|
-
"StandardRuntime",
|
61
|
-
"SimpleApplication",
|
62
39
|
]
|
rats/apps/_annotations.py
CHANGED
@@ -1,74 +1,164 @@
|
|
1
|
-
from collections
|
2
|
-
from
|
1
|
+
from collections import defaultdict
|
2
|
+
from collections.abc import Callable, Iterator
|
3
|
+
from functools import cache
|
4
|
+
from typing import Any, cast
|
3
5
|
|
4
|
-
from
|
6
|
+
from typing_extensions import NamedTuple
|
5
7
|
|
6
|
-
from .
|
8
|
+
from ._container import Container
|
9
|
+
from ._ids import ConfigId, ServiceId, T_ConfigType, T_ServiceType
|
7
10
|
from ._namespaces import ProviderNamespaces
|
8
|
-
from ._scoping import scope_service_name
|
9
11
|
|
10
|
-
|
12
|
+
DEFAULT_CONTAINER_GROUP = ServiceId[Container]("__default__")
|
11
13
|
|
12
14
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
class GroupAnnotations(NamedTuple):
|
16
|
+
"""
|
17
|
+
The list of service ids attached to a given function.
|
18
|
+
|
19
|
+
The `name` attribute is the name of the function, and the `namespace` attribute represents a
|
20
|
+
specific meaning for the group of services.
|
21
|
+
"""
|
22
|
+
|
23
|
+
name: str
|
24
|
+
namespace: str
|
25
|
+
groups: tuple[ServiceId[Any], ...]
|
26
|
+
|
27
|
+
|
28
|
+
class FunctionAnnotations(NamedTuple):
|
29
|
+
"""
|
30
|
+
Holds metadata about the annotated service provider.
|
31
|
+
|
32
|
+
Loosely inspired by: https://peps.python.org/pep-3107/.
|
33
|
+
"""
|
34
|
+
|
35
|
+
providers: tuple[GroupAnnotations, ...]
|
36
|
+
|
37
|
+
def group_in_namespace(
|
38
|
+
self,
|
39
|
+
namespace: str,
|
40
|
+
group_id: ServiceId[T_ServiceType],
|
41
|
+
) -> tuple[GroupAnnotations, ...]:
|
42
|
+
return tuple([x for x in self.with_namespace(namespace) if group_id in x.groups])
|
43
|
+
|
44
|
+
def with_namespace(
|
45
|
+
self,
|
46
|
+
namespace: str,
|
47
|
+
) -> tuple[GroupAnnotations, ...]:
|
48
|
+
return tuple([x for x in self.providers if x.namespace == namespace])
|
49
|
+
|
50
|
+
|
51
|
+
class FunctionAnnotationsBuilder:
|
52
|
+
_service_ids: dict[str, list[ServiceId[Any]]]
|
53
|
+
|
54
|
+
def __init__(self) -> None:
|
55
|
+
self._service_ids = defaultdict(list)
|
56
|
+
|
57
|
+
def add(self, namespace: str, service_id: ServiceId[T_ServiceType]) -> None:
|
58
|
+
self._service_ids[namespace].append(service_id)
|
59
|
+
|
60
|
+
def make(self, name: str) -> tuple[GroupAnnotations, ...]:
|
61
|
+
return tuple(
|
62
|
+
[
|
63
|
+
GroupAnnotations(name=name, namespace=namespace, groups=tuple(services))
|
64
|
+
for namespace, services in self._service_ids.items()
|
65
|
+
]
|
66
|
+
)
|
18
67
|
|
19
68
|
|
20
|
-
|
21
|
-
|
22
|
-
|
69
|
+
class AnnotatedContainer(Container):
|
70
|
+
def get_namespaced_group(
|
71
|
+
self,
|
72
|
+
namespace: str,
|
73
|
+
group_id: ServiceId[T_ServiceType],
|
74
|
+
) -> Iterator[T_ServiceType]:
|
75
|
+
annotations = _extract_class_annotations(type(self))
|
76
|
+
containers = annotations.with_namespace(ProviderNamespaces.CONTAINERS)
|
77
|
+
groups = annotations.group_in_namespace(namespace, group_id)
|
78
|
+
|
79
|
+
for annotation in groups:
|
80
|
+
yield getattr(self, annotation.name)()
|
81
|
+
|
82
|
+
for container in containers:
|
83
|
+
c = getattr(self, container.name)()
|
84
|
+
yield from c.get_namespaced_group(namespace, group_id)
|
85
|
+
|
86
|
+
|
87
|
+
def service(
|
88
|
+
service_id: ServiceId[T_ServiceType],
|
89
|
+
) -> Callable[..., Callable[..., T_ServiceType]]:
|
90
|
+
return fn_annotation_decorator(ProviderNamespaces.SERVICES, service_id)
|
23
91
|
|
24
92
|
|
25
93
|
def group(
|
26
94
|
group_id: ServiceId[T_ServiceType],
|
27
|
-
) -> Callable[
|
28
|
-
|
29
|
-
|
95
|
+
) -> Callable[..., Callable[..., T_ServiceType]]:
|
96
|
+
return fn_annotation_decorator(ProviderNamespaces.GROUPS, group_id)
|
97
|
+
|
98
|
+
|
99
|
+
def config(
|
100
|
+
config_id: ConfigId[T_ConfigType],
|
101
|
+
) -> Callable[..., Callable[..., T_ConfigType]]:
|
102
|
+
return fn_annotation_decorator(ProviderNamespaces.SERVICES, config_id)
|
30
103
|
|
31
104
|
|
32
105
|
def fallback_service(
|
33
106
|
service_id: ServiceId[T_ServiceType],
|
34
|
-
) -> Callable[
|
35
|
-
|
36
|
-
return annotations.annotation(
|
37
|
-
ProviderNamespaces.FALLBACK_SERVICES,
|
38
|
-
service_id,
|
39
|
-
)
|
107
|
+
) -> Callable[..., Callable[..., T_ServiceType]]:
|
108
|
+
return fn_annotation_decorator(ProviderNamespaces.FALLBACK_SERVICES, service_id)
|
40
109
|
|
41
110
|
|
42
111
|
def fallback_group(
|
43
112
|
group_id: ServiceId[T_ServiceType],
|
44
|
-
) -> Callable[
|
45
|
-
|
46
|
-
return annotations.annotation(
|
47
|
-
ProviderNamespaces.FALLBACK_GROUPS,
|
48
|
-
group_id,
|
49
|
-
)
|
113
|
+
) -> Callable[..., Callable[..., T_ServiceType]]:
|
114
|
+
return fn_annotation_decorator(ProviderNamespaces.FALLBACK_GROUPS, group_id)
|
50
115
|
|
51
116
|
|
52
|
-
def
|
53
|
-
|
54
|
-
|
117
|
+
def fallback_config(
|
118
|
+
config_id: ConfigId[T_ConfigType],
|
119
|
+
) -> Callable[..., Callable[..., T_ConfigType]]:
|
120
|
+
return fn_annotation_decorator(ProviderNamespaces.FALLBACK_SERVICES, config_id)
|
55
121
|
|
56
|
-
The service id is constructed from the module, class and method name. It should be identical
|
57
|
-
regardless of whether the method is bound or not, and regardless of the instance it is bound
|
58
|
-
to.
|
59
122
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
return
|
123
|
+
def container(
|
124
|
+
group_id: ServiceId[T_ServiceType] = DEFAULT_CONTAINER_GROUP,
|
125
|
+
) -> Callable[..., Callable[..., T_ServiceType]]:
|
126
|
+
return fn_annotation_decorator(ProviderNamespaces.CONTAINERS, group_id)
|
127
|
+
|
128
|
+
|
129
|
+
def fn_annotation_decorator(
|
130
|
+
namespace: str,
|
131
|
+
service_id: ServiceId[T_ServiceType],
|
132
|
+
) -> Callable[..., Callable[..., T_ServiceType]]:
|
133
|
+
def wrapper(
|
134
|
+
fn: Callable[..., T_ServiceType],
|
135
|
+
) -> Callable[..., T_ServiceType]:
|
136
|
+
_add_annotation(namespace, fn, service_id)
|
137
|
+
return cache(fn)
|
138
|
+
|
139
|
+
return wrapper
|
140
|
+
|
141
|
+
|
142
|
+
@cache
|
143
|
+
def _extract_class_annotations(cls: Any) -> FunctionAnnotations:
|
144
|
+
function_annotations: list[GroupAnnotations] = []
|
145
|
+
for method_name in dir(cls):
|
146
|
+
if method_name.startswith("_"):
|
147
|
+
continue
|
148
|
+
|
149
|
+
builder = _get_annotations_builder(getattr(cls, method_name))
|
150
|
+
function_annotations.extend(list(builder.make(method_name)))
|
151
|
+
|
152
|
+
return FunctionAnnotations(tuple(function_annotations))
|
153
|
+
|
64
154
|
|
155
|
+
def _add_annotation(namespace: str, fn: Any, service_id: ServiceId[T_ServiceType]) -> None:
|
156
|
+
builder = _get_annotations_builder(fn)
|
157
|
+
builder.add(namespace, service_id)
|
65
158
|
|
66
|
-
def _get_method_service_id_name(method: Callable[..., Any]) -> str:
|
67
|
-
tates = annotations.get_annotations(method).with_namespace(ProviderNamespaces.SERVICES)
|
68
159
|
|
69
|
-
|
70
|
-
|
160
|
+
def _get_annotations_builder(fn: Any) -> FunctionAnnotationsBuilder:
|
161
|
+
if not hasattr(fn, "__rats_service_annotations__"):
|
162
|
+
fn.__rats_service_annotations__ = FunctionAnnotationsBuilder()
|
71
163
|
|
72
|
-
|
73
|
-
class_name, method_name = method.__qualname__.rsplit(".", 1)
|
74
|
-
return scope_service_name(module_name, class_name, method_name)
|
164
|
+
return cast(FunctionAnnotationsBuilder, fn.__rats_service_annotations__)
|
@@ -1,13 +1,11 @@
|
|
1
1
|
from collections.abc import Iterator
|
2
|
-
from typing import final
|
3
2
|
|
4
3
|
from ._container import Container
|
5
4
|
from ._ids import ServiceId, T_ServiceType
|
6
5
|
|
7
6
|
|
8
|
-
@final
|
9
7
|
class CompositeContainer(Container):
|
10
|
-
|
8
|
+
_contailers: tuple[Container, ...]
|
11
9
|
|
12
10
|
def __init__(self, *containers: Container) -> None:
|
13
11
|
self._containers = containers
|
rats/apps/_container.py
CHANGED
@@ -1,18 +1,10 @@
|
|
1
|
-
import abc
|
2
|
-
import logging
|
3
1
|
from abc import abstractmethod
|
4
|
-
from collections.abc import
|
5
|
-
from typing import Generic,
|
2
|
+
from collections.abc import Iterator
|
3
|
+
from typing import Generic, Protocol
|
6
4
|
|
7
|
-
from
|
8
|
-
|
9
|
-
from rats import annotations
|
10
|
-
|
11
|
-
from ._ids import ServiceId, T_ServiceType, Tco_ServiceType
|
5
|
+
from ._ids import ServiceId, T_ServiceType, Tco_ConfigType, Tco_ServiceType
|
12
6
|
from ._namespaces import ProviderNamespaces
|
13
7
|
|
14
|
-
logger = logging.getLogger(__name__)
|
15
|
-
|
16
8
|
|
17
9
|
class ServiceProvider(Protocol[Tco_ServiceType]):
|
18
10
|
@abstractmethod
|
@@ -20,62 +12,22 @@ class ServiceProvider(Protocol[Tco_ServiceType]):
|
|
20
12
|
"""Return the service instance."""
|
21
13
|
|
22
14
|
|
23
|
-
class
|
15
|
+
class ConfigProvider(ServiceProvider[Tco_ConfigType], Protocol[Tco_ConfigType]):
|
24
16
|
@abstractmethod
|
25
|
-
def __call__(self) ->
|
26
|
-
"""Return the
|
17
|
+
def __call__(self) -> Tco_ConfigType:
|
18
|
+
"""Return the config instance."""
|
27
19
|
|
28
20
|
|
29
21
|
class Container(Protocol):
|
30
|
-
"""
|
31
|
-
Main interface for service containers.
|
32
|
-
|
33
|
-
The default methods in this protocol attempt to find service providers that have been
|
34
|
-
annotated.
|
35
|
-
|
36
|
-
Example:
|
37
|
-
.. code-block:: python
|
38
|
-
|
39
|
-
from rats import apps
|
40
|
-
|
41
|
-
|
42
|
-
class MyStorageClient:
|
43
|
-
def save(self, data: str) -> None:
|
44
|
-
print(f"Saving data: {data}")
|
45
|
-
|
46
|
-
|
47
|
-
class MyPluginServices:
|
48
|
-
STORAGE_CLIENT = ServiceId[MyStorageClient]("storage-client")
|
49
|
-
|
50
|
-
|
51
|
-
class MyPluginContainer(apps.Container):
|
52
|
-
@apps.service(MyPluginServices.STORAGE_CLIENT)
|
53
|
-
def _storage_client() -> MyStorageClient:
|
54
|
-
return MyStorageClient()
|
55
|
-
|
56
|
-
|
57
|
-
container = MyPluginContainer()
|
58
|
-
storage_client = container.get(MyPluginServices.STORAGE_CLIENT)
|
59
|
-
storage_client.save("Hello, world!")
|
60
|
-
"""
|
22
|
+
"""Main interface for service containers."""
|
61
23
|
|
62
24
|
def has(self, service_id: ServiceId[T_ServiceType]) -> bool:
|
63
|
-
"""
|
64
|
-
Check if a service is provided by this container.
|
65
|
-
|
66
|
-
Example:
|
67
|
-
.. code-block:: python
|
68
|
-
|
69
|
-
if not container.has(MyPluginServices.STORAGE_CLIENT):
|
70
|
-
print("Did you forget to configure a storage client?")
|
71
|
-
"""
|
72
25
|
try:
|
73
26
|
return self.get(service_id) is not None
|
74
27
|
except ServiceNotFoundError:
|
75
28
|
return False
|
76
29
|
|
77
30
|
def has_group(self, group_id: ServiceId[T_ServiceType]) -> bool:
|
78
|
-
"""Check if a service group has at least one provider in the container."""
|
79
31
|
try:
|
80
32
|
return next(self.get_group(group_id)) is not None
|
81
33
|
except StopIteration:
|
@@ -112,61 +64,13 @@ class Container(Protocol):
|
|
112
64
|
|
113
65
|
yield from self.get_namespaced_group(ProviderNamespaces.GROUPS, group_id)
|
114
66
|
|
67
|
+
@abstractmethod
|
115
68
|
def get_namespaced_group(
|
116
69
|
self,
|
117
70
|
namespace: str,
|
118
71
|
group_id: ServiceId[T_ServiceType],
|
119
72
|
) -> Iterator[T_ServiceType]:
|
120
73
|
"""Retrieve a service group by its id, within a given service namespace."""
|
121
|
-
tates = annotations.get_class_annotations(type(self))
|
122
|
-
containers = tates.with_namespace(ProviderNamespaces.CONTAINERS)
|
123
|
-
groups = tates.with_group(namespace, group_id)
|
124
|
-
|
125
|
-
for annotation in groups.annotations:
|
126
|
-
if not hasattr(self, f"__rats_cache_{annotation.name}"):
|
127
|
-
setattr(self, f"__rats_cache_{annotation.name}", getattr(self, annotation.name)())
|
128
|
-
|
129
|
-
yield getattr(self, f"__rats_cache_{annotation.name}")
|
130
|
-
|
131
|
-
for annotation in containers.annotations:
|
132
|
-
if not hasattr(self, f"__rats_container_cache_{annotation.name}"):
|
133
|
-
setattr(
|
134
|
-
self,
|
135
|
-
f"__rats_container_cache_{annotation.name}",
|
136
|
-
getattr(self, annotation.name)(),
|
137
|
-
)
|
138
|
-
|
139
|
-
c = getattr(self, f"__rats_container_cache_{annotation.name}")
|
140
|
-
yield from c.get_namespaced_group(namespace, group_id)
|
141
|
-
|
142
|
-
|
143
|
-
@deprecated(
|
144
|
-
" ".join(
|
145
|
-
[
|
146
|
-
"AnnotatedContainer is deprecated and will be removed in the next major release.",
|
147
|
-
"The functionality has been moved into the apps.Container protocol.",
|
148
|
-
"Please extend apps.Container directly.",
|
149
|
-
]
|
150
|
-
),
|
151
|
-
stacklevel=2,
|
152
|
-
)
|
153
|
-
class AnnotatedContainer(Container, abc.ABC):
|
154
|
-
"""
|
155
|
-
A Container implementation that extracts providers from its annotated methods.
|
156
|
-
|
157
|
-
.. deprecated:: 0.1.3
|
158
|
-
The behavior of this class has been made the default within ``Container``.
|
159
|
-
"""
|
160
|
-
|
161
|
-
|
162
|
-
DEFAULT_CONTAINER_GROUP = ServiceId[Container]("__default__")
|
163
|
-
P = ParamSpec("P")
|
164
|
-
|
165
|
-
|
166
|
-
def container(
|
167
|
-
group_id: ServiceId[T_ServiceType] = DEFAULT_CONTAINER_GROUP,
|
168
|
-
) -> Callable[[Callable[P, T_ServiceType]], Callable[P, T_ServiceType]]:
|
169
|
-
return annotations.annotation(ProviderNamespaces.CONTAINERS, group_id)
|
170
74
|
|
171
75
|
|
172
76
|
class ServiceNotFoundError(RuntimeError, Generic[T_ServiceType]):
|
rats/apps/_ids.py
CHANGED
@@ -1,13 +1,17 @@
|
|
1
|
+
import typing
|
1
2
|
from typing import Generic, TypeVar
|
2
3
|
|
3
4
|
from typing_extensions import NamedTuple
|
4
5
|
|
5
|
-
from ._executables import Executable
|
6
|
-
|
7
6
|
T_ServiceType = TypeVar("T_ServiceType")
|
8
|
-
|
7
|
+
T_ConfigType = TypeVar("T_ConfigType", bound=typing.NamedTuple)
|
9
8
|
Tco_ServiceType = TypeVar("Tco_ServiceType", covariant=True)
|
9
|
+
Tco_ConfigType = TypeVar("Tco_ConfigType", bound=NamedTuple, covariant=True)
|
10
10
|
|
11
11
|
|
12
12
|
class ServiceId(NamedTuple, Generic[T_ServiceType]):
|
13
13
|
name: str
|
14
|
+
|
15
|
+
|
16
|
+
class ConfigId(ServiceId[T_ConfigType]):
|
17
|
+
pass
|
rats/apps/_plugin_container.py
CHANGED
@@ -7,24 +7,12 @@ from ._ids import ServiceId, T_ServiceType
|
|
7
7
|
|
8
8
|
|
9
9
|
class PluginContainers(Container):
|
10
|
-
"""
|
11
|
-
A container that loads plugins using importlib.metadata.entry_points.
|
12
|
-
|
13
|
-
When looking for groups, the container loads the specified entry_points and defers the lookups
|
14
|
-
to the plugins. Plugin containers are expected to be Callable[[Container], Container] objects,
|
15
|
-
where the input container is typically the root application container.
|
16
|
-
|
17
|
-
TODO: How do we better specify the API for plugins without relying on documentation?
|
18
|
-
"""
|
19
|
-
|
20
10
|
_app: Container
|
21
11
|
_group: str
|
22
|
-
_names: tuple[str, ...]
|
23
12
|
|
24
|
-
def __init__(self, app: Container, group: str
|
13
|
+
def __init__(self, app: Container, group: str) -> None:
|
25
14
|
self._app = app
|
26
15
|
self._group = group
|
27
|
-
self._names = names
|
28
16
|
|
29
17
|
def get_namespaced_group(
|
30
18
|
self,
|
@@ -37,7 +25,4 @@ class PluginContainers(Container):
|
|
37
25
|
@cache # noqa: B019
|
38
26
|
def _load_containers(self) -> Iterable[Container]:
|
39
27
|
entries = entry_points(group=self._group)
|
40
|
-
return tuple(entry.load()(self._app) for entry in entries
|
41
|
-
|
42
|
-
def _is_enabled(self, plugin_name: str) -> bool:
|
43
|
-
return len(self._names) == 0 or plugin_name in self._names
|
28
|
+
return tuple(entry.load()(self._app) for entry in entries)
|
rats/apps/_scoping.py
CHANGED
@@ -22,7 +22,7 @@ def autoscope(cls: type[T]) -> type[T]:
|
|
22
22
|
if not isinstance(result, ServiceId):
|
23
23
|
return result
|
24
24
|
|
25
|
-
return ServiceId[Any](
|
25
|
+
return ServiceId[Any](f"{cls.__module__}:{cls.__name__}[{result.name}]")
|
26
26
|
|
27
27
|
return cast(FunctionType, wrapper)
|
28
28
|
|
@@ -37,11 +37,7 @@ def autoscope(cls: type[T]) -> type[T]:
|
|
37
37
|
if not isinstance(non_ns, ServiceId):
|
38
38
|
continue
|
39
39
|
|
40
|
-
prop = ServiceId[Any](
|
40
|
+
prop = ServiceId[Any](f"{cls.__module__}:{cls.__name__}[{non_ns.name}]")
|
41
41
|
setattr(cls, prop_name, prop)
|
42
42
|
|
43
43
|
return cls
|
44
|
-
|
45
|
-
|
46
|
-
def scope_service_name(module_name: str, cls_name: str, name: str) -> str:
|
47
|
-
return f"{module_name}:{cls_name}[{name}]"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: rats-apps
|
3
|
-
Version: 0.1.3
|
3
|
+
Version: 0.1.3.dev8
|
4
4
|
Summary: research analysis tools for building applications
|
5
5
|
Home-page: https://github.com/microsoft/rats/
|
6
6
|
License: MIT
|
@@ -11,8 +11,6 @@ Classifier: Programming Language :: Python :: 3
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.10
|
12
12
|
Classifier: Programming Language :: Python :: 3.11
|
13
13
|
Classifier: Programming Language :: Python :: 3.12
|
14
|
-
Requires-Dist: click
|
15
|
-
Requires-Dist: colorlog
|
16
14
|
Requires-Dist: typing_extensions
|
17
15
|
Project-URL: Documentation, https://microsoft.github.io/rats/
|
18
16
|
Project-URL: Repository, https://github.com/microsoft/rats/
|
@@ -0,0 +1,13 @@
|
|
1
|
+
rats/apps/__init__.py,sha256=JYVss3L2R4uxdOp4Ozfg_cHWgRvCWq79OyVZefFw9wY,858
|
2
|
+
rats/apps/_annotations.py,sha256=NGCw1JMZdPMoK_pE61iXgjeI1Xn7P5WXLt7t8zWligg,5125
|
3
|
+
rats/apps/_composite_container.py,sha256=wSWVQWPin2xxIlEoSgk_D1rlc3N2gpTxQ2y9UFdqXy0,553
|
4
|
+
rats/apps/_container.py,sha256=5uiCyxN6HS2z97XcTOFP-t72cNoB1U1sJMkMcfSfDps,3129
|
5
|
+
rats/apps/_ids.py,sha256=dxWCPMpMA_vpaTDJEKNByIBJaX97Db203XqWLhaOezo,457
|
6
|
+
rats/apps/_namespaces.py,sha256=THUV_Xj5PtweC23Ob-zsSpk8exC4fT-qRwjpQ6IDm0U,188
|
7
|
+
rats/apps/_plugin_container.py,sha256=W_xQD2btc0N2dEb3c5tXM-ZZ4A4diMpkCjbOZdlXYuI,853
|
8
|
+
rats/apps/_scoping.py,sha256=lRV1DDq-U4mr4WOQhvFjTiCQe2dKY95LNn6b0RXRjFA,1305
|
9
|
+
rats/apps/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
10
|
+
rats_apps-0.1.3.dev8.dist-info/METADATA,sha256=mZp5dVow8ScTYqG5JaKsEPzABPF-b3r55srRYgJJ9y8,716
|
11
|
+
rats_apps-0.1.3.dev8.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
12
|
+
rats_apps-0.1.3.dev8.dist-info/entry_points.txt,sha256=Vu1IgAPQvL4xMJzW_OG2JSPFac7HalCHyXiRr0-OfCI,86
|
13
|
+
rats_apps-0.1.3.dev8.dist-info/RECORD,,
|
rats/annotations/__init__.py
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
General purpose library to attach annotations to functions.
|
3
|
-
|
4
|
-
Annotations are typically, but not exclusively, attached using decorators.
|
5
|
-
"""
|
6
|
-
|
7
|
-
from ._functions import (
|
8
|
-
AnnotationsContainer,
|
9
|
-
DecoratorType,
|
10
|
-
GroupAnnotations,
|
11
|
-
T_GroupType,
|
12
|
-
annotation,
|
13
|
-
get_annotations,
|
14
|
-
get_class_annotations,
|
15
|
-
)
|
16
|
-
|
17
|
-
__all__ = [
|
18
|
-
"annotation",
|
19
|
-
"DecoratorType",
|
20
|
-
"AnnotationsContainer",
|
21
|
-
"get_annotations",
|
22
|
-
"get_class_annotations",
|
23
|
-
"GroupAnnotations",
|
24
|
-
"T_GroupType",
|
25
|
-
]
|