Skip to content

Commit f8f2f7f

Browse files
authored
feat: Add HTTPS serving option (#1000)
# What does this PR do? Enables HTTPS option for Llama Stack. While doing so, introduces a `ServerConfig` sub-structure to house all server related configuration (port, ssl, etc.) Also simplified the `start_container.sh` entrypoint to simply be `python` instead of a complex bash command line. ## Test Plan Conda: Run: ```bash $ llama stack build --template together $ llama stack run --port 8322 # ensure server starts $ llama-stack-client configure --endpoint http://localhost:8322 $ llama-stack-client models list ``` Create a self-signed SSL key / cert pair. Then, using a local checkout of `llama-stack-client-python`, change https://github.com/meta-llama/llama-stack-client-python/blob/main/src/llama_stack_client/_base_client.py#L759 to add `kwargs.setdefault("verify", False)` so SSL verification is disabled. Then: ```bash $ llama stack run --port 8322 --tls-keyfile <KEYFILE> --tls-certfile <CERTFILE> $ llama-stack-client configure --endpoint https://localhost:8322 # notice the `https` $ llama-stack-client models list ``` Also tested with containers (but of course one needs to make sure the cert and key files are appropriately provided to the container.)
1 parent c97e05f commit f8f2f7f

File tree

5 files changed

+88
-6
lines changed

5 files changed

+88
-6
lines changed

llama_stack/cli/stack/run.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,16 @@ def _add_arguments(self):
5555
default=[],
5656
metavar="KEY=VALUE",
5757
)
58+
self.parser.add_argument(
59+
"--tls-keyfile",
60+
type=str,
61+
help="Path to TLS key file for HTTPS",
62+
)
63+
self.parser.add_argument(
64+
"--tls-certfile",
65+
type=str,
66+
help="Path to TLS certificate file for HTTPS",
67+
)
5868

5969
def _run_stack_run_cmd(self, args: argparse.Namespace) -> None:
6070
import importlib.resources
@@ -178,4 +188,7 @@ def get_conda_prefix(env_name):
178188
return
179189
run_args.extend(["--env", f"{key}={value}"])
180190

191+
if args.tls_keyfile and args.tls_certfile:
192+
run_args.extend(["--tls-keyfile", args.tls_keyfile, "--tls-certfile", args.tls_certfile])
193+
181194
run_with_pty(run_args)

llama_stack/distribution/datatypes.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,23 @@ class Provider(BaseModel):
117117
config: Dict[str, Any]
118118

119119

120+
class ServerConfig(BaseModel):
121+
port: int = Field(
122+
default=8321,
123+
description="Port to listen on",
124+
ge=1024,
125+
le=65535,
126+
)
127+
tls_certfile: Optional[str] = Field(
128+
default=None,
129+
description="Path to TLS certificate file for HTTPS",
130+
)
131+
tls_keyfile: Optional[str] = Field(
132+
default=None,
133+
description="Path to TLS key file for HTTPS",
134+
)
135+
136+
120137
class StackRunConfig(BaseModel):
121138
version: str = LLAMA_STACK_RUN_CONFIG_VERSION
122139

@@ -159,6 +176,11 @@ class StackRunConfig(BaseModel):
159176
eval_tasks: List[EvalTaskInput] = Field(default_factory=list)
160177
tool_groups: List[ToolGroupInput] = Field(default_factory=list)
161178

179+
server: ServerConfig = Field(
180+
default_factory=ServerConfig,
181+
description="Configuration for the HTTP(S) server",
182+
)
183+
162184

163185
class BuildConfig(BaseModel):
164186
version: str = LLAMA_STACK_BUILD_CONFIG_VERSION

llama_stack/distribution/server/server.py

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -282,8 +282,19 @@ def main():
282282
action="append",
283283
help="Environment variables in KEY=value format. Can be specified multiple times.",
284284
)
285+
parser.add_argument(
286+
"--tls-keyfile",
287+
help="Path to TLS key file for HTTPS",
288+
required="--tls-certfile" in sys.argv,
289+
)
290+
parser.add_argument(
291+
"--tls-certfile",
292+
help="Path to TLS certificate file for HTTPS",
293+
required="--tls-keyfile" in sys.argv,
294+
)
285295

286296
args = parser.parse_args()
297+
287298
if args.env:
288299
for env_pair in args.env:
289300
try:
@@ -381,11 +392,36 @@ def main():
381392

382393
import uvicorn
383394

384-
# FYI this does not do hot-reloads
395+
# Configure SSL if certificates are provided
396+
port = args.port or config.server.port
397+
398+
ssl_config = None
399+
if args.tls_keyfile:
400+
keyfile = args.tls_keyfile
401+
certfile = args.tls_certfile
402+
else:
403+
keyfile = config.server.tls_keyfile
404+
certfile = config.server.tls_certfile
405+
406+
if keyfile and certfile:
407+
ssl_config = {
408+
"ssl_keyfile": keyfile,
409+
"ssl_certfile": certfile,
410+
}
411+
print(f"HTTPS enabled with certificates:\n Key: {keyfile}\n Cert: {certfile}")
385412

386413
listen_host = ["::", "0.0.0.0"] if not args.disable_ipv6 else "0.0.0.0"
387-
print(f"Listening on {listen_host}:{args.port}")
388-
uvicorn.run(app, host=listen_host, port=args.port)
414+
print(f"Listening on {listen_host}:{port}")
415+
416+
uvicorn_config = {
417+
"app": app,
418+
"host": listen_host,
419+
"port": port,
420+
}
421+
if ssl_config:
422+
uvicorn_config.update(ssl_config)
423+
424+
uvicorn.run(**uvicorn_config)
389425

390426

391427
def extract_path_params(route: str) -> List[str]:

llama_stack/distribution/start_conda_env.sh

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ shift
3434

3535
# Process environment variables from --env arguments
3636
env_vars=""
37+
other_args=""
3738
while [[ $# -gt 0 ]]; do
3839
case "$1" in
3940
--env)
@@ -48,6 +49,7 @@ while [[ $# -gt 0 ]]; do
4849
fi
4950
;;
5051
*)
52+
other_args="$other_args $1"
5153
shift
5254
;;
5355
esac
@@ -61,4 +63,5 @@ $CONDA_PREFIX/bin/python \
6163
-m llama_stack.distribution.server.server \
6264
--yaml-config "$yaml_config" \
6365
--port "$port" \
64-
$env_vars
66+
$env_vars \
67+
$other_args

llama_stack/distribution/start_container.sh

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,12 @@ shift
4040
port="$1"
4141
shift
4242

43+
# Initialize other_args
44+
other_args=""
45+
4346
# Process environment variables from --env arguments
4447
env_vars=""
48+
4549
while [[ $# -gt 0 ]]; do
4650
case "$1" in
4751
--env)
@@ -55,6 +59,7 @@ while [[ $# -gt 0 ]]; do
5559
fi
5660
;;
5761
*)
62+
other_args="$other_args $1"
5863
shift
5964
;;
6065
esac
@@ -93,5 +98,8 @@ $CONTAINER_BINARY run $CONTAINER_OPTS -it \
9398
-v "$yaml_config:/app/config.yaml" \
9499
$mounts \
95100
--env LLAMA_STACK_PORT=$port \
96-
--entrypoint='["python", "-m", "llama_stack.distribution.server.server", "--yaml-config", "/app/config.yaml"]' \
97-
$container_image:$version_tag
101+
--entrypoint python \
102+
$container_image:$version_tag \
103+
-m llama_stack.distribution.server.server \
104+
--yaml-config /app/config.yaml \
105+
$other_args

0 commit comments

Comments
 (0)