mirror of
https://github.com/meta-llama/llama-stack.git
synced 2025-06-28 02:53:30 +00:00
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.)
This commit is contained in:
parent
c97e05f75e
commit
f8f2f7f9bb
5 changed files with 88 additions and 6 deletions
|
@ -55,6 +55,16 @@ class StackRun(Subcommand):
|
||||||
default=[],
|
default=[],
|
||||||
metavar="KEY=VALUE",
|
metavar="KEY=VALUE",
|
||||||
)
|
)
|
||||||
|
self.parser.add_argument(
|
||||||
|
"--tls-keyfile",
|
||||||
|
type=str,
|
||||||
|
help="Path to TLS key file for HTTPS",
|
||||||
|
)
|
||||||
|
self.parser.add_argument(
|
||||||
|
"--tls-certfile",
|
||||||
|
type=str,
|
||||||
|
help="Path to TLS certificate file for HTTPS",
|
||||||
|
)
|
||||||
|
|
||||||
def _run_stack_run_cmd(self, args: argparse.Namespace) -> None:
|
def _run_stack_run_cmd(self, args: argparse.Namespace) -> None:
|
||||||
import importlib.resources
|
import importlib.resources
|
||||||
|
@ -178,4 +188,7 @@ class StackRun(Subcommand):
|
||||||
return
|
return
|
||||||
run_args.extend(["--env", f"{key}={value}"])
|
run_args.extend(["--env", f"{key}={value}"])
|
||||||
|
|
||||||
|
if args.tls_keyfile and args.tls_certfile:
|
||||||
|
run_args.extend(["--tls-keyfile", args.tls_keyfile, "--tls-certfile", args.tls_certfile])
|
||||||
|
|
||||||
run_with_pty(run_args)
|
run_with_pty(run_args)
|
||||||
|
|
|
@ -117,6 +117,23 @@ class Provider(BaseModel):
|
||||||
config: Dict[str, Any]
|
config: Dict[str, Any]
|
||||||
|
|
||||||
|
|
||||||
|
class ServerConfig(BaseModel):
|
||||||
|
port: int = Field(
|
||||||
|
default=8321,
|
||||||
|
description="Port to listen on",
|
||||||
|
ge=1024,
|
||||||
|
le=65535,
|
||||||
|
)
|
||||||
|
tls_certfile: Optional[str] = Field(
|
||||||
|
default=None,
|
||||||
|
description="Path to TLS certificate file for HTTPS",
|
||||||
|
)
|
||||||
|
tls_keyfile: Optional[str] = Field(
|
||||||
|
default=None,
|
||||||
|
description="Path to TLS key file for HTTPS",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class StackRunConfig(BaseModel):
|
class StackRunConfig(BaseModel):
|
||||||
version: str = LLAMA_STACK_RUN_CONFIG_VERSION
|
version: str = LLAMA_STACK_RUN_CONFIG_VERSION
|
||||||
|
|
||||||
|
@ -159,6 +176,11 @@ a default SQLite store will be used.""",
|
||||||
eval_tasks: List[EvalTaskInput] = Field(default_factory=list)
|
eval_tasks: List[EvalTaskInput] = Field(default_factory=list)
|
||||||
tool_groups: List[ToolGroupInput] = Field(default_factory=list)
|
tool_groups: List[ToolGroupInput] = Field(default_factory=list)
|
||||||
|
|
||||||
|
server: ServerConfig = Field(
|
||||||
|
default_factory=ServerConfig,
|
||||||
|
description="Configuration for the HTTP(S) server",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class BuildConfig(BaseModel):
|
class BuildConfig(BaseModel):
|
||||||
version: str = LLAMA_STACK_BUILD_CONFIG_VERSION
|
version: str = LLAMA_STACK_BUILD_CONFIG_VERSION
|
||||||
|
|
|
@ -282,8 +282,19 @@ def main():
|
||||||
action="append",
|
action="append",
|
||||||
help="Environment variables in KEY=value format. Can be specified multiple times.",
|
help="Environment variables in KEY=value format. Can be specified multiple times.",
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--tls-keyfile",
|
||||||
|
help="Path to TLS key file for HTTPS",
|
||||||
|
required="--tls-certfile" in sys.argv,
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--tls-certfile",
|
||||||
|
help="Path to TLS certificate file for HTTPS",
|
||||||
|
required="--tls-keyfile" in sys.argv,
|
||||||
|
)
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
if args.env:
|
if args.env:
|
||||||
for env_pair in args.env:
|
for env_pair in args.env:
|
||||||
try:
|
try:
|
||||||
|
@ -381,11 +392,36 @@ def main():
|
||||||
|
|
||||||
import uvicorn
|
import uvicorn
|
||||||
|
|
||||||
# FYI this does not do hot-reloads
|
# Configure SSL if certificates are provided
|
||||||
|
port = args.port or config.server.port
|
||||||
|
|
||||||
|
ssl_config = None
|
||||||
|
if args.tls_keyfile:
|
||||||
|
keyfile = args.tls_keyfile
|
||||||
|
certfile = args.tls_certfile
|
||||||
|
else:
|
||||||
|
keyfile = config.server.tls_keyfile
|
||||||
|
certfile = config.server.tls_certfile
|
||||||
|
|
||||||
|
if keyfile and certfile:
|
||||||
|
ssl_config = {
|
||||||
|
"ssl_keyfile": keyfile,
|
||||||
|
"ssl_certfile": certfile,
|
||||||
|
}
|
||||||
|
print(f"HTTPS enabled with certificates:\n Key: {keyfile}\n Cert: {certfile}")
|
||||||
|
|
||||||
listen_host = ["::", "0.0.0.0"] if not args.disable_ipv6 else "0.0.0.0"
|
listen_host = ["::", "0.0.0.0"] if not args.disable_ipv6 else "0.0.0.0"
|
||||||
print(f"Listening on {listen_host}:{args.port}")
|
print(f"Listening on {listen_host}:{port}")
|
||||||
uvicorn.run(app, host=listen_host, port=args.port)
|
|
||||||
|
uvicorn_config = {
|
||||||
|
"app": app,
|
||||||
|
"host": listen_host,
|
||||||
|
"port": port,
|
||||||
|
}
|
||||||
|
if ssl_config:
|
||||||
|
uvicorn_config.update(ssl_config)
|
||||||
|
|
||||||
|
uvicorn.run(**uvicorn_config)
|
||||||
|
|
||||||
|
|
||||||
def extract_path_params(route: str) -> List[str]:
|
def extract_path_params(route: str) -> List[str]:
|
||||||
|
|
|
@ -34,6 +34,7 @@ shift
|
||||||
|
|
||||||
# Process environment variables from --env arguments
|
# Process environment variables from --env arguments
|
||||||
env_vars=""
|
env_vars=""
|
||||||
|
other_args=""
|
||||||
while [[ $# -gt 0 ]]; do
|
while [[ $# -gt 0 ]]; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
--env)
|
--env)
|
||||||
|
@ -48,6 +49,7 @@ while [[ $# -gt 0 ]]; do
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
|
other_args="$other_args $1"
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
@ -61,4 +63,5 @@ $CONDA_PREFIX/bin/python \
|
||||||
-m llama_stack.distribution.server.server \
|
-m llama_stack.distribution.server.server \
|
||||||
--yaml-config "$yaml_config" \
|
--yaml-config "$yaml_config" \
|
||||||
--port "$port" \
|
--port "$port" \
|
||||||
$env_vars
|
$env_vars \
|
||||||
|
$other_args
|
||||||
|
|
|
@ -40,8 +40,12 @@ shift
|
||||||
port="$1"
|
port="$1"
|
||||||
shift
|
shift
|
||||||
|
|
||||||
|
# Initialize other_args
|
||||||
|
other_args=""
|
||||||
|
|
||||||
# Process environment variables from --env arguments
|
# Process environment variables from --env arguments
|
||||||
env_vars=""
|
env_vars=""
|
||||||
|
|
||||||
while [[ $# -gt 0 ]]; do
|
while [[ $# -gt 0 ]]; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
--env)
|
--env)
|
||||||
|
@ -55,6 +59,7 @@ while [[ $# -gt 0 ]]; do
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
|
other_args="$other_args $1"
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
@ -93,5 +98,8 @@ $CONTAINER_BINARY run $CONTAINER_OPTS -it \
|
||||||
-v "$yaml_config:/app/config.yaml" \
|
-v "$yaml_config:/app/config.yaml" \
|
||||||
$mounts \
|
$mounts \
|
||||||
--env LLAMA_STACK_PORT=$port \
|
--env LLAMA_STACK_PORT=$port \
|
||||||
--entrypoint='["python", "-m", "llama_stack.distribution.server.server", "--yaml-config", "/app/config.yaml"]' \
|
--entrypoint python \
|
||||||
$container_image:$version_tag
|
$container_image:$version_tag \
|
||||||
|
-m llama_stack.distribution.server.server \
|
||||||
|
--yaml-config /app/config.yaml \
|
||||||
|
$other_args
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue