rats-apps 0.1.3.dev20240723085916__py3-none-any.whl → 0.1.3.dev20240731210159__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 CHANGED
@@ -8,8 +8,6 @@ domain.
8
8
  from ._annotations import (
9
9
  autoid,
10
10
  autoid_service,
11
- config,
12
- fallback_config,
13
11
  fallback_group,
14
12
  fallback_service,
15
13
  group,
@@ -18,7 +16,6 @@ from ._annotations import (
18
16
  from ._composite_container import CompositeContainer
19
17
  from ._container import (
20
18
  AnnotatedContainer, # type: ignore[reportDeprecated]
21
- ConfigProvider,
22
19
  Container,
23
20
  DuplicateServiceError,
24
21
  ServiceNotFoundError,
@@ -26,34 +23,30 @@ from ._container import (
26
23
  container,
27
24
  )
28
25
  from ._executables import App, Executable
29
- from ._ids import ConfigId, ServiceId
26
+ from ._ids import ServiceId, T_ExecutableType
30
27
  from ._namespaces import ProviderNamespaces
31
28
  from ._plugin_container import PluginContainers
32
29
  from ._plugins import PluginRunner
33
- from ._runtimes import Runtime, T_ExecutableType
30
+ from ._runtimes import NullRuntime, Runtime
34
31
  from ._scoping import autoscope
35
- from ._simple_apps import AppServices, SimpleApplication, SimpleRuntime
32
+ from ._simple_apps import AppServices, SimpleApplication, StandardRuntime
36
33
 
37
34
  __all__ = [
38
35
  "AnnotatedContainer",
39
36
  "App",
40
37
  "CompositeContainer",
41
- "ConfigId",
42
38
  "Container",
43
39
  "DuplicateServiceError",
44
40
  "Executable",
45
41
  "PluginContainers",
46
42
  "ProviderNamespaces",
47
- "ConfigProvider",
48
43
  "ServiceProvider",
49
44
  "ServiceId",
50
45
  "ServiceNotFoundError",
51
46
  "autoid_service",
52
47
  "autoscope",
53
- "config",
54
48
  "container",
55
49
  "PluginRunner",
56
- "fallback_config",
57
50
  "fallback_group",
58
51
  "fallback_service",
59
52
  "group",
@@ -61,8 +54,9 @@ __all__ = [
61
54
  "service",
62
55
  "T_ExecutableType",
63
56
  "Runtime",
57
+ "NullRuntime",
64
58
  "AppServices",
65
- "SimpleRuntime",
66
- "SimpleRuntime",
59
+ "StandardRuntime",
60
+ "StandardRuntime",
67
61
  "SimpleApplication",
68
62
  ]
rats/apps/_annotations.py CHANGED
@@ -3,7 +3,7 @@ from typing import Any, ParamSpec
3
3
 
4
4
  from rats import annotations
5
5
 
6
- from ._ids import ConfigId, ServiceId, T_ConfigType, T_ServiceType
6
+ from ._ids import ServiceId, T_ServiceType
7
7
  from ._namespaces import ProviderNamespaces
8
8
  from ._scoping import scope_service_name
9
9
 
@@ -29,16 +29,6 @@ def group(
29
29
  return annotations.annotation(ProviderNamespaces.GROUPS, group_id)
30
30
 
31
31
 
32
- def config(
33
- config_id: ConfigId[T_ConfigType],
34
- ) -> Callable[[Callable[P, T_ConfigType]], Callable[P, T_ConfigType]]:
35
- """A service that provides simple data-structures."""
36
- return annotations.annotation(
37
- ProviderNamespaces.SERVICES,
38
- config_id,
39
- )
40
-
41
-
42
32
  def fallback_service(
43
33
  service_id: ServiceId[T_ServiceType],
44
34
  ) -> Callable[[Callable[P, T_ServiceType]], Callable[P, T_ServiceType]]:
@@ -59,16 +49,6 @@ def fallback_group(
59
49
  )
60
50
 
61
51
 
62
- def fallback_config(
63
- config_id: ConfigId[T_ConfigType],
64
- ) -> Callable[[Callable[P, T_ConfigType]], Callable[P, T_ConfigType]]:
65
- """A fallback config gets used if no config is defined."""
66
- return annotations.annotation(
67
- ProviderNamespaces.FALLBACK_SERVICES,
68
- config_id,
69
- )
70
-
71
-
72
52
  def autoid(method: Callable[..., T_ServiceType]) -> ServiceId[T_ServiceType]:
73
53
  """
74
54
  Get a service id for a method.
@@ -1,11 +1,13 @@
1
1
  from collections.abc import Iterator
2
+ from typing import final
2
3
 
3
4
  from ._container import Container
4
5
  from ._ids import ServiceId, T_ServiceType
5
6
 
6
7
 
8
+ @final
7
9
  class CompositeContainer(Container):
8
- _contailers: tuple[Container, ...]
10
+ _containers: tuple[Container, ...]
9
11
 
10
12
  def __init__(self, *containers: Container) -> None:
11
13
  self._containers = containers
rats/apps/_container.py CHANGED
@@ -8,7 +8,7 @@ from typing_extensions import deprecated
8
8
 
9
9
  from rats import annotations
10
10
 
11
- from ._ids import ServiceId, T_ServiceType, Tco_ConfigType, Tco_ServiceType
11
+ from ._ids import ServiceId, T_ServiceType, Tco_ServiceType
12
12
  from ._namespaces import ProviderNamespaces
13
13
 
14
14
  logger = logging.getLogger(__name__)
@@ -20,10 +20,10 @@ class ServiceProvider(Protocol[Tco_ServiceType]):
20
20
  """Return the service instance."""
21
21
 
22
22
 
23
- class ConfigProvider(ServiceProvider[Tco_ConfigType], Protocol[Tco_ConfigType]):
23
+ class GroupProvider(Protocol[Tco_ServiceType]):
24
24
  @abstractmethod
25
- def __call__(self) -> Tco_ConfigType:
26
- """Return the config instance."""
25
+ def __call__(self) -> Iterator[Tco_ServiceType]:
26
+ """Return the group instances."""
27
27
 
28
28
 
29
29
  class Container(Protocol):
rats/apps/_executables.py CHANGED
@@ -32,21 +32,3 @@ class App(Executable):
32
32
 
33
33
  def execute(self) -> None:
34
34
  self._callback()
35
-
36
-
37
- # class AppContainer(Container):
38
- # _container: Callable[[Container], Container]
39
- #
40
- # def __init__(self, container: Callable[[Container], Container]) -> None:
41
- # self._container = container
42
- #
43
- # def get_namespaced_group(
44
- # self,
45
- # namespace: str,
46
- # group_id: ServiceId[T_ServiceType],
47
- # ) -> Iterator[T_ServiceType]:
48
- # yield from self._load_container().get_namespaced_group(namespace, group_id)
49
- #
50
- # @cache
51
- # def _load_container(self) -> Container:
52
- # return self._container(self)
rats/apps/_ids.py CHANGED
@@ -1,17 +1,13 @@
1
- import typing
2
1
  from typing import Generic, TypeVar
3
2
 
4
3
  from typing_extensions import NamedTuple
5
4
 
5
+ from ._executables import Executable
6
+
6
7
  T_ServiceType = TypeVar("T_ServiceType")
7
- T_ConfigType = TypeVar("T_ConfigType", bound=typing.NamedTuple)
8
+ T_ExecutableType = TypeVar("T_ExecutableType", bound=Executable)
8
9
  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
@@ -7,6 +7,16 @@ 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
+
10
20
  _app: Container
11
21
  _group: str
12
22
  _names: tuple[str, ...]
rats/apps/_runtimes.py CHANGED
@@ -1,11 +1,8 @@
1
1
  from abc import abstractmethod
2
2
  from collections.abc import Callable
3
- from typing import Protocol, TypeVar
3
+ from typing import Protocol, final
4
4
 
5
- from ._executables import Executable
6
- from ._ids import ServiceId
7
-
8
- T_ExecutableType = TypeVar("T_ExecutableType", bound=Executable)
5
+ from ._ids import ServiceId, T_ExecutableType
9
6
 
10
7
 
11
8
  class Runtime(Protocol):
@@ -30,3 +27,15 @@ class Runtime(Protocol):
30
27
 
31
28
  The used ServiceId is determined by the Runtime implementation.
32
29
  """
30
+
31
+
32
+ @final
33
+ class NullRuntime(Runtime):
34
+ def execute(self, *exe_ids: ServiceId[T_ExecutableType]) -> None:
35
+ raise NotImplementedError("NullRuntime does not support execution.")
36
+
37
+ def execute_group(self, *exe_group_ids: ServiceId[T_ExecutableType]) -> None:
38
+ raise NotImplementedError("NullRuntime does not support execution.")
39
+
40
+ def execute_callable(self, *callables: Callable[[], None]) -> None:
41
+ raise NotImplementedError("NullRuntime does not support execution.")
rats/apps/_simple_apps.py CHANGED
@@ -2,7 +2,7 @@ from collections.abc import Callable, Iterable, Iterator
2
2
  from contextlib import contextmanager
3
3
  from typing import final
4
4
 
5
- from ._annotations import fallback_service
5
+ from ._annotations import fallback_service, service
6
6
  from ._composite_container import CompositeContainer
7
7
  from ._container import Container, container
8
8
  from ._executables import App, Executable
@@ -56,13 +56,14 @@ class AppServices:
56
56
  """
57
57
 
58
58
  RUNTIME = ServiceId[Runtime]("app-runtime")
59
+ STANDARD_RUNTIME = ServiceId[Runtime]("standard-runtime")
59
60
  CONTAINER = ServiceId[Container]("app-container")
60
61
  CALLABLE_EXE_CTX = ServiceId[ExecutableCallableContext]("callable-exe-ctx")
61
62
  CALLABLE_EXE = ServiceId[Executable]("callable-exe")
62
63
 
63
64
 
64
65
  @final
65
- class SimpleRuntime(Runtime):
66
+ class StandardRuntime(Runtime):
66
67
  """A simple runtime that executes sequentially and in a single thread."""
67
68
 
68
69
  _app: Container
@@ -91,9 +92,15 @@ class SimpleApplication(Runtime, Container):
91
92
  """An application without anything fancy."""
92
93
 
93
94
  _plugin_groups: Iterable[str]
95
+ _runtime_plugin: Callable[[Container], Container] | None
94
96
 
95
- def __init__(self, *plugin_groups: str) -> None:
97
+ def __init__(
98
+ self,
99
+ *plugin_groups: str,
100
+ runtime_plugin: Callable[[Container], Container] | None = None,
101
+ ) -> None:
96
102
  self._plugin_groups = plugin_groups
103
+ self._runtime_plugin = runtime_plugin
97
104
 
98
105
  def execute(self, *exe_ids: ServiceId[T_ExecutableType]) -> None:
99
106
  self._runtime().execute(*exe_ids)
@@ -108,11 +115,21 @@ class SimpleApplication(Runtime, Container):
108
115
  @fallback_service(AppServices.RUNTIME)
109
116
  def _runtime(self) -> Runtime:
110
117
  """
111
- The default runtime is an instance of SimpleRuntime.
118
+ The default runtime defers to AppServices.STANDARD_RUNTIME.
112
119
 
113
120
  Define a non-fallback service to override this default implementation.
114
121
  """
115
- return SimpleRuntime(self)
122
+ return self.get(AppServices.STANDARD_RUNTIME)
123
+
124
+ @service(AppServices.STANDARD_RUNTIME)
125
+ def _std_runtime(self) -> Runtime:
126
+ """
127
+ The standard locally executed runtime.
128
+
129
+ Regardless of the configured AppServices.RUNTIME provider, everyone has access to this
130
+ class for plugin development.
131
+ """
132
+ return StandardRuntime(self)
116
133
 
117
134
  @fallback_service(AppServices.CALLABLE_EXE)
118
135
  def _callable_exe(self) -> Executable:
@@ -139,6 +156,8 @@ class SimpleApplication(Runtime, Container):
139
156
 
140
157
  @container()
141
158
  def _plugins(self) -> Container:
142
- return CompositeContainer(
143
- *[PluginContainers(self, group) for group in self._plugin_groups],
144
- )
159
+ plugins: list[Container] = [PluginContainers(self, group) for group in self._plugin_groups]
160
+ if self._runtime_plugin:
161
+ plugins.append(self._runtime_plugin(self))
162
+
163
+ return CompositeContainer(*plugins)
rats/cli/_plugin.py CHANGED
@@ -36,7 +36,6 @@ class PluginServices:
36
36
 
37
37
  @staticmethod
38
38
  def click_command(cmd_id: apps.ServiceId[apps.Executable]) -> apps.ServiceId[click.Group]:
39
- # autowrapped!
40
39
  return cast(apps.ServiceId[click.Group], cmd_id)
41
40
 
42
41
 
rats/logs/_plugin.py CHANGED
@@ -54,7 +54,10 @@ class PluginContainer(apps.Container):
54
54
  "stream": "ext://sys.stderr",
55
55
  }
56
56
  },
57
- "root": {"level": "INFO", "handlers": ["console"]},
57
+ "loggers": {
58
+ "": {"level": "INFO", "handlers": ["console"]},
59
+ "azure": {"level": "WARNING", "handlers": ["console"]},
60
+ },
58
61
  }
59
62
  )
60
63
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: rats-apps
3
- Version: 0.1.3.dev20240723085916
3
+ Version: 0.1.3.dev20240731210159
4
4
  Summary: research analysis tools for building applications
5
5
  Home-page: https://github.com/microsoft/rats/
6
6
  License: MIT
@@ -1,29 +1,29 @@
1
1
  rats/annotations/__init__.py,sha256=wsGhRQzZrV2oJTnBAX0aGgpyT1kYT235jkP3Wb8BTRY,498
2
2
  rats/annotations/_functions.py,sha256=ziAZOqS1lojfjDjZW7qPYNJUAFuLBWtVAoPsmJqxqpE,4356
3
3
  rats/annotations/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- rats/apps/__init__.py,sha256=yvwCwhSZrPre0_SNESf0asSrabZrru9P_JteKcljemU,1611
5
- rats/apps/_annotations.py,sha256=2dvq0ZXDUMC9LK4athRzHrVlx23rGYtw4Gn0aNA9aSk,3063
6
- rats/apps/_composite_container.py,sha256=wSWVQWPin2xxIlEoSgk_D1rlc3N2gpTxQ2y9UFdqXy0,553
7
- rats/apps/_container.py,sha256=tIpU4o1nK5tQaOKZHh35qGBw6TV4uuU0k5vDY6NwS3Y,6280
8
- rats/apps/_executables.py,sha256=acwOXlWpGmLuSFr30dPzg2LU6-ae1yfOtbDRTIXLEjc,1520
9
- rats/apps/_ids.py,sha256=dxWCPMpMA_vpaTDJEKNByIBJaX97Db203XqWLhaOezo,457
4
+ rats/apps/__init__.py,sha256=z_6eujGnU6pW12xTRR1caTJzv5v8VEbt8yLmwnMBiik,1511
5
+ rats/apps/_annotations.py,sha256=6qBqjxfBBZyVMLT3COGgQ-flQL6Wkuzp_TtndD4TwmE,2458
6
+ rats/apps/_composite_container.py,sha256=s_of6NyyrjFVYWGVehyEHe9WJIPRCnbB-tyWyNF8zyc,585
7
+ rats/apps/_container.py,sha256=GTPu6qmVCy69w87kMsQcL5BJavgW9O9RxH0z0zQu3fY,6242
8
+ rats/apps/_executables.py,sha256=QJ5_UPdZPmDQ1a3cLRJDUoeUMzNMwa3ZHYhYeS3AVq4,971
9
+ rats/apps/_ids.py,sha256=T8Onrj79t8NPfBMQBk0xI6fIWDKF0m2JfFNrdtXAbWg,353
10
10
  rats/apps/_namespaces.py,sha256=THUV_Xj5PtweC23Ob-zsSpk8exC4fT-qRwjpQ6IDm0U,188
11
- rats/apps/_plugin_container.py,sha256=Vhh1IdCzpUVwRdh301sALX7DQKny7Hru-yF_GwdxVqc,1075
11
+ rats/apps/_plugin_container.py,sha256=wmaBgxmvKo82ue9CrKHRXafgik5wIXh8XkEYMfhcTjs,1530
12
12
  rats/apps/_plugins.py,sha256=mvSYQPi11wTGZpM4umoyD37Rc8CQX8nt5eAJbmLrBFM,688
13
- rats/apps/_runtimes.py,sha256=r6aRoI4rAkUh0uv3IKn-rNuwEu2MmB724rHsJpHDO74,1138
13
+ rats/apps/_runtimes.py,sha256=nQWwC-O-j0bKCEkGpBSXhdtE0-X2ACeP7zXZfqaPGqg,1545
14
14
  rats/apps/_scoping.py,sha256=EIUopw3b38CEV57kCmSKQTAnQQMcXHZ_vwtk9t0K__g,1453
15
- rats/apps/_simple_apps.py,sha256=wjrPUt2_GLnp065gKSfIgG_3aLAU9ixi9rRt2d9mIJw,4742
15
+ rats/apps/_simple_apps.py,sha256=n-3zeHY3iintZ9LN597c7zDHv3DiIdl7c8NTk0gUk1Y,5477
16
16
  rats/apps/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
17
  rats/cli/__init__.py,sha256=dMrubxMJocbl8QoI_3fKI0Dt0QHYAM5Mxh5Vj8OaX-w,664
18
18
  rats/cli/_annotations.py,sha256=0dI8hu_y754Y53Pka1-mGEgHjjVcnIOGd8l1SFx8OBY,1190
19
19
  rats/cli/_click.py,sha256=7-ClnYSW4poFr_B-Q6NT45DnMF1XL7ntUgwQqQ7q_eo,1036
20
20
  rats/cli/_executable.py,sha256=kAQ9hImv3hBaScu6e19o_BMvl7tdYJql38E76S3FjSk,580
21
- rats/cli/_plugin.py,sha256=iUf2-ScR8o5p3g-0M1qNTAb3l9Q-FIBVjT_HEskISJY,2301
21
+ rats/cli/_plugin.py,sha256=j9exzjL4sTCrGvine0rxumdfl0RPGpOFk7Ysk73aKWk,2278
22
22
  rats/cli/_plugins.py,sha256=H3-QdaICPJhCC5FkLHdXpwqe7Z0mpvsenakhNiPllC8,2739
23
23
  rats/cli/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
24
  rats/logs/__init__.py,sha256=fCn4pfpYiAcTtt5CsnUZX68CjOB3KJHxMSiYxsma4qE,183
25
- rats/logs/_plugin.py,sha256=j3hLJDcdF4DvxeZ84zdMGP4EHgfMEzZc0wBGQjvrzGc,2039
26
- rats_apps-0.1.3.dev20240723085916.dist-info/METADATA,sha256=t1LSuoY6LhzUV3xK-Vf6n00c-Es_pLZUwQ_X_nwZ9Ss,774
27
- rats_apps-0.1.3.dev20240723085916.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
28
- rats_apps-0.1.3.dev20240723085916.dist-info/entry_points.txt,sha256=9oOvf2loQr5ACWQgvuu9Q3KZIVIxKE5Aa-rLuUII5WQ,91
29
- rats_apps-0.1.3.dev20240723085916.dist-info/RECORD,,
25
+ rats/logs/_plugin.py,sha256=eAAG4ci-XS9A9ituXj9PrcI6zH-xlCqhJlUbSGC-MYM,2175
26
+ rats_apps-0.1.3.dev20240731210159.dist-info/METADATA,sha256=W1GSJ7ViMy4OiPBHH1EAMFwWJhch4vF4GBNkVO20EiM,774
27
+ rats_apps-0.1.3.dev20240731210159.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
28
+ rats_apps-0.1.3.dev20240731210159.dist-info/entry_points.txt,sha256=9oOvf2loQr5ACWQgvuu9Q3KZIVIxKE5Aa-rLuUII5WQ,91
29
+ rats_apps-0.1.3.dev20240731210159.dist-info/RECORD,,