Skip to content

Conversation

@keivenchang
Copy link
Contributor

@keivenchang keivenchang commented Aug 12, 2025

Overview:

A concise checker that prints key environment info, verifies imports, and gives clear suggestions to fix failures.

Details:

  • Shows system, Cargo, and Dynamo layout in a compact tree
  • Checks runtime/framework imports and reports exact issues
  • Offers actionable PYTHONPATH/build guidance when something’s missing

Where should the reviewer start?

deploy/dynamo_check.py

Example:

ubuntu@keivenc-linux:~/dynamo$ ./deploy/dynamo_check.py --import
System info:
├─ Linux: Ubuntu 24.04.1 LTS (Noble Numbat) (Linux 6.11.0-28-generic x86_64); Memory: 25.5/125.5 GiB; Cores: 32
├─ GPU: NVIDIA NVIDIA RTX 6000 Ada Generation (driver 570.133.07, CUDA 12.8); Power: 27.98/300.00 W; Memory: 2/49140 MiB
├─ CUDA: driver 570.133.07, CUDA 12.8
├─ Python: 3.12.3 (/opt/dynamo/venv/bin/python3); PYTHONPATH=:/home/ubuntu/dynamo/components/planner/src:
   └─ Torch: 2.7.1+cu126
├─ Cargo (/usr/local/cargo/bin/cargo, cargo 1.87.0 (99624be96 2025-05-06))
   ├─ Cargo home directory: $HOME/dynamo/.build/.cargo (CARGO_HOME is set)
   └─ Cargo target directory: $HOME/dynamo/.build/target (CARGO_TARGET_DIR is set)
      ├─ Debug:   $HOME/dynamo/.build/target/debug (modified: 2025-08-12 16:40:58 PDT)
      ├─ Release: $HOME/dynamo/.build/target/release (modified: 2025-08-13 09:41:20 PDT)
      └─ Binary:  $HOME/dynamo/.build/target/debug/libdynamo_llm_capi.so (modified: 2025-08-12 16:40:22 PDT)
└─ Dynamo ($HOME/dynamo):
   └─ Runtime components (ai-dynamo-runtime 0.4.0):
      ├─ /opt/dynamo/venv/lib/python3.12/site-packages/ai_dynamo_runtime-0.4.0.dist-info (created: 2025-08-13 09:41:22 PDT)
      ├─ ✅ dynamo._core        /opt/dynamo/venv/lib/python3.12/site-packages/dynamo/_core.cpython-312-x86_64-linux-gnu.so (modified: 2025-08-13 09:41:22 PDT)
      ├─ ✅ dynamo.nixl_connect /opt/dynamo/venv/lib/python3.12/site-packages/dynamo/nixl_connect/__init__.py
      ├─ ✅ dynamo.llm          /opt/dynamo/venv/lib/python3.12/site-packages/dynamo/llm/__init__.py
      └─ ✅ dynamo.runtime      /opt/dynamo/venv/lib/python3.12/site-packages/dynamo/runtime/__init__.py
   └─ Framework components (ai-dynamo 0.4.0):
      ├─ /opt/dynamo/venv/lib/python3.12/site-packages/ai_dynamo-0.4.0.dist-info (created: 2025-08-13 09:41:23 PDT)
      ├─ ✅ dynamo.frontend     /opt/dynamo/venv/lib/python3.12/site-packages/dynamo/frontend/__init__.py
      ├─ ✅ dynamo.planner      components/planner/src/dynamo/planner/__init__.py
      ├─ ✅ dynamo.mocker       /opt/dynamo/venv/lib/python3.12/site-packages/dynamo/mocker/__init__.py
      ├─ ✅ dynamo.trtllm       /opt/dynamo/venv/lib/python3.12/site-packages/dynamo/trtllm/__init__.py
      ├─ ✅ dynamo.vllm         /opt/dynamo/venv/lib/python3.12/site-packages/dynamo/vllm/__init__.py
      ├─ ✅ dynamo.sglang       /opt/dynamo/venv/lib/python3.12/site-packages/dynamo/sglang/__init__.py
      └─ ✅ dynamo.llama_cpp    /opt/dynamo/venv/lib/python3.12/site-packages/dynamo/llama_cpp/__init__.py

And for other environments:

