llama-deploy-appserver 0.3.13__py3-none-any.whl → 0.3.15__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.
@@ -37,6 +37,7 @@ from llama_deploy.appserver.workflow_loader import (
37
37
  load_environment_variables,
38
38
  load_workflows,
39
39
  start_dev_ui_process,
40
+ validate_required_env_vars,
40
41
  )
41
42
  from llama_deploy.core.config import DEFAULT_DEPLOYMENT_FILE_PATH
42
43
  from prometheus_fastapi_instrumentator import Instrumentator
@@ -168,7 +169,9 @@ def prepare_server(
168
169
  configure_settings(
169
170
  deployment_file_path=deployment_file or Path(DEFAULT_DEPLOYMENT_FILE_PATH)
170
171
  )
171
- load_environment_variables(get_deployment_config(), settings.resolved_config_parent)
172
+ cfg = get_deployment_config()
173
+ load_environment_variables(cfg, settings.resolved_config_parent)
174
+ validate_required_env_vars(cfg)
172
175
  if install:
173
176
  config = get_deployment_config()
174
177
  inject_appserver_into_target(config, settings.resolved_config_parent)
@@ -192,7 +195,9 @@ def start_server(
192
195
  deployment_file_path=deployment_file or Path(DEFAULT_DEPLOYMENT_FILE_PATH),
193
196
  reload=reload,
194
197
  )
195
- load_environment_variables(get_deployment_config(), settings.resolved_config_parent)
198
+ cfg = get_deployment_config()
199
+ load_environment_variables(cfg, settings.resolved_config_parent)
200
+ validate_required_env_vars(cfg)
196
201
 
197
202
  ui_process = None
198
203
  if proxy_ui:
@@ -18,6 +18,7 @@ from llama_deploy.appserver.workflow_loader import (
18
18
  inject_appserver_into_target,
19
19
  install_ui,
20
20
  load_environment_variables,
21
+ validate_required_env_vars,
21
22
  )
22
23
  from llama_deploy.core.git.git_util import (
23
24
  clone_repo,
@@ -50,6 +51,8 @@ def bootstrap_app_from_repo(
50
51
  )
51
52
  config = get_deployment_config()
52
53
  load_environment_variables(config, settings.resolved_config_parent)
54
+ # Fail fast if required env vars are missing
55
+ validate_required_env_vars(config)
53
56
 
54
57
  sdists = None
55
58
  if bootstrap_settings.bootstrap_sdists:
@@ -1,7 +1,6 @@
1
1
  import functools
2
2
  import os
3
3
  import platform
4
- import pty
5
4
  import subprocess
6
5
  import sys
7
6
  import threading
@@ -118,6 +117,8 @@ def _spawn_process(
118
117
  use_pty: bool,
119
118
  ) -> tuple[subprocess.Popen, list[tuple[int | TextIO, TextIO]], Callable[[], None]]:
120
119
  if use_pty:
120
+ import pty
121
+
121
122
  master_fd, slave_fd = pty.openpty()
122
123
  process = subprocess.Popen(
123
124
  cmd,
@@ -140,6 +141,9 @@ def _spawn_process(
140
141
  ]
141
142
  return process, sources, cleanup
142
143
 
144
+ use_shell = False
145
+ if platform.system() == "Windows":
146
+ use_shell = True
143
147
  process = subprocess.Popen(
144
148
  cmd,
145
149
  env=env,
@@ -149,6 +153,7 @@ def _spawn_process(
149
153
  stderr=subprocess.PIPE,
150
154
  text=True,
151
155
  encoding="utf-8",
156
+ shell=use_shell,
152
157
  )
153
158
 
154
159
  def cleanup() -> None:
@@ -175,8 +180,11 @@ def _stream_source(
175
180
  for line in f:
176
181
  out = transform(line) if transform else line
177
182
  if out is not None:
178
- writer.write(out)
179
- writer.flush()
183
+ try:
184
+ writer.write(out)
185
+ writer.flush()
186
+ except UnicodeEncodeError:
187
+ pass
180
188
  except OSError:
181
189
  # PTY EOF may raise EIO; ignore
182
190
  pass
@@ -37,6 +37,10 @@ def load_workflows(config: DeploymentConfig) -> dict[str, Workflow]:
37
37
  if config.app:
38
38
  module_name, app_name = config.app.split(":", 1)
39
39
  module = importlib.import_module(module_name)
40
+ if not hasattr(module, app_name):
41
+ raise AttributeError(
42
+ f"Module '{module_name}' has no attribute '{app_name}'"
43
+ )
40
44
  workflow = getattr(module, app_name)
41
45
  if not isinstance(workflow, WorkflowServer):
42
46
  raise ValueError(
@@ -48,6 +52,10 @@ def load_workflows(config: DeploymentConfig) -> dict[str, Workflow]:
48
52
  for service_id, workflow_name in config.workflows.items():
49
53
  module_name, workflow_name = workflow_name.split(":", 1)
50
54
  module = importlib.import_module(module_name)
55
+ if not hasattr(module, workflow_name):
56
+ raise AttributeError(
57
+ f"Module '{module_name}' has no attribute '{workflow_name}'"
58
+ )
51
59
  workflow = getattr(module, workflow_name)
52
60
  if not isinstance(workflow, Workflow):
53
61
  logger.warning(
@@ -67,6 +75,27 @@ def load_environment_variables(config: DeploymentConfig, source_root: Path) -> N
67
75
  os.environ[key] = value
68
76
 
69
77
 
78
+ def validate_required_env_vars(config: DeploymentConfig) -> None:
79
+ """
80
+ Validate that all required environment variables are present and non-empty.
81
+
82
+ Raises:
83
+ RuntimeError: If any required env vars are missing or empty.
84
+ """
85
+ required = config.required_env_vars
86
+ if not required:
87
+ return
88
+ missing = [name for name in required if not os.environ.get(name)]
89
+ if missing:
90
+ missing_list = ", ".join(sorted(missing))
91
+ raise RuntimeError(
92
+ (
93
+ "Missing required environment variables defined in required_env_vars: "
94
+ f"{missing_list}. Provide them via your environment, .env files, or the deployment secrets."
95
+ )
96
+ )
97
+
98
+
70
99
  def parse_environment_variables(
71
100
  config: DeploymentConfig, source_root: Path
72
101
  ) -> dict[str, str]:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: llama-deploy-appserver
3
- Version: 0.3.13
3
+ Version: 0.3.15
4
4
  Summary: Application server components for LlamaDeploy
5
5
  Author: Massimiliano Pippi, Adrian Lyjak
6
6
  Author-email: Massimiliano Pippi <mpippi@gmail.com>, Adrian Lyjak <adrianlyjak@gmail.com>
@@ -9,7 +9,7 @@ Requires-Dist: llama-index-workflows[server]>=2.6.0
9
9
  Requires-Dist: pydantic-settings>=2.10.1
10
10
  Requires-Dist: fastapi>=0.100.0
11
11
  Requires-Dist: websockets>=12.0
12
- Requires-Dist: llama-deploy-core>=0.3.13,<0.4.0
12
+ Requires-Dist: llama-deploy-core>=0.3.15,<0.4.0
13
13
  Requires-Dist: httpx>=0.24.0,<1.0.0
14
14
  Requires-Dist: prometheus-fastapi-instrumentator>=7.1.0
15
15
  Requires-Dist: packaging>=25.0
@@ -1,12 +1,12 @@
1
1
  llama_deploy/appserver/__init__.py,sha256=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855,0
2
- llama_deploy/appserver/app.py,sha256=2fe0264887efa4cde9275da08e59c56438d6ce50d30f5951fd1eb4438260fddc,9562
3
- llama_deploy/appserver/bootstrap.py,sha256=fa32be007f18b4b3af92c878bac417416c9afb09b1beddf51b5cd73115e6b7c6,2453
2
+ llama_deploy/appserver/app.py,sha256=8f45734ee7d3748fefb29d9d8bf987de3fda89834876c32609a72e0bfc8e335b,9694
3
+ llama_deploy/appserver/bootstrap.py,sha256=d0c7b4ad5bd64aa5070d993b1439006694a639010ae757b1d897680318173743,2573
4
4
  llama_deploy/appserver/configure_logging.py,sha256=194dd1ebed3c1d9065d9174f7828d557a577eaac8fb0443b3102430b1f578c19,6329
5
5
  llama_deploy/appserver/correlation_id.py,sha256=8ac5bc6160c707b93a9fb818b64dd369a4ef7a53f9f91a6b3d90c4cf446f7327,572
6
6
  llama_deploy/appserver/deployment.py,sha256=b813ac5abe71940b8535e7c66348192848df14b9cdca2ff2830d0bee60c8a26c,6397
7
7
  llama_deploy/appserver/deployment_config_parser.py,sha256=e2b6c483203d96ab795c4e55df15c694c20458d5a03fab89c2b71e481291a2d3,510
8
8
  llama_deploy/appserver/interrupts.py,sha256=14f262a0cedc00bb3aecd3d6c14c41ba0e88e7d2a6df02cd35b5bea1940822a2,1622
9
- llama_deploy/appserver/process_utils.py,sha256=befee4918c6cf72082dca8bf807afb61ad3d6c83f01bc0c007594b47930570d8,6056
9
+ llama_deploy/appserver/process_utils.py,sha256=5d449008cac17878e30aa0c47748f6b9feddcef72891e1a5190c8d86120fcb36,6297
10
10
  llama_deploy/appserver/py.typed,sha256=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855,0
11
11
  llama_deploy/appserver/routers/__init__.py,sha256=ee2d14ebf4b067c844947ed1cc98186456e8bfa4919282722eaaf8cca345a138,214
12
12
  llama_deploy/appserver/routers/deployments.py,sha256=e7bafd72c1b4b809e5ad57442594a997c85ecab998b8430da65899faa910db1c,7572
@@ -15,10 +15,10 @@ llama_deploy/appserver/routers/ui_proxy.py,sha256=78b334097dc8a14916aa403ffe1a23
15
15
  llama_deploy/appserver/settings.py,sha256=aa4512d2f1f28b8ee7d3fedc8c61f77bce9f807f85857c0f6282054320c9da23,5124
16
16
  llama_deploy/appserver/stats.py,sha256=1f3989f6705a6de3e4d61ee8cdd189fbe04a2c53ec5e720b2e5168acc331427f,691
17
17
  llama_deploy/appserver/types.py,sha256=4edc991aafb6b8497f068d12387455df292da3ff8440223637641ab1632553ec,2133
18
- llama_deploy/appserver/workflow_loader.py,sha256=aa06b3cdc9cdbf7e4c58c1b5bbd28025f56869a0065311aac8e98e729e70d38a,14342
18
+ llama_deploy/appserver/workflow_loader.py,sha256=03ef9d2d5eed6b0ec3e3520a6566163637b6ba99b9fa77ecee8ce0243a211d13,15413
19
19
  llama_deploy/appserver/workflow_store/agent_data_store.py,sha256=c94ab0e0628eb3d6364179e4fbf9467524270cdf38d8d9294494f89c9629a229,4219
20
20
  llama_deploy/appserver/workflow_store/keyed_lock.py,sha256=bb1504d9de09d51a8f60721cc77b14d4051ac5a897ace6f9d9cba494f068465e,950
21
21
  llama_deploy/appserver/workflow_store/lru_cache.py,sha256=7511231b6aba81ea96044cf644cd9c1f11d78190b7b7f578b1b5a55e2c218f9f,1323
22
- llama_deploy_appserver-0.3.13.dist-info/WHEEL,sha256=66530aef82d5020ef5af27ae0123c71abb9261377c5bc519376c671346b12918,79
23
- llama_deploy_appserver-0.3.13.dist-info/METADATA,sha256=ba1697472a56908d3baeec509c9ca88d53ac9c8013bea03f651550ebfe04e3db,1009
24
- llama_deploy_appserver-0.3.13.dist-info/RECORD,,
22
+ llama_deploy_appserver-0.3.15.dist-info/WHEEL,sha256=66530aef82d5020ef5af27ae0123c71abb9261377c5bc519376c671346b12918,79
23
+ llama_deploy_appserver-0.3.15.dist-info/METADATA,sha256=e6ae7c3c54a716122c0a0eabd2bb7f55d1695f70cf78a6f1a357f6a425ff6b9c,1009
24
+ llama_deploy_appserver-0.3.15.dist-info/RECORD,,