"examples/vscode:/vscode.git/clone" did not exist on "11d7d3f59e15bc5eabe42ce056260dbd26550f3c"
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 ...@@ -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 && \ sed '/^#\s/d' /workspace/launch_message.txt > ~/.launch_screen && \
echo "cat ~/.launch_screen" >> ~/.bashrc echo "cat ~/.launch_screen" >> ~/.bashrc
# Once UX refactor is merged, we can remove these files # Copy tests, benchmarks, deploy and components for CI
# 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 /workspace/tests COPY tests /workspace/tests
COPY benchmarks /workspace/benchmarks COPY benchmarks /workspace/benchmarks
COPY examples /workspace/examples COPY examples /workspace/examples
COPY deploy /workspace/deploy 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 files
COPY ATTRIBUTION* LICENSE /workspace/ COPY ATTRIBUTION* LICENSE /workspace/
...@@ -303,12 +294,12 @@ COPY --from=dynamo_base /usr/local/cargo /usr/local/cargo ...@@ -303,12 +294,12 @@ COPY --from=dynamo_base /usr/local/cargo /usr/local/cargo
COPY --from=runtime ${VIRTUAL_ENV} ${VIRTUAL_ENV} COPY --from=runtime ${VIRTUAL_ENV} ${VIRTUAL_ENV}
# so we can use maturin develop # Install maturin, for maturin develop
RUN uv pip install maturin[patchelf] RUN uv pip install maturin[patchelf]
# Make sure to sync this with the one specified on README.md. # Editable install of dynamo
# This is a generic PYTHONPATH which works for all the frameworks, so some paths may not be relevant for this particular framework. COPY pyproject.toml README.md hatch_build.py /workspace/
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 RUN uv pip install --no-deps -e .
ENTRYPOINT ["/opt/nvidia/nvidia_entrypoint.sh"] ENTRYPOINT ["/opt/nvidia/nvidia_entrypoint.sh"]
CMD [] CMD []
\ No newline at end of file
...@@ -332,11 +332,11 @@ COPY --from=dynamo_base /usr/local/cargo /usr/local/cargo ...@@ -332,11 +332,11 @@ COPY --from=dynamo_base /usr/local/cargo /usr/local/cargo
COPY --from=runtime ${VIRTUAL_ENV} ${VIRTUAL_ENV} COPY --from=runtime ${VIRTUAL_ENV} ${VIRTUAL_ENV}
# so we can use maturin develop # Install maturin, for maturin develop
RUN uv pip install maturin[patchelf] RUN uv pip install maturin[patchelf]
# Make sure to sync this with the one specified on README.md. # Editable install of dynamo
# This is a generic PYTHONPATH which works for all the frameworks, so some paths may not be relevant for this particular framework. COPY pyproject.toml README.md hatch_build.py /workspace/
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 RUN uv pip install --no-deps -e .
CMD [] CMD []
\ No newline at end of file
...@@ -337,12 +337,10 @@ COPY --from=dynamo_base /usr/local/cargo /usr/local/cargo ...@@ -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) # Much better than chown -R $USERNAME:$USERNAME /opt/dynamo/venv (~10min on my cpu)
COPY --from=runtime ${VIRTUAL_ENV} ${VIRTUAL_ENV} COPY --from=runtime ${VIRTUAL_ENV} ${VIRTUAL_ENV}
# so we can use maturin develop # Install maturin, for maturin develop
RUN uv pip install maturin[patchelf] # Editable install of dynamo
RUN uv pip install maturin[patchelf] && \
# Make sure to sync this with the one specified on README.md. uv pip install --no-deps -e .
# 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
ENTRYPOINT ["/opt/nvidia/nvidia_entrypoint.sh"] ENTRYPOINT ["/opt/nvidia/nvidia_entrypoint.sh"]
CMD [] CMD []
\ No newline at end of file
...@@ -2011,29 +2011,14 @@ class DynamoFrameworkInfo(NodeInfo): ...@@ -2011,29 +2011,14 @@ class DynamoFrameworkInfo(NodeInfo):
if not workspace_dir: if not workspace_dir:
return components return components
# Scan components directory (frontend, planner, etc.) # Scan components python src directory (frontend, planner, etc.)
components_path = os.path.join(workspace_dir, "components") components_path = os.path.join(workspace_dir, "components", "src", "dynamo")
if os.path.exists(components_path): if os.path.exists(components_path):
for item in os.listdir(components_path): for item in os.listdir(components_path):
item_path = os.path.join(components_path, item) item_path = os.path.join(components_path, item)
if os.path.isdir(item_path): if os.path.isdir(item_path):
# Check for dynamo module in src # Check for dynamo module in src
module_path = os.path.join( module_path = os.path.join(item_path, "__init__.py")
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"
)
if os.path.exists(module_path): if os.path.exists(module_path):
components.append(f"dynamo.{item}") components.append(f"dynamo.{item}")
...@@ -2228,20 +2213,9 @@ def show_pythonpath_recommendation(): ...@@ -2228,20 +2213,9 @@ def show_pythonpath_recommendation():
# Collect all component source paths # Collect all component source paths
comp_path = os.path.join(workspace_dir, "components") comp_path = os.path.join(workspace_dir, "components")
if os.path.exists(comp_path): if os.path.exists(comp_path):
for item in os.listdir(comp_path): src_path = os.path.join(comp_path, "src")
if item == "backends": if os.path.exists(src_path):
continue # Handle backends separately paths.append(src_path)
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)
# Also add runtime path # Also add runtime path
runtime_path = os.path.join(workspace_dir, "lib/bindings/python/src") runtime_path = os.path.join(workspace_dir, "lib/bindings/python/src")
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
"cwd": "${workspaceFolder}", "cwd": "${workspaceFolder}",
"env": { "env": {
"RUST_BACKTRACE": "1", "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": [ "sourceLanguages": [
"rust" "rust"
...@@ -63,7 +63,7 @@ ...@@ -63,7 +63,7 @@
"cwd": "${workspaceFolder}", "cwd": "${workspaceFolder}",
"env": { "env": {
"RUST_BACKTRACE": "1", "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": [ "sourceLanguages": [
"rust" "rust"
......
...@@ -36,9 +36,9 @@ docker compose -f deploy/metrics/docker-compose.yml up -d ...@@ -36,9 +36,9 @@ docker compose -f deploy/metrics/docker-compose.yml up -d
## Components ## Components
- [Frontend](../../../components/frontend/README.md) - HTTP API endpoint that receives requests and forwards them to the decode worker - [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 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 - [vLLM Decode Worker](/components/backends/vllm/README.md) - Specialized worker that handles requests and decides between local/remote prefill
```mermaid ```mermaid
--- ---
......
...@@ -217,7 +217,7 @@ The frontend will: ...@@ -217,7 +217,7 @@ The frontend will:
- Enable KV-aware routing for intelligent request distribution - Enable KV-aware routing for intelligent request distribution
- Monitor worker health and adjust routing accordingly - 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 ## Testing the Setup
......
...@@ -17,8 +17,8 @@ docker compose -f deploy/docker-compose.yml up -d ...@@ -17,8 +17,8 @@ docker compose -f deploy/docker-compose.yml up -d
## Components ## 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 - [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 - [vLLM Backend](/components/backends/vllm/README.md) - A built-in component that runs vLLM within the Dynamo runtime
```mermaid ```mermaid
--- ---
......
...@@ -7,13 +7,13 @@ import subprocess ...@@ -7,13 +7,13 @@ import subprocess
from hatchling.builders.hooks.plugin.interface import BuildHookInterface from hatchling.builders.hooks.plugin.interface import BuildHookInterface
COMPONENTS = [ COMPONENTS = [
"frontend/src/dynamo/frontend", "frontend",
"backends/vllm/src/dynamo/vllm", "vllm",
"backends/sglang/src/dynamo/sglang", "sglang",
"backends/trtllm/src/dynamo/trtllm", "trtllm",
"backends/mocker/src/dynamo/mocker", "mocker",
"backends/llama_cpp/src/dynamo/llama_cpp", "llama_cpp",
"planner/src/dynamo/planner", "planner",
] ]
...@@ -46,7 +46,7 @@ class VersionWriterHook(BuildHookInterface): ...@@ -46,7 +46,7 @@ class VersionWriterHook(BuildHookInterface):
for component in COMPONENTS: for component in COMPONENTS:
version_file_path = os.path.join( 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: with open(version_file_path, "w") as f:
f.write(version_content) f.write(version_content)
...@@ -77,14 +77,7 @@ path = "hatch_build.py" ...@@ -77,14 +77,7 @@ path = "hatch_build.py"
[tool.hatch.build.targets.wheel] [tool.hatch.build.targets.wheel]
packages = [ packages = [
"components/frontend/src/dynamo", "components/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"
] ]
[tool.hatch.metadata] [tool.hatch.metadata]
...@@ -139,7 +132,7 @@ addopts = [ ...@@ -139,7 +132,7 @@ addopts = [
"--ignore-glob=*_inc.py", "--ignore-glob=*_inc.py",
"--ignore-glob=*/llm/tensorrtllm*", "--ignore-glob=*/llm/tensorrtllm*",
"--ignore-glob=docs/*", "--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/*", "--ignore-glob=components/backends/sglang/slurm_jobs/*",
# FIXME: Get relative/generic blob paths to work here # FIXME: Get relative/generic blob paths to work here
] ]
......
...@@ -150,11 +150,11 @@ Test the replica calculation logic without requiring Kubernetes: ...@@ -150,11 +150,11 @@ Test the replica calculation logic without requiring Kubernetes:
```bash ```bash
# Set PYTHONPATH to include planner components # 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: # Or from the tests/planner directory:
cd tests/planner 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. **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