ubuntu@keivenc-linux:~/dynamo$ bin/dynamo_check.py --import
System info:
├─ Linux: Ubuntu 24.04.1 LTS (Noble Numbat) (Linux 6.11.0-28-generic x86_64); Memory: 25.3/125.5 GiB; Cores: 32
├─ GPU: NVIDIA NVIDIA RTX 6000 Ada Generation (driver 570.133.07, CUDA 12.8); Power: 27.50/300.00 W; Memory: 2/49140 MiB
├─ CUDA: driver 570.133.07, CUDA 12.8
├─ Python: 3.12.3 (/opt/dynamo/venv/bin/python3); PYTHONPATH=:/home/ubuntu/dynamo/components/planner/src:
   └─ Torch: 2.7.1+cu126
├─ Cargo (/usr/local/cargo/bin/cargo, cargo 1.87.0 (99624be96 2025-05-06))
   ├─ Cargo home directory: $HOME/dynamo/.build/.cargo (CARGO_HOME is set)
   └─ Cargo target directory: $HOME/dynamo/.build/target (CARGO_TARGET_DIR is set)
      ├─ Debug:   $HOME/dynamo/.build/target/debug (modified: 2025-08-13 13:23:08 PDT)
      └─ Binary:  $HOME/dynamo/.build/target/debug/libdynamo_llm_capi.so (modified: 2025-08-13 13:22:10 PDT)
└─ Dynamo ($HOME/dynamo):
   └─ Runtime components (ai-dynamo-runtime 0.4.0):
      ├─ /opt/dynamo/venv/lib/python3.12/site-packages/ai_dynamo_runtime-0.4.0.dist-info (created: 2025-08-13 09:34:32 PDT)
      ├─ /opt/dynamo/venv/lib/python3.12/site-packages/ai_dynamo_runtime.pth (modified: 2025-08-13 09:34:32 PDT)
         └─ Points to: $HOME/dynamo/lib/bindings/python/src
      ├─ ✅ dynamo._core        lib/bindings/python/src/dynamo/_core.cpython-312-x86_64-linux-gnu.so (modified: 2025-08-13 09:34:32 PDT)
      ├─ ✅ dynamo.nixl_connect lib/bindings/python/src/dynamo/nixl_connect/__init__.py
      ├─ ✅ dynamo.llm          lib/bindings/python/src/dynamo/llm/__init__.py
      └─ ✅ dynamo.runtime      lib/bindings/python/src/dynamo/runtime/__init__.py
   └─ Framework components (ai-dynamo 0.4.0):
      ├─ /opt/dynamo/venv/lib/python3.12/site-packages/ai_dynamo-0.4.0.dist-info (created: 2025-08-13 09:34:33 PDT)
      ├─ /opt/dynamo/venv/lib/python3.12/site-packages/_ai_dynamo.pth (modified: 2025-08-13 09:34:33 PDT)
         └─ Points to: $HOME/dynamo/components/backends/vllm/src
      ├─ ❌ dynamo.frontend     No module named 'dynamo.frontend'
      ├─ ✅ dynamo.planner      components/planner/src/dynamo/planner/__init__.py
      ├─ ❌ dynamo.mocker       No module named 'dynamo.mocker'
      ├─ ❌ dynamo.trtllm       No module named 'dynamo.trtllm'
      ├─ ✅ dynamo.vllm         components/backends/vllm/src/dynamo/vllm/__init__.py
      ├─ ❌ dynamo.sglang       No module named 'dynamo.sglang'
      └─ ❌ dynamo.llama_cpp    No module named 'dynamo.llama_cpp'

Missing framework components. You can choose one of the following options:
1. For local development, set the PYTHONPATH environment variable:
   dynamo_check.py --try-pythonpath --imports
   export PYTHONPATH="$HOME/dynamo/components/router/src:$HOME/dynamo/components/metrics/src:$HOME/dynamo/components/frontend/src:$HOME/dynamo/components/planner/src:$HOME/dynamo/components/backends/mocker/src:$HOME/dynamo/components/backends/trtllm/src:$HOME/dynamo/components/backends/vllm/src:$HOME/dynamo/components/backends/sglang/src:$HOME/dynamo/components/backends/llama_cpp/src"
2. For a production-release (slower build time), build the packages with:
   dynamo_build.sh --release

Summary by CodeRabbit

  • New Features

    • Introduced a command-line environment checker that discovers your workspace and components, validates setup, tests imports, and reports results in a readable tree.
    • Shows build details, detects installed packages, and recommends PYTHONPATH updates (with an option to apply them).
    • Supports flexible modes via flags (e.g., imports-only, examples, try-pythonpath) and prints timestamps and component locations.
  • Documentation

    • Built-in usage examples and troubleshooting guidance, including commands for setting environment variables and building artifacts for a working setup.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 12, 2025

Walkthrough

Adds a new deploy/dynamo_check.py CLI tool that discovers a Dynamo workspace, inspects components and Python packages, probes Cargo build artifacts, optionally sets PYTHONPATH, tests imports, prints summaries, troubleshooting, and usage examples. Exposes DynamoChecker class with run_all, test_imports, show_usage_examples, show_troubleshooting, show_summary, and a main entrypoint.

Changes

Cohort / File(s) Summary
Dynamo environment checker
deploy/dynamo_check.py
New standalone CLI utility introducing DynamoChecker class to discover workspace/components, inspect site-packages and Cargo artifacts, suggest PYTHONPATH, run import tests, print summaries, usage examples, troubleshooting, and provide a main() entrypoint with flags (--imports, --examples, --try-pythonpath).

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant U as User
  participant CLI as dynamo_check.py (main)
  participant DC as DynamoChecker
  participant FS as FileSystem
  participant ENV as Env Vars
  participant PY as Python Import System
  participant CG as Cargo/Targets

  U->>CLI: Run with flags (--imports/--examples/--try-pythonpath)
  CLI->>DC: Initialize DynamoChecker
  DC->>FS: Discover workspace (README, components, lib/bindings, Cargo.toml)
  DC->>ENV: Read Cargo env, PYTHONPATH
  DC->>FS: Locate components (runtime/framework)
  DC->>CG: Detect target dirs, build profile, .so artifacts
  DC->>PY: Optionally update sys.path (try-pythonpath)
  alt --imports
    DC->>PY: Attempt imports per discovered modules
    PY-->>DC: Success/ImportError details
  else --examples
    DC->>U: Print usage examples
  else default
    DC->>PY: Run full checks incl. imports
  end
  DC->>U: Print summary, environment tree, troubleshooting
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

A whisker twitch, I map the lair,
Paths and crates laid bare to air.
I hop through imports, rustling logs,
Nose to PYTHONPATH, over sprogs.
If cargo growls, I try again—
Carrot-shaped success: run-all, then grin. 🥕✨


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (4)
deploy/dynamo_check.py (4)

407-409: Improve timestamp comparison precision.

Using a 1-second tolerance for timestamp comparison might miss genuinely different timestamps that happen to be close. Consider either using exact comparison or documenting why this tolerance is necessary.

Consider making the comparison more precise or configurable:

-                if (
-                    abs(debug_mtime - release_mtime) < 1.0
-                ):  # Same timestamp (within 1 second)
+                # Consider timestamps the same if within 0.01 seconds (filesystem precision)
+                if abs(debug_mtime - release_mtime) < 0.01:
                     return "debug/release"  # Both available, runtime choice depends on invocation

450-451: Consider defensive ordering when modifying sys.path.

When inserting paths at the beginning of sys.path, the order matters. Currently, paths are inserted in the order they're discovered, which might not be deterministic across different filesystem implementations.

Consider sorting the paths for consistent behavior:

         # Update sys.path for current process
         if paths:
+            # Sort paths for consistent ordering
+            paths.sort()
             # Add paths to sys.path for immediate effect on imports
             for path in paths:
                 if path not in sys.path:
                     sys.path.insert(0, path)  # Insert at beginning for priority

569-575: Consider using a set for file extension checking.

Using a list comprehension with any() for checking file extensions is less efficient than using a set membership test.

                     # Check if this is a generated file we want to show timestamps for
-                    if any(
-                        module_path.endswith(ext)
-                        for ext in [".so", ".pth", ".dll", ".dylib"]
-                    ):
+                    generated_extensions = {".so", ".pth", ".dll", ".dylib"}
+                    if any(module_path.endswith(ext) for ext in generated_extensions):
                         show_timestamp = True

693-703: Simplify package matching logic.

The nested conditions for matching .pth files to packages can be simplified using a more direct approach.

-                        pth_matches_package = False
-                        if package_name == "ai-dynamo-runtime":
-                            # Look for ai_dynamo_runtime.pth or similar
-                            if (
-                                "ai_dynamo_runtime" in file.lower()
-                                or file.lower().startswith("ai_dynamo_runtime")
-                            ):
-                                pth_matches_package = True
-                        elif package_name == "ai-dynamo":
-                            # Look for _ai_dynamo.pth or ai_dynamo.pth (but not ai_dynamo_runtime.pth)
-                            if (
-                                "ai_dynamo" in file.lower()
-                                or "_ai_dynamo" in file.lower()
-                            ) and "runtime" not in file.lower():
-                                pth_matches_package = True
+                        file_lower = file.lower()
+                        pth_matches_package = (
+                            (package_name == "ai-dynamo-runtime" and "ai_dynamo_runtime" in file_lower) or
+                            (package_name == "ai-dynamo" and "ai_dynamo" in file_lower and "runtime" not in file_lower)
+                        )
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7e4eec2 and 18b34c8.

📒 Files selected for processing (1)
  • deploy/dynamo_check.py (1 hunks)
🧰 Additional context used
🪛 GitHub Actions: Copyright Checks
deploy/dynamo_check.py

[error] 1-1: Copyright header check failed for deploy/dynamo_check.py. Step: pwsh /workspace/.github/workflows/copyright-check.ps1. Exit code: 255.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Mirror Repository to GitLab
  • GitHub Check: Build and Test - dynamo
🔇 Additional comments (4)
deploy/dynamo_check.py (4)

259-263: Verify PDT offset calculation for daylight saving time.

The code assumes PDT is always UTC-7, but Pacific Time alternates between PST (UTC-8) and PDT (UTC-7) depending on the date. This hardcoded offset could produce incorrect timestamps during standard time.

Consider using a more robust approach or documenting this limitation:

         # Fallback to local time with manual PDT offset approximation
-        # PDT is UTC-7, so subtract 7 hours from UTC
+        # Note: This assumes PDT (UTC-7) and doesn't account for PST (UTC-8) during standard time
         dt_utc = datetime.datetime.utcfromtimestamp(timestamp)
         dt_pdt = dt_utc - datetime.timedelta(hours=7)
         return dt_pdt.strftime("%Y-%m-%d %H:%M:%S PDT")

Alternatively, provide more accurate handling:

         # Fallback to local time with manual Pacific Time offset
-        # PDT is UTC-7, so subtract 7 hours from UTC
         dt_utc = datetime.datetime.utcfromtimestamp(timestamp)
-        dt_pdt = dt_utc - datetime.timedelta(hours=7)
-        return dt_pdt.strftime("%Y-%m-%d %H:%M:%S PDT")
+        # Approximate DST: April-October uses PDT (UTC-7), November-March uses PST (UTC-8)
+        month = dt_utc.month
+        if 4 <= month <= 10:
+            dt_pacific = dt_utc - datetime.timedelta(hours=7)
+            return dt_pacific.strftime("%Y-%m-%d %H:%M:%S PDT")
+        else:
+            dt_pacific = dt_utc - datetime.timedelta(hours=8)
+            return dt_pacific.strftime("%Y-%m-%d %H:%M:%S PST")

56-61: LGTM! Clean optional dependency handling.

Good practice using a try-except block for the optional pytz dependency and setting a flag for later conditional use.


72-77: LGTM! Thoughtful warning suppression.

Good attention to user experience by suppressing known warnings from the planner module during import testing.


221-234: LGTM! Consistent path normalization.

Excellent implementation of home directory replacement for portable output across different environments.

- Implement hierarchical tree display with Dynamo Environment as root
- Merge Python package installation status with Runtime/Framework sections
- Add .pth file detection with 'Points to' messages for editable installs
- Implement proper tree symbols (├─, └─) for visual hierarchy
- Fix package matching logic to prevent cross-contamination between packages
- Remove redundant 'Package:' prefix and suppress 'Not found' lines when appropriate
- Replace user home directory paths with $HOME for cleaner, portable display
- Fix workspace detection to always use absolute paths for consistent $HOME replacement
- Improve overall readability and organization of environment status reporting
@keivenchang keivenchang force-pushed the keivenchang/feat_add-dynamo-check-script branch from 5e1ceae to b9a48ee Compare August 12, 2025 23:51
- Replace pytz external dependency with standard library zoneinfo
- Add proper type annotations for all variables and function parameters
- Fix Optional parameter types with explicit Dict[str, Any] annotations
- Handle potential None values with type narrowing checks
- Replace None defaults with empty strings where appropriate
- Ensure all function signatures have complete type information
- Script now passes mypy type checking without external dependencies
@biswapanda
Copy link
Contributor

Approved because change and output looks great!

Q: is deploy the right place to keep these helper scripts? @nnshah1

@keivenchang keivenchang merged commit da1bf52 into main Aug 14, 2025
9 of 11 checks passed
@keivenchang keivenchang deleted the keivenchang/feat_add-dynamo-check-script branch August 14, 2025 04:14
@keivenchang
Copy link
Contributor Author

Approved because change and output looks great!

Q: is deploy the right place to keep these helper scripts? @nnshah1

Ideally I'd move this to a bin or utils path, but I don't see one here. Got an idea, @nnshah1?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants