arkitekt-next 0.7.37__py3-none-any.whl → 0.7.39__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/__blok__.py CHANGED
@@ -14,6 +14,9 @@ from arkitekt_next.bloks.mount import MountBlok
14
14
  from arkitekt_next.bloks.internal_docker import InternalDockerBlok
15
15
  from arkitekt_next.bloks.socket import DockerSocketBlok
16
16
  from arkitekt_next.bloks.rekuest import RekuestBlok
17
+ from arkitekt_next.bloks.tailscale import TailscaleBlok
18
+ from arkitekt_next.bloks.secret import SecretBlok
19
+ from arkitekt_next.bloks.namegen import PreformedNamesBlok
17
20
 
18
21
 
19
22
  def get_bloks():
@@ -34,4 +37,7 @@ def get_bloks():
34
37
  InternalDockerBlok(),
35
38
  DockerSocketBlok(),
36
39
  RekuestBlok(),
40
+ TailscaleBlok(),
41
+ SecretBlok(),
42
+ PreformedNamesBlok(),
37
43
  ]
@@ -1,5 +1,6 @@
1
1
  from pydantic import BaseModel
2
2
  from typing import Dict, Any
3
+ from arkitekt_next.bloks.tailscale import TailscaleBlok
3
4
  from blok import blok, InitContext, Renderer, Panel
4
5
  from .livekit import LocalLiveKitBlok
5
6
  from .mikro import MikroBlok
@@ -29,7 +30,7 @@ class ArkitektBlok:
29
30
  )
30
31
  )
31
32
 
32
- def preflight(self, lok: LocalLiveKitBlok, mikro: MikroBlok, kabinet: KabinetBlok, rekuest: RekuestBlok, fluss: FlussBlok, gateway: GatewayBlok, internal_engine: InternalDockerBlok):
33
+ def preflight(self, lok: LocalLiveKitBlok, mikro: MikroBlok, kabinet: KabinetBlok, rekuest: RekuestBlok, fluss: FlussBlok, gateway: GatewayBlok, internal_engine: InternalDockerBlok, scale: TailscaleBlok):
33
34
  print (lok, mikro, kabinet, rekuest, fluss, gateway, internal_engine)
34
35
 
35
36
 
@@ -1,5 +1,8 @@
1
1
  import secrets
2
- from arkitekt_next.bloks.funcs import create_default_service_yaml
2
+ from arkitekt_next.bloks.funcs import (
3
+ create_default_service_dependencies,
4
+ create_default_service_yaml,
5
+ )
3
6
  from blok import blok, InitContext, ExecutionContext, Option
4
7
  from blok.tree import YamlFile, Repo
5
8
 
@@ -21,17 +24,11 @@ class FlussBlok:
21
24
  self.secret_key = secrets.token_hex(16)
22
25
  self.ensured_repos = []
23
26
 
27
+ def get_builder(self):
28
+ return "arkitekt.generic"
29
+
24
30
  def get_dependencies(self):
25
- return [
26
- "live.arkitekt.mount",
27
- "live.arkitekt.config",
28
- "live.arkitekt.gateway",
29
- "live.arkitekt.postgres",
30
- "live.arkitekt.lok",
31
- "live.arkitekt.admin",
32
- "live.arkitekt.redis",
33
- "live.arkitekt.s3",
34
- ]
31
+ return create_default_service_dependencies()
35
32
 
36
33
  def preflight(self, init: InitContext):
37
34
  for key, value in init.kwargs.items():
@@ -58,13 +55,13 @@ class FlussBlok:
58
55
  mount_repo = Option(
59
56
  subcommand="mount_repo",
60
57
  help="Should we mount the repo into the container?",
61
- is_flag=True,
58
+ type=bool,
62
59
  default=self.mount_repo,
63
60
  )
64
61
  build_repo = Option(
65
62
  subcommand="build_repo",
66
63
  help="Should we build the container from the repo?",
67
- is_flag=True,
64
+ type=bool,
68
65
  default=self.build_repo,
69
66
  )
70
67
  with_host = Option(
@@ -3,6 +3,20 @@ from blok.tree import YamlFile, Repo
3
3
  from typing import Protocol
4
4
  from blok.utils import check_protocol_compliance
5
5
  from dataclasses import asdict
6
+ from arkitekt_next.bloks.services import (
7
+ GatewayService,
8
+ DBService,
9
+ RedisService,
10
+ S3Service,
11
+ ConfigService,
12
+ MountService,
13
+ AdminService,
14
+ SecretService,
15
+ LokService,
16
+ )
17
+
18
+ from blok.bloks.services.dns import DnsService
19
+
6
20
 
7
21
  class DefaultService(Protocol):
8
22
  service_name: str
@@ -15,6 +29,23 @@ class DefaultService(Protocol):
15
29
 
16
30
  def get_identifier(self) -> str: ...
17
31
 
32
+ def get_builder(self) -> str: ...
33
+
34
+
35
+ def create_default_service_dependencies():
36
+ return [
37
+ DnsService,
38
+ GatewayService,
39
+ DBService,
40
+ RedisService,
41
+ S3Service,
42
+ ConfigService,
43
+ MountService,
44
+ AdminService,
45
+ SecretService,
46
+ LokService,
47
+ ]
48
+
18
49
 
19
50
  def create_default_service_yaml(
20
51
  init: InitContext,
@@ -22,17 +53,28 @@ def create_default_service_yaml(
22
53
  ) -> YamlFile:
23
54
  check_protocol_compliance(self, DefaultService)
24
55
  deps = init.dependencies
25
- deps["live.arkitekt.lok"].register_scopes(self.scopes)
26
56
 
27
- gateway_access = deps["live.arkitekt.gateway"].expose(self.host, 80, self.host)
57
+ init.get_service(LokService).register_scopes(self.scopes)
58
+
59
+ path_name = self.host
60
+
61
+ gateway_access = init.get_service(GatewayService).expose(path_name, 80, self.host)
62
+
63
+ postgress_access = init.get_service(DBService).register_db(self.host)
64
+ redis_access = init.get_service(RedisService).register()
65
+ lok_access = init.get_service(LokService).retrieve_credentials()
66
+ admin_access = init.get_service(AdminService).retrieve()
67
+ minio_access = init.get_service(S3Service).create_buckets(self.buckets)
68
+ lok_labels = init.get_service(LokService).retrieve_labels(
69
+ self.get_identifier(), self.get_builder()
70
+ )
71
+
72
+ dns_result = init.get_service(DnsService).get_dns_result()
28
73
 
29
- postgress_access = deps["live.arkitekt.postgres"].register_db(self.host)
30
- redis_access = deps["live.arkitekt.redis"].register()
31
- lok_access = deps["live.arkitekt.lok"].retrieve_credentials()
32
- admin_access = deps["live.arkitekt.admin"].retrieve()
33
- minio_access = deps["live.arkitekt.s3"].create_buckets(self.buckets)
34
- lok_access = deps["live.arkitekt.lok"].retrieve_credentials()
35
- lok_labels = deps["live.arkitekt.lok"].retrieve_labels(self.get_identifier())
74
+ csrf_trusted_origins = []
75
+ for hostname in dns_result.hostnames:
76
+ csrf_trusted_origins.append(f"http://{hostname}")
77
+ csrf_trusted_origins.append(f"https://{hostname}")
36
78
 
37
79
  configuration = YamlFile(
38
80
  **{
@@ -47,10 +89,12 @@ def create_default_service_yaml(
47
89
  "lok": asdict(lok_access),
48
90
  "s3": asdict(minio_access),
49
91
  "scopes": self.scopes,
92
+ "force_script_name": path_name,
93
+ "csrf_trusted_origins": csrf_trusted_origins,
50
94
  }
51
95
  )
52
96
 
53
- config_mount = deps["live.arkitekt.config"].register_config(
97
+ config_mount = init.get_service(ConfigService).register_config(
54
98
  f"{self.host}.yaml", configuration
55
99
  )
56
100
 
@@ -72,11 +116,15 @@ def create_default_service_yaml(
72
116
  }
73
117
 
74
118
  if self.mount_repo:
75
- mount = deps["live.arkitekt.mount"].register_mount(self.host, Repo(self.repo))
119
+ mount = init.get_service(MountService).register_mount(
120
+ self.host, Repo(self.repo)
121
+ )
76
122
  service["volumes"].extend([f"{mount}:/workspace"])
77
123
 
78
124
  if self.build_repo:
79
- mount = deps["live.arkitekt.mount"].register_mount(self.host, Repo(self.repo))
125
+ mount = init.get_service(MountService).register_mount(
126
+ self.host, Repo(self.repo)
127
+ )
80
128
  service["build"] = mount
81
129
  else:
82
130
  service["image"] = self.image
@@ -16,16 +16,25 @@ class ExposedHost(BaseModel):
16
16
  stip_prefix: bool = True
17
17
 
18
18
 
19
+ class ExpostedToHost(BaseModel):
20
+ port: int
21
+ host: str
22
+ to: str
23
+ tls: bool = False
24
+
25
+
19
26
  class ExposedPort(BaseModel):
20
27
  port: int
21
28
  host: str
22
29
  tls: bool = False
30
+ to: int
23
31
 
24
32
 
25
33
  @blok("live.arkitekt.gateway")
26
34
  class GatewayBlok:
27
35
  def __init__(self) -> None:
28
36
  self.exposed_hosts = {}
37
+ self.exposed_to_hosts = {}
29
38
  self.http_expose_default = None
30
39
  self.exposed_ports = {}
31
40
  self.with_certer = True
@@ -36,6 +45,15 @@ class GatewayBlok:
36
45
  self.public_ips = DEFAULT_PUBLIC_URLS
37
46
  self.public_hosts = DEFAULT_PUBLIC_HOSTS
38
47
 
48
+ def get_internal_host(self):
49
+ return "caddy"
50
+
51
+ def get_https_port(self):
52
+ return 443
53
+
54
+ def get_http_port(self):
55
+ return 80
56
+
39
57
  def preflight(self, init: InitContext, dns: DnsService):
40
58
  for key, value in init.kwargs.items():
41
59
  setattr(self, key, value)
@@ -43,7 +61,10 @@ class GatewayBlok:
43
61
  self.public_ips = dns.get_dns_result().ip_addresses
44
62
  self.public_hosts = dns.get_dns_result().hostnames
45
63
 
46
- def build(self, context: ExecutionContext,):
64
+ def build(
65
+ self,
66
+ context: ExecutionContext,
67
+ ):
47
68
  caddyfile = """
48
69
  {
49
70
  auto_https off
@@ -55,13 +76,13 @@ class GatewayBlok:
55
76
  caddyfile += f"""
56
77
  :{port.port} {{
57
78
  tls /certs/caddy.crt /certs/caddy.key
58
- reverse_proxy {port.host}:{port.port}
79
+ reverse_proxy {port.host}:{port.to}
59
80
  }}
60
81
  """
61
82
  else:
62
83
  caddyfile += f"""
63
84
  :{port.port} {{
64
- reverse_proxy {port.host}:{port.port}
85
+ reverse_proxy {port.host}:{port.to}
65
86
  }}
66
87
  """
67
88
 
@@ -103,6 +124,15 @@ class GatewayBlok:
103
124
  }}
104
125
  """
105
126
 
127
+ for path_name, exposed_to_host in self.exposed_to_hosts.items():
128
+ caddyfile += f"""
129
+ @{path_name} path /{path_name}*
130
+ handle @{path_name} {{
131
+ rewrite * /{exposed_to_host.to}{{uri}}
132
+ reverse_proxy {exposed_to_host.host}:{exposed_to_host.port}
133
+ }}
134
+ """
135
+
106
136
  if self.http_expose_default:
107
137
  caddyfile += f"""
108
138
  handle {{
@@ -120,10 +150,18 @@ class GatewayBlok:
120
150
  if self.with_certer:
121
151
  caddy_depends_on.append("certer")
122
152
 
153
+ exposed_ports_strings = [
154
+ f"{port.port}:{port.port}" for port in self.exposed_ports.values()
155
+ ]
156
+
123
157
  caddy_container = {
124
158
  "image": "caddy:latest",
125
159
  "volumes": ["./configs/Caddyfile:/etc/caddy/Caddyfile", "./certs:/certs"],
126
- "ports": [f"{self.http_port}:80", f"{self.https_port}:443"],
160
+ "ports": [
161
+ f"{self.http_port}:80",
162
+ f"{self.https_port}:443",
163
+ ]
164
+ + exposed_ports_strings,
127
165
  "depends_on": caddy_depends_on,
128
166
  }
129
167
 
@@ -141,16 +179,24 @@ class GatewayBlok:
141
179
 
142
180
  context.docker_compose.set_nested("services", "certer", certer_container)
143
181
 
144
- def expose(self, path_name: str, port: int, host: str, strip_prefix: bool = True):
182
+ def expose(self, path_name: str, port: int, host: str, strip_prefix: bool = False):
145
183
  self.exposed_hosts[path_name] = ExposedHost(
146
184
  host=host, port=port, stip_prefix=strip_prefix
147
185
  )
148
186
 
187
+ def expose_mapped(self, path_name: str, port: int, host: str, to: str):
188
+ self.exposed_to_hosts[path_name] = ExpostedToHost(host=host, port=port, to=to)
189
+
149
190
  def expose_default(self, port: int, host: str):
150
191
  self.http_expose_default = ExposedHost(host=host, port=port, stip_prefix=False)
151
192
 
152
193
  def expose_port(self, port: int, host: str, tls: bool = False):
153
- self.exposed_ports[port] = ExposedPort(port=port, host=host, tls=tls)
194
+ self.exposed_ports[port] = ExposedPort(port=port, host=host, tls=tls, to=port)
195
+
196
+ def expose_port_to(self, port: int, host: str, to_port: int, tls: bool = False):
197
+ self.exposed_ports[port] = ExposedPort(
198
+ port=port, host=host, tls=tls, to=to_port
199
+ )
154
200
 
155
201
  def get_options(self):
156
202
  with_public_urls = Option(
@@ -1,7 +1,11 @@
1
1
  from typing import Dict, Any
2
2
  import secrets
3
3
 
4
+ from arkitekt_next.bloks.lok import LokBlok
5
+ from arkitekt_next.bloks.services.gateway import GatewayService
6
+ from arkitekt_next.bloks.socket import DockerSocketBlok
4
7
  from blok import blok, InitContext, ExecutionContext, Option
8
+ from blok.bloks.services.dns import DnsService
5
9
  from blok.tree import YamlFile, Repo
6
10
 
7
11
 
@@ -9,16 +13,12 @@ from blok.tree import YamlFile, Repo
9
13
  class InternalDockerBlok:
10
14
  def __init__(self) -> None:
11
15
  self.host = "internal_docker"
12
- self.command = (
13
- "arkitekt-next run prod --redeem-token=mylittletoken --url http://caddy:80"
14
- )
16
+
15
17
  self.image = "jhnnsrs/deployer:0.0.1-vanilla"
16
18
  self.instance_id = "INTERNAL_DOCKER"
17
19
 
18
- def get_dependencies(self):
19
- return ["live.arkitekt.docker_socket"]
20
20
 
21
- def preflight(self, init: InitContext):
21
+ def preflight(self, init: InitContext, gateway: GatewayService, lok: LokBlok, socket: DockerSocketBlok):
22
22
  for key, value in init.kwargs.items():
23
23
  setattr(self, key, value)
24
24
 
@@ -27,7 +27,15 @@ class InternalDockerBlok:
27
27
  if self.skip:
28
28
  return
29
29
 
30
- self._socket = deps["live.arkitekt.docker_socket"].register_socket(self.host)
30
+ self._socket = socket.register_socket(self.host)
31
+ self.gateway_host = gateway.get_internal_host()
32
+ self.gateway_port = gateway.get_http_port()
33
+
34
+ self.token = lok.retrieve_token()
35
+
36
+ self.command = (
37
+ f"arkitekt-next run prod --redeem-token={self.token} --url http://{self.gateway_host}:{self.gateway_port}"
38
+ )
31
39
 
32
40
  self.initialized = True
33
41
 
@@ -50,27 +58,21 @@ class InternalDockerBlok:
50
58
  context.docker_compose.set_nested("services", self.host, db_service)
51
59
 
52
60
  def get_options(self):
53
- with_command = Option(
54
- subcommand="command",
55
- help="The fakts url for connection",
56
- default=self.command,
57
- )
58
61
  with_host = Option(
59
62
  subcommand="host",
60
- help="The fakts url for connection",
63
+ help="The host of this service",
61
64
  default=self.host,
62
65
  )
63
66
  with_skip = Option(
64
67
  subcommand="skip",
65
- help="The fakts url for connection",
68
+ help="Should we skip creating this service?",
66
69
  default=False,
67
70
  type=bool,
68
- is_flag=True,
71
+
69
72
  )
70
73
 
71
74
  return [
72
75
  with_host,
73
- with_command,
74
76
  with_skip,
75
77
  ]
76
78
 
@@ -1,7 +1,10 @@
1
1
  from typing import Dict, Any
2
2
  import secrets
3
3
 
4
- from arkitekt_next.bloks.funcs import create_default_service_yaml
4
+ from arkitekt_next.bloks.funcs import (
5
+ create_default_service_yaml,
6
+ create_default_service_dependencies,
7
+ )
5
8
  from blok import blok, InitContext, ExecutionContext, Option
6
9
  from blok.tree import Repo, YamlFile
7
10
 
@@ -12,7 +15,10 @@ class KabinetBlok:
12
15
  self.host = "kabinet"
13
16
  self.command = "bash run-debug.sh"
14
17
  self.repo = "https://github.com/jhnnsrs/kabinet-server"
15
- self.scopes = {"read_image": "Read image from the database"}
18
+ self.scopes = {
19
+ "kabinet_deploy": "Deploy containers",
20
+ "kabinet_add_repo": "Add repositories to the database",
21
+ }
16
22
  self.mount_repo = False
17
23
  self.build_repo = False
18
24
  self.buckets = ["media"]
@@ -20,17 +26,11 @@ class KabinetBlok:
20
26
  self.ensured_repos = []
21
27
  self.image = "jhnnsrs/kabinet:next"
22
28
 
29
+ def get_builder(self):
30
+ return "arkitekt.generic"
31
+
23
32
  def get_dependencies(self):
24
- return [
25
- "live.arkitekt.mount",
26
- "live.arkitekt.config",
27
- "live.arkitekt.gateway",
28
- "live.arkitekt.postgres",
29
- "live.arkitekt.lok",
30
- "live.arkitekt.admin",
31
- "live.arkitekt.redis",
32
- "live.arkitekt.s3",
33
- ]
33
+ return create_default_service_dependencies()
34
34
 
35
35
  def preflight(self, init: InitContext):
36
36
  for key, value in init.kwargs.items():
@@ -57,13 +57,13 @@ class KabinetBlok:
57
57
  mount_repo = Option(
58
58
  subcommand="mount_repo",
59
59
  help="Should we mount the repo into the container?",
60
- is_flag=True,
60
+ type=bool,
61
61
  default=self.mount_repo,
62
62
  )
63
63
  build_repo = Option(
64
64
  subcommand="build_repo",
65
65
  help="Should we build the container from the repo?",
66
- is_flag=True,
66
+ type=bool,
67
67
  default=self.build_repo,
68
68
  )
69
69
  with_host = Option(
@@ -22,7 +22,6 @@ class LocalLiveKitBlok:
22
22
  self.api_secret = "secret"
23
23
  self.skip = False
24
24
 
25
-
26
25
  def preflight(self, init: InitContext, gateway: GatewayService):
27
26
  for key, value in init.kwargs.items():
28
27
  setattr(self, key, value)
@@ -33,16 +32,18 @@ class LocalLiveKitBlok:
33
32
  return
34
33
 
35
34
  gateway.expose_port(7880, self.host, True)
36
- gateway.expose_port(7881, self.host, True)
35
+ gateway.expose_port_to(7882, self.host, 7880, False)
37
36
 
38
37
  self.initialized = True
39
38
 
40
39
  def retrieve_access(self):
41
- return LivekitCredentials(**{
42
- "api_key": self.api_key,
43
- "api_secret": self.api_secret,
44
- "api_url": f"http://{self.host}:7880",
45
- })
40
+ return LivekitCredentials(
41
+ **{
42
+ "api_key": self.api_key,
43
+ "api_secret": self.api_secret,
44
+ "api_url": f"http://{self.host}:7880",
45
+ }
46
+ )
46
47
 
47
48
  def build(self, context: ExecutionContext):
48
49
  if self.skip:
@@ -55,18 +56,14 @@ class LocalLiveKitBlok:
55
56
  "image": self.image,
56
57
  "command": self.command,
57
58
  "ports": [
58
- f"{self.port_range[0]}-{self.port_range[1]}:{self.port_range[0]}-{self.port_range[1]}"
59
+ f"{self.port_range[0]}-{self.port_range[1]}:{self.port_range[0]}-{self.port_range[1]}",
60
+ "7881:7881",
59
61
  ],
60
62
  }
61
63
 
62
64
  context.docker_compose.set_nested("services", self.host, db_service)
63
65
 
64
66
  def get_options(self):
65
- with_command = Option(
66
- subcommand="command",
67
- help="The fakts url for connection",
68
- default=self.command,
69
- )
70
67
  with_host = Option(
71
68
  subcommand="host",
72
69
  help="The fakts url for connection",
@@ -77,12 +74,10 @@ class LocalLiveKitBlok:
77
74
  help="The fakts url for connection",
78
75
  default=False,
79
76
  type=bool,
80
- is_flag=True,
81
77
  )
82
78
 
83
79
  return [
84
80
  with_host,
85
- with_command,
86
81
  with_skip,
87
82
  ]
88
83