Unverified Commit 836d7417 authored by Anant Sharma's avatar Anant Sharma Committed by GitHub
Browse files

feat: restructure source code for python packaging (#3201)


Signed-off-by: default avatarAnant Sharma <anants@nvidia.com>
parent 4e38d628
......@@ -216,22 +216,13 @@ RUN --mount=type=bind,source=./container/launch_message.txt,target=/workspace/la
sed '/^#\s/d' /workspace/launch_message.txt > ~/.launch_screen && \
echo "cat ~/.launch_screen" >> ~/.bashrc
# Once UX refactor is merged, we can remove these files
# Python components will have been pip installed and packaged in wheel
COPY components/ /workspace/components/
# Copy benchmarks, examples, and tests for CI
# TODO: Remove this once we have a functional CI image built on top of the runtime image
# Copy tests, benchmarks, deploy and components for CI
COPY tests /workspace/tests
COPY benchmarks /workspace/benchmarks
COPY examples /workspace/examples
COPY deploy /workspace/deploy
RUN uv pip install /workspace/benchmarks
COPY components/ /workspace/components/
# Copy benchmarks, backends and tests for CI
COPY tests /workspace/tests
COPY benchmarks /workspace/benchmarks
COPY deploy /workspace/deploy
COPY components/backends/sglang /workspace/components/backends/sglang
# Copy attribution files
COPY ATTRIBUTION* LICENSE /workspace/
......@@ -303,12 +294,12 @@ COPY --from=dynamo_base /usr/local/cargo /usr/local/cargo
COPY --from=runtime ${VIRTUAL_ENV} ${VIRTUAL_ENV}
# so we can use maturin develop
# Install maturin, for maturin develop
RUN uv pip install maturin[patchelf]
# Make sure to sync this with the one specified on README.md.
# This is a generic PYTHONPATH which works for all the frameworks, so some paths may not be relevant for this particular framework.
ENV PYTHONPATH=${WORKSPACE_DIR}/components/metrics/src:${WORKSPACE_DIR}/components/frontend/src:${WORKSPACE_DIR}/components/planner/src:${WORKSPACE_DIR}/components/backends/mocker/src:${WORKSPACE_DIR}/components/backends/trtllm/src:${WORKSPACE_DIR}/components/backends/vllm/src:${WORKSPACE_DIR}/components/backends/sglang/src:${WORKSPACE_DIR}/components/backends/llama_cpp/src
# Editable install of dynamo
COPY pyproject.toml README.md hatch_build.py /workspace/
RUN uv pip install --no-deps -e .
ENTRYPOINT ["/opt/nvidia/nvidia_entrypoint.sh"]
CMD []
\ No newline at end of file
......@@ -332,11 +332,11 @@ COPY --from=dynamo_base /usr/local/cargo /usr/local/cargo
COPY --from=runtime ${VIRTUAL_ENV} ${VIRTUAL_ENV}
# so we can use maturin develop
# Install maturin, for maturin develop
RUN uv pip install maturin[patchelf]
# Make sure to sync this with the one specified on README.md.
# This is a generic PYTHONPATH which works for all the frameworks, so some paths may not be relevant for this particular framework.
ENV PYTHONPATH=${WORKSPACE_DIR}:${WORKSPACE_DIR}/components/metrics/src:${WORKSPACE_DIR}/components/frontend/src:${WORKSPACE_DIR}/components/planner/src:${WORKSPACE_DIR}/components/backends/mocker/src:${WORKSPACE_DIR}/components/backends/trtllm/src:${WORKSPACE_DIR}/components/backends/vllm/src:${WORKSPACE_DIR}/components/backends/sglang/src:${WORKSPACE_DIR}/components/backends/llama_cpp/src
# Editable install of dynamo
COPY pyproject.toml README.md hatch_build.py /workspace/
RUN uv pip install --no-deps -e .
CMD []
\ No newline at end of file
......@@ -337,12 +337,10 @@ COPY --from=dynamo_base /usr/local/cargo /usr/local/cargo
# Much better than chown -R $USERNAME:$USERNAME /opt/dynamo/venv (~10min on my cpu)
COPY --from=runtime ${VIRTUAL_ENV} ${VIRTUAL_ENV}
# so we can use maturin develop
RUN uv pip install maturin[patchelf]
# Make sure to sync this with the one specified on README.md.
# This is a generic PYTHONPATH which works for all the frameworks, so some paths may not be relevant for this particular framework.
ENV PYTHONPATH=${WORKSPACE_DIR}/components/metrics/src:${WORKSPACE_DIR}/components/frontend/src:${WORKSPACE_DIR}/components/planner/src:${WORKSPACE_DIR}/components/backends/mocker/src:${WORKSPACE_DIR}/components/backends/trtllm/src:${WORKSPACE_DIR}/components/backends/vllm/src:${WORKSPACE_DIR}/components/backends/sglang/src:${WORKSPACE_DIR}/components/backends/llama_cpp/src
# Install maturin, for maturin develop
# Editable install of dynamo
RUN uv pip install maturin[patchelf] && \
uv pip install --no-deps -e .
ENTRYPOINT ["/opt/nvidia/nvidia_entrypoint.sh"]
CMD []
\ No newline at end of file
......@@ -2011,29 +2011,14 @@ class DynamoFrameworkInfo(NodeInfo):
if not workspace_dir:
return components
# Scan components directory (frontend, planner, etc.)
components_path = os.path.join(workspace_dir, "components")
# Scan components python src directory (frontend, planner, etc.)
components_path = os.path.join(workspace_dir, "components", "src", "dynamo")
if os.path.exists(components_path):
for item in os.listdir(components_path):
item_path = os.path.join(components_path, item)
if os.path.isdir(item_path):
# Check for dynamo module in src
module_path = os.path.join(
item_path, "src", "dynamo", item, "__init__.py"
)
if os.path.exists(module_path):
components.append(f"dynamo.{item}")
# Scan backends directory (vllm, sglang, trtllm, etc.)
backends_path = os.path.join(workspace_dir, "components", "backends")
if os.path.exists(backends_path):
for item in os.listdir(backends_path):
item_path = os.path.join(backends_path, item)
if os.path.isdir(item_path):
# Check for dynamo module in src
module_path = os.path.join(
item_path, "src", "dynamo", item, "__init__.py"
)
module_path = os.path.join(item_path, "__init__.py")
if os.path.exists(module_path):
components.append(f"dynamo.{item}")
......@@ -2228,20 +2213,9 @@ def show_pythonpath_recommendation():
# Collect all component source paths
comp_path = os.path.join(workspace_dir, "components")
if os.path.exists(comp_path):
for item in os.listdir(comp_path):
if item == "backends":
continue # Handle backends separately
src_path = os.path.join(comp_path, item, "src")
if os.path.exists(src_path):
paths.append(src_path)
# Collect all backend source paths
backend_path = os.path.join(workspace_dir, "components", "backends")
if os.path.exists(backend_path):
for item in os.listdir(backend_path):
src_path = os.path.join(backend_path, item, "src")
if os.path.exists(src_path):
paths.append(src_path)
src_path = os.path.join(comp_path, "src")
if os.path.exists(src_path):
paths.append(src_path)
# Also add runtime path
runtime_path = os.path.join(workspace_dir, "lib/bindings/python/src")
......
......@@ -38,7 +38,7 @@
"cwd": "${workspaceFolder}",
"env": {
"RUST_BACKTRACE": "1",
"PYTHONPATH": "${env:PYTHONPATH}:${workspaceFolder}/components/frontend/src:${workspaceFolder}/components/planner/src:${workspaceFolder}/components/backends/llama_cpp/src:${workspaceFolder}/components/backends/mocker/src:${workspaceFolder}/components/backends/trtllm/src:${workspaceFolder}/components/backends/sglang/src:${workspaceFolder}/components/backends/vllm/src"
"PYTHONPATH": "${env:PYTHONPATH}:${workspaceFolder}/components/src"
},
"sourceLanguages": [
"rust"
......@@ -63,7 +63,7 @@
"cwd": "${workspaceFolder}",
"env": {
"RUST_BACKTRACE": "1",
"PYTHONPATH": "${env:PYTHONPATH}:${workspaceFolder}/components/frontend/src:${workspaceFolder}/components/planner/src:${workspaceFolder}/components/backends/llama_cpp/src:${workspaceFolder}/components/backends/mocker/src:${workspaceFolder}/components/backends/trtllm/src:${workspaceFolder}/components/backends/sglang/src:${workspaceFolder}/components/backends/vllm/src"
"PYTHONPATH": "${env:PYTHONPATH}:${workspaceFolder}/components/src"
},
"sourceLanguages": [
"rust"
......
......@@ -36,9 +36,9 @@ docker compose -f deploy/metrics/docker-compose.yml up -d
## Components
- [Frontend](../../../components/frontend/README.md) - HTTP API endpoint that receives requests and forwards them to the decode worker
- [vLLM Prefill Worker](../../../components/backends/vllm/README.md) - Specialized worker for prefill phase execution
- [vLLM Decode Worker](../../../components/backends/vllm/README.md) - Specialized worker that handles requests and decides between local/remote prefill
- [Frontend](/components/src/dynamo/frontend/README.md) - HTTP API endpoint that receives requests and forwards them to the decode worker
- [vLLM Prefill Worker](/components/backends/vllm/README.md) - Specialized worker for prefill phase execution
- [vLLM Decode Worker](/components/backends/vllm/README.md) - Specialized worker that handles requests and decides between local/remote prefill
```mermaid
---
......
......@@ -217,7 +217,7 @@ The frontend will:
- Enable KV-aware routing for intelligent request distribution
- Monitor worker health and adjust routing accordingly
For more details about frontend configuration options, see the [Frontend Component Documentation](../../../components/frontend/README.md).
For more details about frontend configuration options, see the [Frontend Component Documentation](/components/src/dynamo/frontend/README.md).
## Testing the Setup
......
......@@ -17,8 +17,8 @@ docker compose -f deploy/docker-compose.yml up -d
## Components
- [Frontend](../../../components/frontend/README.md) - A built-in component that launches an OpenAI compliant HTTP server, a pre-processor, and a router in a single process
- [vLLM Backend](../../../components/backends/vllm/README.md) - A built-in component that runs vLLM within the Dynamo runtime
- [Frontend](/components/src/dynamo/frontend/README.md) - A built-in component that launches an OpenAI compliant HTTP server, a pre-processor, and a router in a single process
- [vLLM Backend](/components/backends/vllm/README.md) - A built-in component that runs vLLM within the Dynamo runtime
```mermaid
---
......
......@@ -7,13 +7,13 @@ import subprocess
from hatchling.builders.hooks.plugin.interface import BuildHookInterface
COMPONENTS = [
"frontend/src/dynamo/frontend",
"backends/vllm/src/dynamo/vllm",
"backends/sglang/src/dynamo/sglang",
"backends/trtllm/src/dynamo/trtllm",
"backends/mocker/src/dynamo/mocker",
"backends/llama_cpp/src/dynamo/llama_cpp",
"planner/src/dynamo/planner",
"frontend",
"vllm",
"sglang",
"trtllm",
"mocker",
"llama_cpp",
"planner",
]
......@@ -46,7 +46,7 @@ class VersionWriterHook(BuildHookInterface):
for component in COMPONENTS:
version_file_path = os.path.join(
self.root, f"components/{component}/_version.py"
self.root, f"components/src/dynamo/{component}/_version.py"
)
with open(version_file_path, "w") as f:
f.write(version_content)
......@@ -77,14 +77,7 @@ path = "hatch_build.py"
[tool.hatch.build.targets.wheel]
packages = [
"components/frontend/src/dynamo",
"components/planner/src/dynamo",
"components/router/src/dynamo",
"components/backends/llama_cpp/src/dynamo",
"components/backends/mocker/src/dynamo",
"components/backends/trtllm/src/dynamo",
"components/backends/sglang/src/dynamo",
"components/backends/vllm/src/dynamo"
"components/src/dynamo",
]
[tool.hatch.metadata]
......@@ -139,7 +132,7 @@ addopts = [
"--ignore-glob=*_inc.py",
"--ignore-glob=*/llm/tensorrtllm*",
"--ignore-glob=docs/*",
"--ignore-glob=components/backends/sglang/src/dynamo/sglang/request_handlers/*",
"--ignore-glob=components/src/dynamo/sglang/request_handlers/*",
"--ignore-glob=components/backends/sglang/slurm_jobs/*",
# FIXME: Get relative/generic blob paths to work here
]
......
......@@ -150,11 +150,11 @@ Test the replica calculation logic without requiring Kubernetes:
```bash
# Set PYTHONPATH to include planner components
PYTHONPATH=components/planner/src python -m pytest tests/planner/test_replica_calculation.py -v
PYTHONPATH=components/src python -m pytest tests/planner/test_replica_calculation.py -v
# Or from the tests/planner directory:
cd tests/planner
PYTHONPATH=../../components/planner/src python -m pytest test_replica_calculation.py -v
PYTHONPATH=../../components/src python -m pytest test_replica_calculation.py -v
```
**Note**: The unit tests automatically mock external dependencies (prometheus_client, runtime modules) to ensure they can run in isolation without requiring the full Dynamo environment.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment