llama-deploy-appserver 0.2.7a1__py3-none-any.whl → 0.3.0a2__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.
- llama_deploy/appserver/__main__.py +0 -4
- llama_deploy/appserver/app.py +105 -25
- llama_deploy/appserver/bootstrap.py +76 -24
- llama_deploy/appserver/deployment.py +7 -421
- llama_deploy/appserver/deployment_config_parser.py +35 -59
- llama_deploy/appserver/routers/__init__.py +4 -3
- llama_deploy/appserver/routers/deployments.py +162 -385
- llama_deploy/appserver/routers/status.py +4 -31
- llama_deploy/appserver/routers/ui_proxy.py +213 -0
- llama_deploy/appserver/settings.py +57 -55
- llama_deploy/appserver/types.py +0 -3
- llama_deploy/appserver/workflow_loader.py +383 -0
- {llama_deploy_appserver-0.2.7a1.dist-info → llama_deploy_appserver-0.3.0a2.dist-info}/METADATA +3 -6
- llama_deploy_appserver-0.3.0a2.dist-info/RECORD +17 -0
- {llama_deploy_appserver-0.2.7a1.dist-info → llama_deploy_appserver-0.3.0a2.dist-info}/WHEEL +1 -1
- llama_deploy/appserver/client/__init__.py +0 -3
- llama_deploy/appserver/client/base.py +0 -30
- llama_deploy/appserver/client/client.py +0 -49
- llama_deploy/appserver/client/models/__init__.py +0 -4
- llama_deploy/appserver/client/models/apiserver.py +0 -356
- llama_deploy/appserver/client/models/model.py +0 -82
- llama_deploy/appserver/run_autodeploy.py +0 -141
- llama_deploy/appserver/server.py +0 -60
- llama_deploy/appserver/source_managers/__init__.py +0 -5
- llama_deploy/appserver/source_managers/base.py +0 -33
- llama_deploy/appserver/source_managers/git.py +0 -48
- llama_deploy/appserver/source_managers/local.py +0 -51
- llama_deploy/appserver/tracing.py +0 -237
- llama_deploy_appserver-0.2.7a1.dist-info/RECORD +0 -28
@@ -1,12 +1,8 @@
|
|
1
1
|
import uvicorn
|
2
|
-
from prometheus_client import start_http_server
|
3
2
|
|
4
3
|
from .settings import settings
|
5
4
|
|
6
5
|
if __name__ == "__main__":
|
7
|
-
if settings.prometheus_enabled:
|
8
|
-
start_http_server(settings.prometheus_port)
|
9
|
-
|
10
6
|
uvicorn.run(
|
11
7
|
"llama_deploy.appserver.app:app",
|
12
8
|
host=settings.host,
|
llama_deploy/appserver/app.py
CHANGED
@@ -1,24 +1,75 @@
|
|
1
1
|
import logging
|
2
2
|
import os
|
3
|
+
from pathlib import Path
|
4
|
+
import threading
|
5
|
+
import time
|
6
|
+
from llama_deploy.appserver.deployment_config_parser import (
|
7
|
+
get_deployment_config,
|
8
|
+
)
|
9
|
+
from llama_deploy.appserver.settings import configure_settings, settings
|
3
10
|
|
4
11
|
from fastapi import FastAPI
|
5
12
|
from fastapi.middleware.cors import CORSMiddleware
|
6
|
-
from
|
7
|
-
|
13
|
+
from llama_deploy.appserver.workflow_loader import (
|
14
|
+
build_ui,
|
15
|
+
do_install,
|
16
|
+
start_dev_ui_process,
|
17
|
+
)
|
18
|
+
import uvicorn
|
8
19
|
|
9
|
-
from .routers import
|
10
|
-
from
|
11
|
-
from
|
12
|
-
from
|
20
|
+
from .routers import health_router
|
21
|
+
from prometheus_fastapi_instrumentator import Instrumentator
|
22
|
+
from contextlib import asynccontextmanager
|
23
|
+
from typing import Any, AsyncGenerator
|
13
24
|
|
25
|
+
from llama_deploy.appserver.routers.deployments import (
|
26
|
+
create_base_router,
|
27
|
+
create_deployments_router,
|
28
|
+
)
|
29
|
+
from llama_deploy.appserver.routers.ui_proxy import (
|
30
|
+
create_ui_proxy_router,
|
31
|
+
mount_static_files,
|
32
|
+
)
|
33
|
+
from llama_deploy.appserver.workflow_loader import (
|
34
|
+
load_workflows,
|
35
|
+
)
|
36
|
+
|
37
|
+
from .deployment import Deployment
|
38
|
+
from .stats import apiserver_state
|
39
|
+
import webbrowser
|
14
40
|
|
15
41
|
logger = logging.getLogger("uvicorn.info")
|
16
42
|
|
17
43
|
|
18
|
-
|
44
|
+
@asynccontextmanager
|
45
|
+
async def lifespan(app: FastAPI) -> AsyncGenerator[None, Any]:
|
46
|
+
apiserver_state.state("starting")
|
47
|
+
|
48
|
+
config = get_deployment_config()
|
49
|
+
|
50
|
+
workflows = load_workflows(config)
|
51
|
+
deployment = Deployment(workflows)
|
52
|
+
base_router = create_base_router(config.name)
|
53
|
+
deploy_router = create_deployments_router(config.name, deployment)
|
54
|
+
app.include_router(base_router)
|
55
|
+
app.include_router(deploy_router)
|
56
|
+
# proxy UI in dev mode
|
57
|
+
if config.ui is not None:
|
58
|
+
if settings.proxy_ui:
|
59
|
+
ui_router = create_ui_proxy_router(config.name, config.ui.port)
|
60
|
+
app.include_router(ui_router)
|
61
|
+
else:
|
62
|
+
# otherwise serve the pre-built if available
|
63
|
+
mount_static_files(app, config, settings)
|
64
|
+
|
65
|
+
apiserver_state.state("running")
|
66
|
+
yield
|
67
|
+
|
68
|
+
apiserver_state.state("stopped")
|
69
|
+
|
19
70
|
|
20
|
-
|
21
|
-
|
71
|
+
app = FastAPI(lifespan=lifespan)
|
72
|
+
Instrumentator().instrument(app).expose(app)
|
22
73
|
|
23
74
|
# Configure CORS middleware if the environment variable is set
|
24
75
|
if not os.environ.get("DISABLE_CORS", False):
|
@@ -30,20 +81,49 @@ if not os.environ.get("DISABLE_CORS", False):
|
|
30
81
|
allow_headers=["Content-Type", "Authorization"],
|
31
82
|
)
|
32
83
|
|
33
|
-
app.include_router(
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
}
|
84
|
+
app.include_router(health_router)
|
85
|
+
|
86
|
+
|
87
|
+
def start_server(
|
88
|
+
proxy_ui: bool = False,
|
89
|
+
reload: bool = False,
|
90
|
+
cwd: Path | None = None,
|
91
|
+
deployment_file: Path | None = None,
|
92
|
+
install: bool = False,
|
93
|
+
build: bool = False,
|
94
|
+
open_browser: bool = False,
|
95
|
+
) -> None:
|
96
|
+
# Configure via environment so uvicorn reload workers inherit the values
|
97
|
+
configure_settings(
|
98
|
+
proxy_ui=proxy_ui, app_root=cwd, deployment_file_path=deployment_file
|
49
99
|
)
|
100
|
+
if install:
|
101
|
+
do_install()
|
102
|
+
if build:
|
103
|
+
build_ui(settings.config_parent, get_deployment_config())
|
104
|
+
|
105
|
+
ui_process = None
|
106
|
+
if proxy_ui:
|
107
|
+
ui_process = start_dev_ui_process(
|
108
|
+
settings.config_parent, settings.port, get_deployment_config()
|
109
|
+
)
|
110
|
+
try:
|
111
|
+
if open_browser:
|
112
|
+
|
113
|
+
def open_with_delay():
|
114
|
+
time.sleep(1)
|
115
|
+
webbrowser.open(f"http://{settings.host}:{settings.port}")
|
116
|
+
|
117
|
+
threading.Thread(
|
118
|
+
target=open_with_delay,
|
119
|
+
).start()
|
120
|
+
|
121
|
+
uvicorn.run(
|
122
|
+
"llama_deploy.appserver.app:app",
|
123
|
+
host=settings.host,
|
124
|
+
port=settings.port,
|
125
|
+
reload=reload,
|
126
|
+
)
|
127
|
+
finally:
|
128
|
+
if ui_process is not None:
|
129
|
+
ui_process.terminate()
|
@@ -4,40 +4,92 @@ Bootstraps an application from a remote github repository given environment vari
|
|
4
4
|
This just sets up the files from the repository. It's more of a build process, does not start an application.
|
5
5
|
"""
|
6
6
|
|
7
|
-
import
|
7
|
+
import os
|
8
|
+
from pathlib import Path
|
9
|
+
from llama_deploy.appserver.settings import settings
|
10
|
+
from llama_deploy.appserver.deployment_config_parser import get_deployment_config
|
11
|
+
from llama_deploy.appserver.workflow_loader import build_ui, do_install
|
8
12
|
from llama_deploy.core.git.git_util import (
|
9
13
|
clone_repo,
|
10
14
|
)
|
11
|
-
from
|
12
|
-
from
|
15
|
+
from llama_deploy.appserver.app import start_server
|
16
|
+
from llama_deploy.appserver.settings import BootstrapSettings, configure_settings
|
13
17
|
|
18
|
+
import argparse
|
14
19
|
|
15
|
-
class BootstrapSettings(BaseSettings):
|
16
|
-
model_config = SettingsConfigDict(env_prefix="LLAMA_DEPLOY_")
|
17
|
-
git_url: str = Field(..., description="The URL of the git repository to clone")
|
18
|
-
git_token: str | None = Field(
|
19
|
-
default=None, description="The token to use to clone the git repository"
|
20
|
-
)
|
21
|
-
git_ref: str | None = Field(
|
22
|
-
default=None, description="The git reference to checkout"
|
23
|
-
)
|
24
|
-
git_sha: str | None = Field(default=None, description="The git SHA to checkout")
|
25
|
-
deployment_file_path: str = Field(
|
26
|
-
default="llama_deploy.yaml", description="The path to the deployment file"
|
27
|
-
)
|
28
|
-
deployment_name: str | None = Field(
|
29
|
-
default=None, description="The name of the deployment"
|
30
|
-
)
|
31
20
|
|
32
|
-
|
33
|
-
|
34
|
-
|
21
|
+
def bootstrap_app_from_repo(
|
22
|
+
clone: bool = False,
|
23
|
+
build: bool = False,
|
24
|
+
serve: bool = False,
|
25
|
+
target_dir: str = "/opt/app/",
|
26
|
+
):
|
27
|
+
bootstrap_settings = BootstrapSettings()
|
35
28
|
# Needs the github url+auth, and the deployment file path
|
36
29
|
# clones the repo to a standard directory
|
37
30
|
# (eventually) runs the UI build process and moves that to a standard directory for a file server
|
38
|
-
|
31
|
+
if clone:
|
32
|
+
repo_url = bootstrap_settings.repo_url
|
33
|
+
if repo_url is None:
|
34
|
+
raise ValueError("repo_url is required to bootstrap")
|
35
|
+
clone_repo(
|
36
|
+
repository_url=repo_url,
|
37
|
+
git_ref=bootstrap_settings.git_sha or bootstrap_settings.git_ref,
|
38
|
+
basic_auth=bootstrap_settings.auth_token,
|
39
|
+
dest_dir=target_dir,
|
40
|
+
)
|
41
|
+
# Ensure target_dir exists locally when running tests outside a container
|
42
|
+
os.makedirs(target_dir, exist_ok=True)
|
43
|
+
os.chdir(target_dir)
|
44
|
+
configure_settings(
|
45
|
+
app_root=Path(target_dir),
|
46
|
+
deployment_file_path=Path(bootstrap_settings.deployment_file_path),
|
47
|
+
)
|
48
|
+
|
49
|
+
built = True
|
50
|
+
if build:
|
51
|
+
do_install()
|
52
|
+
built = build_ui(settings.config_parent, get_deployment_config())
|
53
|
+
|
54
|
+
if serve:
|
55
|
+
start_server(
|
56
|
+
proxy_ui=not built,
|
57
|
+
)
|
39
58
|
pass
|
40
59
|
|
41
60
|
|
42
61
|
if __name__ == "__main__":
|
43
|
-
|
62
|
+
parser = argparse.ArgumentParser()
|
63
|
+
parser.add_argument(
|
64
|
+
"--clone",
|
65
|
+
action=argparse.BooleanOptionalAction,
|
66
|
+
default=False,
|
67
|
+
help="Clone the repository before bootstrapping (use --no-clone to disable)",
|
68
|
+
)
|
69
|
+
parser.add_argument(
|
70
|
+
"--build",
|
71
|
+
action=argparse.BooleanOptionalAction,
|
72
|
+
default=False,
|
73
|
+
help="Build the UI/assets (use --no-build to disable)",
|
74
|
+
)
|
75
|
+
parser.add_argument(
|
76
|
+
"--serve",
|
77
|
+
action=argparse.BooleanOptionalAction,
|
78
|
+
default=False,
|
79
|
+
help="Start the API server after bootstrap (use --no-serve to disable)",
|
80
|
+
)
|
81
|
+
args = parser.parse_args()
|
82
|
+
try:
|
83
|
+
bootstrap_app_from_repo(
|
84
|
+
clone=args.clone,
|
85
|
+
build=args.build,
|
86
|
+
serve=args.serve,
|
87
|
+
)
|
88
|
+
except Exception as e:
|
89
|
+
import logging
|
90
|
+
|
91
|
+
logging.exception("Error during bootstrap. Pausing for debugging.")
|
92
|
+
import time
|
93
|
+
|
94
|
+
time.sleep(1000000)
|
95
|
+
raise e
|