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.
- arkitekt_next/__init__.py +43 -0
- arkitekt_next/apps/__init__.py +3 -0
- arkitekt_next/apps/easy.py +99 -0
- arkitekt_next/apps/next.py +40 -0
- arkitekt_next/apps/qt.py +97 -0
- arkitekt_next/apps/service/__init__.py +3 -0
- arkitekt_next/apps/service/fakts.py +88 -0
- arkitekt_next/apps/service/fakts_next.py +79 -0
- arkitekt_next/apps/service/fakts_qt.py +82 -0
- arkitekt_next/apps/service/fluss_next.py +31 -0
- arkitekt_next/apps/service/grant_registry.py +27 -0
- arkitekt_next/apps/service/herre.py +24 -0
- arkitekt_next/apps/service/herre_qt.py +57 -0
- arkitekt_next/apps/service/kabinet.py +31 -0
- arkitekt_next/apps/service/mikro_next.py +81 -0
- arkitekt_next/apps/service/rekuest_next.py +53 -0
- arkitekt_next/apps/service/unlok_next.py +32 -0
- arkitekt_next/apps/types.py +53 -0
- arkitekt_next/builders.py +264 -0
- arkitekt_next/cli/__init__.py +0 -0
- arkitekt_next/cli/commands/call/__init__.py +0 -0
- arkitekt_next/cli/commands/call/local.py +132 -0
- arkitekt_next/cli/commands/call/main.py +22 -0
- arkitekt_next/cli/commands/call/remote.py +90 -0
- arkitekt_next/cli/commands/gen/__init__.py +0 -0
- arkitekt_next/cli/commands/gen/compile.py +45 -0
- arkitekt_next/cli/commands/gen/init.py +122 -0
- arkitekt_next/cli/commands/gen/main.py +29 -0
- arkitekt_next/cli/commands/gen/watch.py +32 -0
- arkitekt_next/cli/commands/init/__init__.py +0 -0
- arkitekt_next/cli/commands/init/main.py +194 -0
- arkitekt_next/cli/commands/inspect/__init__.py +0 -0
- arkitekt_next/cli/commands/inspect/definitions.py +53 -0
- arkitekt_next/cli/commands/inspect/main.py +22 -0
- arkitekt_next/cli/commands/inspect/variables.py +92 -0
- arkitekt_next/cli/commands/manifest/__init__.py +0 -0
- arkitekt_next/cli/commands/manifest/inspect.py +42 -0
- arkitekt_next/cli/commands/manifest/main.py +25 -0
- arkitekt_next/cli/commands/manifest/scopes.py +155 -0
- arkitekt_next/cli/commands/manifest/version.py +147 -0
- arkitekt_next/cli/commands/manifest/wizard.py +94 -0
- arkitekt_next/cli/commands/port/__init__.py +0 -0
- arkitekt_next/cli/commands/port/build.py +231 -0
- arkitekt_next/cli/commands/port/init.py +82 -0
- arkitekt_next/cli/commands/port/main.py +31 -0
- arkitekt_next/cli/commands/port/publish.py +102 -0
- arkitekt_next/cli/commands/port/stage.py +59 -0
- arkitekt_next/cli/commands/port/utils.py +47 -0
- arkitekt_next/cli/commands/port/validate.py +78 -0
- arkitekt_next/cli/commands/port/wizard.py +329 -0
- arkitekt_next/cli/commands/run/__init__.py +0 -0
- arkitekt_next/cli/commands/run/dev.py +349 -0
- arkitekt_next/cli/commands/run/main.py +22 -0
- arkitekt_next/cli/commands/run/prod.py +57 -0
- arkitekt_next/cli/commands/run/utils.py +10 -0
- arkitekt_next/cli/commands/server/__init__.py +0 -0
- arkitekt_next/cli/commands/server/down.py +56 -0
- arkitekt_next/cli/commands/server/init.py +74 -0
- arkitekt_next/cli/commands/server/inspect.py +59 -0
- arkitekt_next/cli/commands/server/main.py +33 -0
- arkitekt_next/cli/commands/server/open.py +66 -0
- arkitekt_next/cli/commands/server/remove.py +60 -0
- arkitekt_next/cli/commands/server/stop.py +56 -0
- arkitekt_next/cli/commands/server/up.py +70 -0
- arkitekt_next/cli/commands/server/utils.py +33 -0
- arkitekt_next/cli/configs/base.yaml +867 -0
- arkitekt_next/cli/constants.py +63 -0
- arkitekt_next/cli/dockerfiles/vanilla.dockerfile +8 -0
- arkitekt_next/cli/errors.py +4 -0
- arkitekt_next/cli/inspect.py +1 -0
- arkitekt_next/cli/io.py +255 -0
- arkitekt_next/cli/main.py +83 -0
- arkitekt_next/cli/options.py +166 -0
- arkitekt_next/cli/schemas/fluss.schema.graphql +2446 -0
- arkitekt_next/cli/schemas/gucker.schema.graphql +8908 -0
- arkitekt_next/cli/schemas/kabinet.schema.graphql +515 -0
- arkitekt_next/cli/schemas/kluster.schema.graphql +109 -0
- arkitekt_next/cli/schemas/konviktion.schema.graphql +70 -0
- arkitekt_next/cli/schemas/kuay.schema.graphql +356 -0
- arkitekt_next/cli/schemas/mikro.schema.graphql +8908 -0
- arkitekt_next/cli/schemas/mikro_next.schema.graphql +1639 -0
- arkitekt_next/cli/schemas/napari.schema.graphql +8908 -0
- arkitekt_next/cli/schemas/omero_ark.schema.graphql +100 -0
- arkitekt_next/cli/schemas/port.schema.graphql +356 -0
- arkitekt_next/cli/schemas/rekuest.schema.graphql +4630 -0
- arkitekt_next/cli/schemas/rekuest_next.schema.graphql +1159 -0
- arkitekt_next/cli/schemas/unlok.schema.graphql +1013 -0
- arkitekt_next/cli/templates/filter.py +26 -0
- arkitekt_next/cli/templates/simple.py +67 -0
- arkitekt_next/cli/texts.py +20 -0
- arkitekt_next/cli/types.py +365 -0
- arkitekt_next/cli/ui.py +111 -0
- arkitekt_next/cli/utils.py +15 -0
- arkitekt_next/cli/validators.py +17 -0
- arkitekt_next/cli/vars.py +39 -0
- arkitekt_next/cli/versions/v1.yaml +1 -0
- arkitekt_next/constants.py +6 -0
- arkitekt_next/model.py +110 -0
- arkitekt_next/qt/__init__.py +9 -0
- arkitekt_next/qt/assets/dark/gear.png +0 -0
- arkitekt_next/qt/assets/dark/green pulse.gif +0 -0
- arkitekt_next/qt/assets/dark/orange pulse.gif +0 -0
- arkitekt_next/qt/assets/dark/pink pulse.gif +0 -0
- arkitekt_next/qt/assets/dark/red pulse.gif +0 -0
- arkitekt_next/qt/assets/light/gear.png +0 -0
- arkitekt_next/qt/assets/light/green pulse.gif +0 -0
- arkitekt_next/qt/assets/light/orange pulse.gif +0 -0
- arkitekt_next/qt/assets/light/pink pulse.gif +0 -0
- arkitekt_next/qt/assets/light/red pulse.gif +0 -0
- arkitekt_next/qt/magic_bar.py +545 -0
- arkitekt_next/qt/utils.py +30 -0
- arkitekt_next/service_registry.py +51 -0
- arkitekt_next/tqdm.py +43 -0
- arkitekt_next/utils.py +38 -0
- arkitekt_next-0.7.8.dist-info/LICENSE +21 -0
- arkitekt_next-0.7.8.dist-info/METADATA +155 -0
- arkitekt_next-0.7.8.dist-info/RECORD +119 -0
- arkitekt_next-0.7.8.dist-info/WHEEL +4 -0
- 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")
|