arkitekt-next 0.7.8__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.

Potentially problematic release.


This version of arkitekt-next might be problematic. Click here for more details.

Files changed (119) hide show
  1. arkitekt_next/__init__.py +43 -0
  2. arkitekt_next/apps/__init__.py +3 -0
  3. arkitekt_next/apps/easy.py +99 -0
  4. arkitekt_next/apps/next.py +40 -0
  5. arkitekt_next/apps/qt.py +97 -0
  6. arkitekt_next/apps/service/__init__.py +3 -0
  7. arkitekt_next/apps/service/fakts.py +88 -0
  8. arkitekt_next/apps/service/fakts_next.py +79 -0
  9. arkitekt_next/apps/service/fakts_qt.py +82 -0
  10. arkitekt_next/apps/service/fluss_next.py +31 -0
  11. arkitekt_next/apps/service/grant_registry.py +27 -0
  12. arkitekt_next/apps/service/herre.py +24 -0
  13. arkitekt_next/apps/service/herre_qt.py +57 -0
  14. arkitekt_next/apps/service/kabinet.py +31 -0
  15. arkitekt_next/apps/service/mikro_next.py +81 -0
  16. arkitekt_next/apps/service/rekuest_next.py +53 -0
  17. arkitekt_next/apps/service/unlok_next.py +32 -0
  18. arkitekt_next/apps/types.py +53 -0
  19. arkitekt_next/builders.py +264 -0
  20. arkitekt_next/cli/__init__.py +0 -0
  21. arkitekt_next/cli/commands/call/__init__.py +0 -0
  22. arkitekt_next/cli/commands/call/local.py +132 -0
  23. arkitekt_next/cli/commands/call/main.py +22 -0
  24. arkitekt_next/cli/commands/call/remote.py +90 -0
  25. arkitekt_next/cli/commands/gen/__init__.py +0 -0
  26. arkitekt_next/cli/commands/gen/compile.py +45 -0
  27. arkitekt_next/cli/commands/gen/init.py +122 -0
  28. arkitekt_next/cli/commands/gen/main.py +29 -0
  29. arkitekt_next/cli/commands/gen/watch.py +32 -0
  30. arkitekt_next/cli/commands/init/__init__.py +0 -0
  31. arkitekt_next/cli/commands/init/main.py +194 -0
  32. arkitekt_next/cli/commands/inspect/__init__.py +0 -0
  33. arkitekt_next/cli/commands/inspect/definitions.py +53 -0
  34. arkitekt_next/cli/commands/inspect/main.py +22 -0
  35. arkitekt_next/cli/commands/inspect/variables.py +92 -0
  36. arkitekt_next/cli/commands/manifest/__init__.py +0 -0
  37. arkitekt_next/cli/commands/manifest/inspect.py +42 -0
  38. arkitekt_next/cli/commands/manifest/main.py +25 -0
  39. arkitekt_next/cli/commands/manifest/scopes.py +155 -0
  40. arkitekt_next/cli/commands/manifest/version.py +147 -0
  41. arkitekt_next/cli/commands/manifest/wizard.py +94 -0
  42. arkitekt_next/cli/commands/port/__init__.py +0 -0
  43. arkitekt_next/cli/commands/port/build.py +231 -0
  44. arkitekt_next/cli/commands/port/init.py +82 -0
  45. arkitekt_next/cli/commands/port/main.py +31 -0
  46. arkitekt_next/cli/commands/port/publish.py +102 -0
  47. arkitekt_next/cli/commands/port/stage.py +59 -0
  48. arkitekt_next/cli/commands/port/utils.py +47 -0
  49. arkitekt_next/cli/commands/port/validate.py +78 -0
  50. arkitekt_next/cli/commands/port/wizard.py +329 -0
  51. arkitekt_next/cli/commands/run/__init__.py +0 -0
  52. arkitekt_next/cli/commands/run/dev.py +349 -0
  53. arkitekt_next/cli/commands/run/main.py +22 -0
  54. arkitekt_next/cli/commands/run/prod.py +57 -0
  55. arkitekt_next/cli/commands/run/utils.py +10 -0
  56. arkitekt_next/cli/commands/server/__init__.py +0 -0
  57. arkitekt_next/cli/commands/server/down.py +56 -0
  58. arkitekt_next/cli/commands/server/init.py +74 -0
  59. arkitekt_next/cli/commands/server/inspect.py +59 -0
  60. arkitekt_next/cli/commands/server/main.py +33 -0
  61. arkitekt_next/cli/commands/server/open.py +66 -0
  62. arkitekt_next/cli/commands/server/remove.py +60 -0
  63. arkitekt_next/cli/commands/server/stop.py +56 -0
  64. arkitekt_next/cli/commands/server/up.py +70 -0
  65. arkitekt_next/cli/commands/server/utils.py +33 -0
  66. arkitekt_next/cli/configs/base.yaml +867 -0
  67. arkitekt_next/cli/constants.py +63 -0
  68. arkitekt_next/cli/dockerfiles/vanilla.dockerfile +8 -0
  69. arkitekt_next/cli/errors.py +4 -0
  70. arkitekt_next/cli/inspect.py +1 -0
  71. arkitekt_next/cli/io.py +255 -0
  72. arkitekt_next/cli/main.py +83 -0
  73. arkitekt_next/cli/options.py +166 -0
  74. arkitekt_next/cli/schemas/fluss.schema.graphql +2446 -0
  75. arkitekt_next/cli/schemas/gucker.schema.graphql +8908 -0
  76. arkitekt_next/cli/schemas/kabinet.schema.graphql +515 -0
  77. arkitekt_next/cli/schemas/kluster.schema.graphql +109 -0
  78. arkitekt_next/cli/schemas/konviktion.schema.graphql +70 -0
  79. arkitekt_next/cli/schemas/kuay.schema.graphql +356 -0
  80. arkitekt_next/cli/schemas/mikro.schema.graphql +8908 -0
  81. arkitekt_next/cli/schemas/mikro_next.schema.graphql +1639 -0
  82. arkitekt_next/cli/schemas/napari.schema.graphql +8908 -0
  83. arkitekt_next/cli/schemas/omero_ark.schema.graphql +100 -0
  84. arkitekt_next/cli/schemas/port.schema.graphql +356 -0
  85. arkitekt_next/cli/schemas/rekuest.schema.graphql +4630 -0
  86. arkitekt_next/cli/schemas/rekuest_next.schema.graphql +1159 -0
  87. arkitekt_next/cli/schemas/unlok.schema.graphql +1013 -0
  88. arkitekt_next/cli/templates/filter.py +26 -0
  89. arkitekt_next/cli/templates/simple.py +67 -0
  90. arkitekt_next/cli/texts.py +20 -0
  91. arkitekt_next/cli/types.py +365 -0
  92. arkitekt_next/cli/ui.py +111 -0
  93. arkitekt_next/cli/utils.py +15 -0
  94. arkitekt_next/cli/validators.py +17 -0
  95. arkitekt_next/cli/vars.py +39 -0
  96. arkitekt_next/cli/versions/v1.yaml +1 -0
  97. arkitekt_next/constants.py +6 -0
  98. arkitekt_next/model.py +110 -0
  99. arkitekt_next/qt/__init__.py +9 -0
  100. arkitekt_next/qt/assets/dark/gear.png +0 -0
  101. arkitekt_next/qt/assets/dark/green pulse.gif +0 -0
  102. arkitekt_next/qt/assets/dark/orange pulse.gif +0 -0
  103. arkitekt_next/qt/assets/dark/pink pulse.gif +0 -0
  104. arkitekt_next/qt/assets/dark/red pulse.gif +0 -0
  105. arkitekt_next/qt/assets/light/gear.png +0 -0
  106. arkitekt_next/qt/assets/light/green pulse.gif +0 -0
  107. arkitekt_next/qt/assets/light/orange pulse.gif +0 -0
  108. arkitekt_next/qt/assets/light/pink pulse.gif +0 -0
  109. arkitekt_next/qt/assets/light/red pulse.gif +0 -0
  110. arkitekt_next/qt/magic_bar.py +545 -0
  111. arkitekt_next/qt/utils.py +30 -0
  112. arkitekt_next/service_registry.py +51 -0
  113. arkitekt_next/tqdm.py +43 -0
  114. arkitekt_next/utils.py +38 -0
  115. arkitekt_next-0.7.8.dist-info/LICENSE +21 -0
  116. arkitekt_next-0.7.8.dist-info/METADATA +155 -0
  117. arkitekt_next-0.7.8.dist-info/RECORD +119 -0
  118. arkitekt_next-0.7.8.dist-info/WHEEL +4 -0
  119. arkitekt_next-0.7.8.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,31 @@
1
+ from kabinet.kabinet import Kabinet
2
+ from kabinet.rath import KabinetLinkComposition, KabinetRath
3
+ from rath.links.split import SplitLink
4
+ from rath.contrib.fakts.links.aiohttp import FaktsAIOHttpLink
5
+ from rath.contrib.fakts.links.graphql_ws import FaktsGraphQLWSLink
6
+ from rath.contrib.herre.links.auth import HerreAuthLink
7
+ from graphql import OperationType
8
+ from arkitekt_next_next.healthz import FaktsHealthz
9
+ from fakts import Fakts
10
+ from herre import Herre
11
+
12
+
13
+ class ArkitektNextKabinet(Kabinet):
14
+ rath: KabinetRath
15
+ healthz: FaktsHealthz
16
+
17
+
18
+ def build_arkitekt_next_kabinet(herre: Herre, fakts: Fakts):
19
+ return ArkitektNextKabinet(
20
+ rath=KabinetRath(
21
+ link=KabinetLinkComposition(
22
+ auth=HerreAuthLink(herre=herre),
23
+ split=SplitLink(
24
+ left=FaktsAIOHttpLink(fakts_group="kabinet", fakts=fakts),
25
+ right=FaktsGraphQLWSLink(fakts_group="kabinet", fakts=fakts),
26
+ split=lambda o: o.node.operation != OperationType.SUBSCRIPTION,
27
+ ),
28
+ )
29
+ ),
30
+ healthz=FaktsHealthz(fakts_group="kabinet", fakts=fakts),
31
+ )
@@ -0,0 +1,81 @@
1
+ """
2
+ This modules provides the main app. It is responsible for setting up the connection to the mikro-server and
3
+ handling authentification and setting up the configuration. Mikro handles the creation of the datalayer and
4
+ the graphql client.
5
+
6
+ You can compose this app together with other apps to create a full fledged app. (Like combining with
7
+ arkitekt_next to enable to call functions that you define on the app)
8
+
9
+ Example:
10
+
11
+ A simple app that takes it configuraiton from basic.fakts and connects to the mikro-server.
12
+ You can define all of the logic within the context manager
13
+
14
+ ```python
15
+ from mikro.app import MikroApp
16
+
17
+ app = MikroApp(fakts=Fakts(subapp="basic"))
18
+
19
+ with app:
20
+ # do stuff
21
+
22
+ ```
23
+
24
+ Async Usage:
25
+
26
+
27
+ ```python
28
+ from mikro.app import MikroApp
29
+
30
+ app = MikroApp(fakts=Fakts(subapp="basic"))
31
+
32
+ async with app:
33
+ # do stuff
34
+
35
+ ```
36
+
37
+
38
+ """
39
+
40
+
41
+ from arkitekt_next_next.healthz import FaktsHealthz
42
+ from mikro_next.mikro_next import MikroNext
43
+ from mikro_next.rath import MikroNextLinkComposition, MikroNextRath
44
+ from rath.links.split import SplitLink
45
+ from rath.contrib.fakts.links.aiohttp import FaktsAIOHttpLink
46
+ from rath.contrib.fakts.links.graphql_ws import FaktsGraphQLWSLink
47
+ from rath.contrib.herre.links.auth import HerreAuthLink
48
+ from mikro_next.contrib.fakts.datalayer import FaktsDataLayer
49
+ from mikro_next.links.upload import UploadLink
50
+ from mikro_next.datalayer import DataLayer
51
+ from graphql import OperationType
52
+ from herre import Herre
53
+ from fakts import Fakts
54
+
55
+
56
+ class ArkitektNextMikroNext(MikroNext):
57
+ rath: MikroNextRath
58
+ datalayer: DataLayer
59
+ healthz: FaktsHealthz
60
+
61
+
62
+ def build_arkitekt_next_mikro_next(herre: Herre, fakts: Fakts):
63
+ datalayer = FaktsDataLayer(fakts_group="datalayer", fakts=fakts)
64
+
65
+ return ArkitektNextMikroNext(
66
+ rath=MikroNextRath(
67
+ link=MikroNextLinkComposition(
68
+ auth=HerreAuthLink(herre=herre),
69
+ upload=UploadLink(
70
+ datalayer=datalayer,
71
+ ),
72
+ split=SplitLink(
73
+ left=FaktsAIOHttpLink(fakts_group="mikro", fakts=fakts),
74
+ right=FaktsGraphQLWSLink(fakts_group="mikro", fakts=fakts),
75
+ split=lambda o: o.node.operation != OperationType.SUBSCRIPTION,
76
+ ),
77
+ )
78
+ ),
79
+ datalayer=datalayer,
80
+ healthz=FaktsHealthz(fakts_group="mikro", fakts=fakts),
81
+ )
@@ -0,0 +1,53 @@
1
+ from arkitekt_next_next.healthz import FaktsHealthz
2
+ from rath.contrib.fakts.links.aiohttp import FaktsAIOHttpLink
3
+ from rath.links.split import SplitLink
4
+ from rath.contrib.fakts.links.graphql_ws import FaktsGraphQLWSLink
5
+ from rath.contrib.herre.links.auth import HerreAuthLink
6
+ from rekuest_next.rath import RekuestNextLinkComposition, RekuestNextRath
7
+ from rekuest_next.rekuest import RekuestNext
8
+ from graphql import OperationType
9
+ from rekuest_next.contrib.arkitekt_next.websocket_agent_transport import (
10
+ ArkitektNextWebsocketAgentTransport,
11
+ )
12
+
13
+ from rekuest_next.agents.base import BaseAgent
14
+ from fakts import Fakts
15
+ from herre import Herre
16
+ from rekuest_next.postmans.graphql import GraphQLPostman
17
+
18
+
19
+ class ArkitektNextRekuestNext(RekuestNext):
20
+ rath: RekuestNextRath
21
+ agent: BaseAgent
22
+ healthz: FaktsHealthz
23
+
24
+
25
+ def build_arkitekt_next_rekuest_next(
26
+ fakts: Fakts, herre: Herre, instance_id: str
27
+ ) -> ArkitektNextRekuestNext:
28
+ rath = RekuestNextRath(
29
+ link=RekuestNextLinkComposition(
30
+ auth=HerreAuthLink(herre=herre),
31
+ split=SplitLink(
32
+ left=FaktsAIOHttpLink(fakts_group="rekuest", fakts=fakts),
33
+ right=FaktsGraphQLWSLink(fakts_group="rekuest", fakts=fakts),
34
+ split=lambda o: o.node.operation != OperationType.SUBSCRIPTION,
35
+ ),
36
+ )
37
+ )
38
+
39
+ return ArkitektNextRekuestNext(
40
+ rath=rath,
41
+ agent=BaseAgent(
42
+ transport=ArkitektNextWebsocketAgentTransport(
43
+ fakts_group="rekuest.agent", fakts=fakts, herre=herre
44
+ ),
45
+ instance_id=instance_id,
46
+ rath=rath,
47
+ ),
48
+ postman=GraphQLPostman(
49
+ rath=rath,
50
+ instance_id=instance_id,
51
+ ),
52
+ healthz=FaktsHealthz(fakts_group="rekuest", fakts=fakts),
53
+ )
@@ -0,0 +1,32 @@
1
+ from herre import Herre
2
+ from rath.contrib.fakts.links.aiohttp import FaktsAIOHttpLink
3
+ from rath.contrib.fakts.links.graphql_ws import FaktsGraphQLWSLink
4
+ from rath.contrib.herre.links.auth import HerreAuthLink
5
+ from rath.links.split import SplitLink
6
+
7
+ from arkitekt_next_next.healthz import FaktsHealthz
8
+ from fakts import Fakts
9
+ from graphql import OperationType
10
+ from unlok_next.rath import UnlokLinkComposition, UnlokRath
11
+ from unlok_next.unlok import Unlok
12
+
13
+
14
+ class ArkitektNextUnlok(Unlok):
15
+ rath: UnlokRath
16
+ healthz: FaktsHealthz
17
+
18
+
19
+ def build_arkitekt_next_unlok_next(herre: Herre, fakts: Fakts):
20
+ return ArkitektNextUnlok(
21
+ rath=UnlokRath(
22
+ link=UnlokLinkComposition(
23
+ auth=HerreAuthLink(herre=herre),
24
+ split=SplitLink(
25
+ left=FaktsAIOHttpLink(fakts_group="lok", fakts=fakts),
26
+ right=FaktsGraphQLWSLink(fakts_group="lok", fakts=fakts),
27
+ split=lambda o: o.node.operation != OperationType.SUBSCRIPTION,
28
+ ),
29
+ )
30
+ ),
31
+ healthz=FaktsHealthz(fakts_group="lok", fakts=fakts),
32
+ )
@@ -0,0 +1,53 @@
1
+ """
2
+ This module contains the types for the apps
3
+ depending on the builder used.
4
+
5
+ This module imports all the apps and their types
6
+ and sets them as attributes on the App class, if they are available.
7
+ If they are not available, they are set to Any, so that we can add
8
+ an import exception to the app.
9
+
10
+
11
+ """
12
+
13
+ import logging
14
+ from typing import TYPE_CHECKING, Any, Dict
15
+ from arkitekt_next.model import Manifest
16
+ from koil.composition import Composition
17
+ from fakts import Fakts
18
+ from herre import Herre
19
+
20
+ logger = logging.getLogger(__name__)
21
+
22
+
23
+
24
+ class App(Composition):
25
+ """An app that is built with the easy builder"""
26
+ fakts: Fakts
27
+ herre: Herre
28
+ manifest: Manifest
29
+ services: Dict[str, Any]
30
+
31
+ def run(self):
32
+ """Run the app"""
33
+ self.services["rekuest"].run()
34
+
35
+
36
+ async def __aenter__(self):
37
+ await super().__aenter__()
38
+ print("Entering")
39
+ for service in self.services.values():
40
+ await service.__aenter__()
41
+
42
+ return self
43
+
44
+
45
+ async def __aexit__(self, exc_type, exc_value, traceback):
46
+ for service in self.services.values():
47
+ await service.__aexit__(exc_type, exc_value, traceback)
48
+
49
+
50
+
51
+
52
+
53
+
@@ -0,0 +1,264 @@
1
+ from typing import List, Optional
2
+ import logging
3
+ import os
4
+
5
+ from arkitekt_next.apps.service.fakts_next import build_arkitekt_next_fakts_next, build_arkitekt_next_redeem_fakts_next
6
+ from arkitekt_next.apps.service.herre import build_arkitekt_next_herre
7
+ from arkitekt_next.apps.service.fakts_qt import build_arkitekt_next_qt_fakts
8
+ from arkitekt_next.apps.service.herre_qt import build_arkitekt_next_qt_herre
9
+ from .utils import create_arkitekt_next_folder
10
+ from .model import Manifest
11
+ from .apps.types import App
12
+ from .service_registry import ServiceBuilderRegistry, get_default_service_builder_registry
13
+ from arkitekt_next.constants import DEFAULT_ARKITEKT_URL
14
+ from qtpy import QtWidgets, QtCore
15
+
16
+
17
+ def easy(
18
+ identifier: str,
19
+ version: str = "0.0.1",
20
+ logo: Optional[str] = None,
21
+ scopes: Optional[List[str]] = None,
22
+ url: str = DEFAULT_ARKITEKT_URL,
23
+ headless: bool = False,
24
+ log_level: str = "ERROR",
25
+ token: Optional[str] = None,
26
+ no_cache: bool = False,
27
+ redeem_token: Optional[str] = None,
28
+ app_kind: str = "development",
29
+ registry: Optional[ServiceBuilderRegistry] = None,
30
+ **kwargs,
31
+ ) -> App:
32
+ """Creates a next app
33
+
34
+ A simple way to create an ArkitektNext Next app, ArkitektNext next apps are
35
+ development apps by default, as they will try to register themselves
36
+ with services that are not yet available in production (such as the
37
+ rekuest_next and mikro_next services). They represent the next generation
38
+ of ArkitektNext apps, and will be the default way to create ArkitektNext apps
39
+ in the future. From here be dragons.
40
+
41
+ A few things to note:
42
+ - The Next builder closely mimics the easy builder, but will use the
43
+ next generation of services (such as rekuest_next and mikro_next)
44
+ and will therefore not be compatible with the current generation.
45
+
46
+ - Next apps will try to establish themselves a "development" apps, by default
47
+ which means that they will be authenticated with the ArkitektNext server on
48
+ a per user basis. If you want to create a "desktop" app, which multiple users
49
+ can use, you should set the `app_kind` to "desktop" TODO: Currently not implemented (use next app for this)
50
+ - The Next builder can also be used in plugin apps, and when provided with a fakts token
51
+ will be able to connect to the ArkitektNext server without any user interaction.
52
+
53
+
54
+ Parameters
55
+ ----------
56
+ identifier : str
57
+ The apps identifier (should be globally unique, see Manifest for more info)
58
+ version : str, optional
59
+ The version of the app, by default "0.0.1"
60
+ logo : str, optional
61
+ The logo of the app as a public http url, by default None
62
+ scopes : List[str], optional
63
+ The scopes, that this apps requires, will default to standard scopes, by default None
64
+ url : str, optional
65
+ The fakts server that will be used to configure this app, in a default ArkitektNext deployment this
66
+ is the address of the "Lok Service" (which provides the Fakts API), by default DEFAULT_ARKITEKT_URL
67
+ Will be overwritten by the FAKTS_URL environment variable
68
+ headless : bool, optional
69
+ Should we run in headless, mode, e.g printing necessary interaction into the console (will forexample
70
+ stop opening browser windows), by default False
71
+ log_level : str, optional
72
+ The log-level to use, by default "ERROR"
73
+ token : str, optional
74
+ A fakts token to use, by default None
75
+ Will be overwritten by the FAKTS_TOKEN environment variable
76
+ no_cache : bool, optional
77
+ Should we skip caching token, acess-token, by default False
78
+ Attention: If this is set to True, the app will always have to be configured
79
+ and authenticated.
80
+ instance_id : str, optional
81
+ The instance_id to use, by default "main"
82
+ Can be set to a different value, if you want to run multiple intstances
83
+ of the same app by the same user.
84
+ Will be overwritten by the REKUEST_INSTANCE_ID environment variable
85
+ register_reaktion : bool, optional
86
+ Should we register the reaktion extension, by default True
87
+ If set to False, the app will not be able to use the reaktion extension
88
+ (which is necessary for scheduling in app` workflows from fluss)
89
+ app_kind : str, optional
90
+ The kind of app to create, by default "development"
91
+ Can be set to "desktop" to create a desktop app, that can be used by multiple users.
92
+
93
+ Returns
94
+ -------
95
+ NextApp
96
+ A built app, that can be used to interact with the ArkitektNext server
97
+ """
98
+ registry = registry or get_default_service_builder_registry()
99
+
100
+
101
+ manifest = Manifest(
102
+ version=version,
103
+ identifier=identifier,
104
+ scopes=scopes if scopes else ["openid"],
105
+ logo=logo,
106
+ requirements=registry.get_requirements(),
107
+ )
108
+
109
+
110
+ if redeem_token:
111
+ fakts = build_arkitekt_next_redeem_fakts_next(
112
+ manifest=manifest,
113
+ redeem_token=redeem_token,
114
+ url=url,
115
+ no_cache=no_cache,
116
+ headless=headless,
117
+ )
118
+ else:
119
+ fakts = build_arkitekt_next_fakts_next(
120
+ manifest=manifest,
121
+ url=url,
122
+ no_cache=no_cache,
123
+ headless=headless,
124
+ client_kind=app_kind,
125
+ )
126
+
127
+ herre = build_arkitekt_next_herre(fakts=fakts)
128
+
129
+ params = kwargs
130
+
131
+
132
+
133
+ url = os.getenv("FAKTS_URL", url)
134
+ token = os.getenv("FAKTS_TOKEN", token)
135
+
136
+ create_arkitekt_next_folder(with_cache=True)
137
+
138
+
139
+
140
+ try:
141
+ from rich.logging import RichHandler
142
+
143
+ logging.basicConfig(level=log_level, handlers=[RichHandler()])
144
+ except ImportError:
145
+ logging.basicConfig(level=log_level)
146
+
147
+ print(registry.service_builders)
148
+
149
+ app = App(
150
+ fakts=fakts,
151
+ herre=herre,
152
+ manifest=manifest,
153
+ services=registry.build_service_map(fakts=fakts, herre=herre, params=params),
154
+ )
155
+
156
+ print()
157
+
158
+
159
+ return app
160
+
161
+
162
+
163
+
164
+ def publicqt(
165
+ identifier: str,
166
+ version: str = "latest",
167
+ logo: Optional[str] = None,
168
+ scopes: Optional[List[str]] = None,
169
+ url: str = "http://localhost:11000",
170
+ headless: bool = False,
171
+ log_level: str = "ERROR",
172
+ token: Optional[str] = None,
173
+ no_cache: bool = False,
174
+ instance_id: str = "main",
175
+ redeem_token: Optional[str] = None,
176
+ app_kind: str = "desktop",
177
+ registry: Optional[ServiceBuilderRegistry] = None,
178
+ parent: Optional[QtWidgets.QWidget] =None,
179
+ beacon_widget: Optional[QtWidgets.QWidget]=None,
180
+ login_widget: Optional[QtWidgets.QWidget]=None,
181
+ settings: Optional[QtCore.QSettings]=None,
182
+ **kwargs,
183
+ ) -> App:
184
+ """Public QtApp creation
185
+
186
+ A simple way to create an Arkitekt app with a public grant (allowing users to sign
187
+ in with the application ) utlizing a retrieve grant (necessating a previous configuration
188
+ of the application on the server side)
189
+
190
+ Args:
191
+ identifier (str): The apps identifier
192
+ version (str, optional): The apps verion. Defaults to "latest".
193
+ parent (QtWidget, optional): The QtParent (for the login and server select widget). Defaults to None.
194
+
195
+ Returns:
196
+ Arkitekt: The Arkitekt app
197
+ """
198
+
199
+ from arkitekt.apps.qt import build_arkitekt_qt_app
200
+
201
+ registry = registry or get_default_service_builder_registry()
202
+
203
+
204
+ manifest = Manifest(
205
+ version=version,
206
+ identifier=identifier,
207
+ scopes=scopes if scopes else ["openid"],
208
+ logo=logo,
209
+ requirements=registry.get_requirements(),
210
+ )
211
+
212
+
213
+ if redeem_token:
214
+ fakts = build_arkitekt_next_redeem_fakts_next(
215
+ manifest=manifest,
216
+ redeem_token=redeem_token,
217
+ url=url,
218
+ no_cache=no_cache,
219
+ headless=headless,
220
+ )
221
+ else:
222
+ fakts = build_arkitekt_next_qt_fakts(
223
+ manifest=manifest,
224
+ url=url,
225
+ no_cache=no_cache,
226
+ client_kind=app_kind,
227
+ beacon_widget=beacon_widget,
228
+ settings=settings,
229
+ )
230
+
231
+ herre = build_arkitekt_next_qt_herre(manifest=manifest, fakts=fakts, login_widget=login_widget, parent=parent, settings=settings)
232
+
233
+ params = kwargs
234
+
235
+
236
+
237
+ url = os.getenv("FAKTS_URL", url)
238
+ token = os.getenv("FAKTS_TOKEN", token)
239
+
240
+ create_arkitekt_next_folder(with_cache=True)
241
+
242
+
243
+
244
+ try:
245
+ from rich.logging import RichHandler
246
+
247
+ logging.basicConfig(level=log_level, handlers=[RichHandler()])
248
+ except ImportError:
249
+ logging.basicConfig(level=log_level)
250
+
251
+ print(registry.service_builders)
252
+
253
+ app = App(
254
+ fakts=fakts,
255
+ herre=herre,
256
+ manifest=manifest,
257
+ services=registry.build_service_map(fakts=fakts, herre=herre, params=params),
258
+ )
259
+
260
+ print()
261
+
262
+
263
+ app.enter()
264
+ return app
File without changes
File without changes
@@ -0,0 +1,132 @@
1
+ import rich_click as click
2
+ from arkitekt_next.cli.options import *
3
+ import asyncio
4
+ from arkitekt_next.cli.ui import construct_run_panel
5
+ from importlib import import_module
6
+ from rekuest.postmans.utils import arkiuse
7
+ from arkitekt_next.cli.utils import import_builder
8
+ from rekuest.api.schema import (
9
+ NodeKind,
10
+ ReserveBindsInput,
11
+ )
12
+ from rich.table import Table
13
+ from rich.console import Console
14
+ from typing import Dict, Any
15
+
16
+
17
+ async def call_app(
18
+ console: Console,
19
+ app: App,
20
+ template_string: str,
21
+ arg: Dict[str, Any],
22
+ ):
23
+ async with app:
24
+ await app.rekuest.agent.aregister_definitions()
25
+
26
+ run_task = asyncio.create_task(app.rekuest.run())
27
+
28
+ template = app.rekuest.agent.interface_template_map[template_string]
29
+
30
+ async with arkiuse(
31
+ hash=template.node.hash,
32
+ binds=ReserveBindsInput(templates=[template.id], clients=[]),
33
+ postman=app.rekuest.postman,
34
+ ) as a:
35
+ if template.node.kind == NodeKind.GENERATOR:
36
+ async for i in a.astream(kwargs=arg):
37
+ table = Table(title=f"Yields of {template.node.name}")
38
+ table.add_column("key")
39
+ table.add_column("value")
40
+
41
+ for key, value in i.items():
42
+ table.add_row(key, value)
43
+
44
+ console.print(table)
45
+
46
+ else:
47
+ i = await a.aassign(kwargs=arg)
48
+ table = Table(title=f"Returns of {template.node.name}")
49
+ table.add_column("key")
50
+ table.add_column("value")
51
+
52
+ for key, value in i.items():
53
+ table.add_row(key, value)
54
+
55
+ console.print(table)
56
+
57
+ run_task.cancel()
58
+
59
+ try:
60
+ await run_task
61
+ except asyncio.CancelledError:
62
+ pass
63
+
64
+
65
+ @click.command("prod")
66
+ @click.option(
67
+ "--url",
68
+ help="The fakts url for connection",
69
+ default=DEFAULT_ARKITEKT_URL,
70
+ envvar="FAKTS_URL",
71
+ )
72
+ @with_builder
73
+ @with_token
74
+ @with_instance_id
75
+ @with_headless
76
+ @with_log_level
77
+ @with_skip_cache
78
+ @click.pass_context
79
+ @click.option(
80
+ "--arg",
81
+ "-a",
82
+ "args",
83
+ help="Key Value pairs for the setup",
84
+ type=(str, str),
85
+ multiple=True,
86
+ )
87
+ @click.option(
88
+ "--template",
89
+ "-t",
90
+ "template",
91
+ help="The template to run",
92
+ type=str,
93
+ )
94
+ def local(
95
+ ctx,
96
+ entrypoint=None,
97
+ builder=None,
98
+ args=None,
99
+ template: str = None,
100
+ **builder_kwargs,
101
+ ):
102
+ """Runs the app in production mode
103
+
104
+ \n
105
+ You can specify the builder to use with the --builder flag. By default, the easy builder is used, which is designed to be easy to use and to get started with.
106
+
107
+ """
108
+
109
+ manifest = get_manifest(ctx)
110
+ console = get_console(ctx)
111
+ entrypoint = entrypoint or manifest.entrypoint
112
+
113
+ kwargs = dict(args or [])
114
+
115
+ builder = import_builder(builder)
116
+
117
+ with console.status("Loading entrypoint module..."):
118
+ try:
119
+ import_module(entrypoint)
120
+ except ModuleNotFoundError as e:
121
+ console.print(f"Could not find entrypoint module {entrypoint}")
122
+ raise e
123
+
124
+ app = builder(
125
+ **manifest.to_builder_dict(),
126
+ **builder_kwargs,
127
+ )
128
+
129
+ panel = construct_run_panel(app)
130
+ console.print(panel)
131
+
132
+ asyncio.run(call_app(console, app, template, kwargs))
@@ -0,0 +1,22 @@
1
+ import rich_click as click
2
+
3
+
4
+ import rich_click as click
5
+ from .remote import remote
6
+ from .local import local
7
+
8
+
9
+ @click.group()
10
+ @click.pass_context
11
+ def call(ctx):
12
+ """Inspects your arkitekt_next app
13
+
14
+ Inspects various parts of your arkitekt_next app. This is useful for debugging
15
+ and development. It also represents methods that are called by the arkitekt_next
16
+ server when you run your app in production mode.
17
+
18
+ """
19
+
20
+
21
+ call.add_command(local, "local")
22
+ call.add_command(remote, "remote")