Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ruff: add known-local-folder #236

Merged
merged 2 commits into from
Jan 27, 2025
Merged

Conversation

bennyz
Copy link
Member

@bennyz bennyz commented Jan 27, 2025

Summary by CodeRabbit

Based on the comprehensive summary of changes, here are the release notes:

Release Notes

  • Import and Configuration Updates

    • Reorganized and restored import statements across multiple packages
    • Added configuration for import sorting in pyproject.toml
  • Driver Enhancements

    • Added @export decorator to several driver methods, improving method accessibility
    • Introduced new driver classes for digital input/output and storage management
  • Testing Improvements

    • Enhanced error handling in configuration tests
    • Restored and updated test utilities across various driver packages
  • Configuration Management

    • Reintroduced configuration classes for clients, exporters, and users
    • Improved metadata filtering capabilities
  • Miscellaneous

    • Minor reorganization of import statements
    • No significant changes to core functionality or logic

Signed-off-by: Benny Zlotnik <[email protected]>
Copy link
Contributor

coderabbitai bot commented Jan 27, 2025

Walkthrough

This pull request involves a comprehensive reorganization and restoration of import statements across multiple packages in the Jumpstarter project. The changes primarily focus on reintroducing previously removed imports, reorganizing import sections, and ensuring that necessary classes and utilities are available for various modules. The modifications do not substantially alter the core functionality of the existing code but enhance import management and potential future extensibility.

Changes

File Change Summary
Multiple CLI Admin Files Reintroduced imports for ClientConfigV1Alpha1, ExporterConfigV1Alpha1, and UserConfigV1Alpha1
Multiple Driver Files Added export and exportstream decorators, reorganized import statements
Multiple Testing Files Restored imports for configuration classes and utility functions
Configuration Files Reintroduced imports for gRPC, metadata filtering, and configuration classes
Client Base Files Restored imports for stream-related classes

Poem

🐰 Imports dance, a rabbit's delight,
Restored and sorted, lines now bright
Modules whisper their secrets anew
CodeRabbit's magic, imports true
Leaping through code with graceful might! 🌈

✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

🪧 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.
    • Generate unit testing code for this file.
    • 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. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • 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 src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

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.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • 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.

Signed-off-by: Benny Zlotnik <[email protected]>
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: 0

🔭 Outside diff range comments (1)
packages/jumpstarter-driver-raspberrypi/jumpstarter_driver_raspberrypi/driver.py (1)

The InputDevice to DigitalOutputDevice conversion pattern appears unnecessary

After reviewing the complete implementation and tests:

  • The pattern is unique to the DigitalOutput class and isn't documented
  • The DigitalInput class demonstrates that direct device initialization works
  • No technical reason found in the codebase for starting with InputDevice

Recommendation:

  • Either document why this conversion is necessary, or
  • Simplify by directly initializing as DigitalOutputDevice, similar to the DigitalInput implementation
🔗 Analysis chain

Line range hint 9-35: Document the InputDevice to DigitalOutputDevice conversion pattern.

The class starts with an InputDevice and converts to DigitalOutputDevice on demand. This unusual pattern needs documentation explaining the rationale.

Consider adding error handling for GPIO initialization.

The GPIO device initialization could fail due to various reasons (permissions, hardware issues). Consider adding try-except blocks with meaningful error messages.

Example:

     def __post_init__(self):
         super().__post_init__()
-        # Initialize as InputDevice first
-        self.device = InputDevice(pin=self.pin)
+        try:
+            # Initialize as InputDevice first
+            self.device = InputDevice(pin=self.pin)
+        except Exception as e:
+            raise RuntimeError(f"Failed to initialize GPIO pin {self.pin}: {e}")
🏁 Scripts executed

The following scripts were executed for the analysis:

Error: No shell scripts found


Script:

#!/bin/bash
# Get the complete driver implementation
echo "=== Complete driver.py implementation ==="
cat packages/jumpstarter-driver-raspberrypi/jumpstarter_driver_raspberrypi/driver.py

echo -e "\n=== Related client implementation ==="
cat packages/jumpstarter-driver-raspberrypi/jumpstarter_driver_raspberrypi/client/DigitalOutputClient.py 2>/dev/null || echo "Client file not found at expected location"

echo -e "\n=== Looking for test files ==="
fd "test.*\.py" packages/jumpstarter-driver-raspberrypi -x cat {}

echo -e "\n=== Looking for similar GPIO patterns ==="
rg -A 5 "InputDevice.*DigitalOutputDevice" packages/jumpstarter-driver-raspberrypi

Length of output: 4355

🧹 Nitpick comments (7)
packages/jumpstarter-driver-dutlink/examples/dutlink.py (1)

Line range hint 11-15: Consider documenting the initialization alternatives.

The code shows two initialization methods (via exporter config and via environment), with the environment method being the active one. Consider adding a brief comment explaining when to use each method and the tradeoffs between them.

-# initialize client from exporter config
-# from jumpstarter.common import MetadataFilter
-# from jumpstarter.config.client import ClientConfigV1Alpha1
-# with ClientConfigV1Alpha1.load("default").lease(metadata_filter=MetadataFilter()) as lease:
-#     with lease.connect() as client:
+# Method 1: Initialize client from exporter config (useful for custom configurations)
+# from jumpstarter.common import MetadataFilter
+# from jumpstarter.config.client import ClientConfigV1Alpha1
+# with ClientConfigV1Alpha1.load("default").lease(metadata_filter=MetadataFilter()) as lease:
+#     with lease.connect() as client:
 
-# initialize client from environment
-# e.g. `jmp-exporter shell dutlink`
+# Method 2: Initialize client from environment (simpler, recommended for most cases)
+# Usage: Run `jmp-exporter shell dutlink` before executing this script

Also applies to: 17-18

packages/jumpstarter-cli-exporter/jumpstarter_cli_exporter/exporter_config.py (3)

Line range hint 9-25: Consider adding input validation for endpoint and token.

While the function correctly handles existing configs, it would be beneficial to validate:

  • The endpoint URL format
  • The token's minimum length and format

Example validation:

 @click.command("create-config")
-@click.option("--endpoint", prompt=True)
-@click.option("--token", prompt=True)
+@click.option("--endpoint", prompt=True, callback=lambda ctx, param, value: value if value.startswith(('http://', 'https://')) else click.fail('Endpoint must start with http:// or https://'))
+@click.option("--token", prompt=True, callback=lambda ctx, param, value: value if len(value) >= 32 else click.fail('Token must be at least 32 characters'))
 @arg_alias
 def create_exporter_config(alias, endpoint, token):

Line range hint 40-48: Consider adding safeguards for file editing.

The current implementation could benefit from additional safety measures:

  • Validate file content after editing
  • Create a backup before editing
  • Handle editor failures gracefully

Example implementation:

 @click.command("edit-config")
 @arg_alias
 def edit_exporter_config(alias):
     """Edit an exporter config."""
     try:
         config = ExporterConfigV1Alpha1.load(alias)
+        # Create backup
+        backup_path = config.path.with_suffix('.bak')
+        backup_path.write_text(config.path.read_text())
     except FileNotFoundError as err:
         raise click.ClickException(f'exporter "{alias}" does not exist') from err
-    click.edit(filename=config.path)
+    
+    if click.edit(filename=config.path) is None:
+        raise click.ClickException("No changes made or editor failed")
+    
+    try:
+        # Validate the edited file
+        ExporterConfigV1Alpha1.load(alias)
+    except Exception as err:
+        # Restore backup on validation failure
+        config.path.write_text(backup_path.read_text())
+        raise click.ClickException(f"Invalid configuration: {err}") from err

Line range hint 51-66: Consider enhancing the config listing output.

The current implementation could be more informative by:

  • Adding the endpoint column (masked token for security)
  • Adding sorting options

Example enhancement:

 @click.command("list-configs")
+@click.option("--sort-by", type=click.Choice(["alias", "endpoint"]), default="alias")
 def list_exporter_configs():
     """List exporter configs."""
     exporters = ExporterConfigV1Alpha1.list()
-    columns = ["ALIAS", "PATH"]
+    columns = ["ALIAS", "ENDPOINT", "PATH"]
+    
     rows = [
         {
             "ALIAS": exporter.alias,
+            "ENDPOINT": exporter.endpoint,
             "PATH": str(exporter.path),
         }
         for exporter in exporters
     ]
+    rows.sort(key=lambda x: x[sort_by.upper()])
     click.echo(make_table(columns, rows))
packages/jumpstarter-driver-sdwire/jumpstarter_driver_sdwire/driver.py (1)

Line range hint 1-124: LGTM! Export decorators are correctly applied.

The export decorators are properly applied to all public methods. The implementation includes robust error handling and device management.

Consider enhancing error handling in device initialization.

The device initialization could benefit from more specific error messages to help diagnose issues.

-            raise FileNotFoundError("failed to find sdcard driver on sd-wire device")
+            raise FileNotFoundError(f"Failed to find sdcard driver on sd-wire device (bus={dev.bus}, address={dev.address})")

-        raise FileNotFoundError("failed to find sd-wire device")
+        raise FileNotFoundError(f"Failed to find sd-wire device with serial={self.serial}")
packages/jumpstarter-driver-http/jumpstarter_driver_http/driver.py (1)

Line range hint 1-208: LGTM! Export decorators are correctly applied.

The export decorators are properly applied to all public methods. The implementation includes comprehensive error handling and logging.

Security: Review IP address detection method.

The get_default_ip() function connects to an external service (8.8.8.8) to determine the local IP. This could:

  1. Leak information about the service deployment
  2. Fail in restricted network environments
  3. Cause delays during initialization

Consider using a more secure local-only approach.

 def get_default_ip():
     try:
         import socket
-
-        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
-        s.connect(("8.8.8.8", 80))
-        ip = s.getsockname()[0]
-        s.close()
+        # Get all local addresses
+        addresses = socket.getaddrinfo(
+            host=socket.gethostname(),
+            port=None,
+            family=socket.AF_INET,
+            type=socket.SOCK_STREAM
+        )
+        # Filter out localhost
+        ip = next((addr[4][0] for addr in addresses if not addr[4][0].startswith('127.')), '0.0.0.0')
         return ip
     except Exception:
         logger.warning("Could not determine default IP address, falling back to 0.0.0.0")
         return "0.0.0.0"
packages/jumpstarter-driver-raspberrypi/jumpstarter_driver_raspberrypi/driver.py (1)

Line range hint 38-57: Add cleanup method and improve error handling.

Consider the following improvements:

  1. Add a close() method to ensure proper cleanup
  2. Add error handling for GPIO initialization
  3. Document the timeout parameter behavior for wait methods

Example implementation:

@dataclass(kw_only=True)
class DigitalInput(Driver):
    pin: int | str
    device: DigitalInputDevice = field(init=False)

    @classmethod
    def client(cls) -> str:
        return "jumpstarter_driver_raspberrypi.client.DigitalInputClient"

    def __post_init__(self):
        super().__post_init__()
-        self.device = DigitalInputDevice(pin=self.pin)
+        try:
+            self.device = DigitalInputDevice(pin=self.pin)
+        except Exception as e:
+            raise RuntimeError(f"Failed to initialize GPIO pin {self.pin}: {e}")

+    def close(self):
+        if hasattr(self, "device"):
+            self.device.close()
+        super().close()

    @export
    def wait_for_active(self, timeout: float | None = None):
+        """Wait for the input to become active.
+
+        Args:
+            timeout: Number of seconds to wait before giving up. None means wait forever.
+
+        Raises:
+            TimeoutError: If timeout is reached before input becomes active.
+        """
        self.device.wait_for_active(timeout)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6eafa84 and 4db8de8.

📒 Files selected for processing (73)
  • packages/jumpstarter-cli-admin/jumpstarter_cli_admin/create.py (1 hunks)
  • packages/jumpstarter-cli-admin/jumpstarter_cli_admin/create_test.py (1 hunks)
  • packages/jumpstarter-cli-admin/jumpstarter_cli_admin/delete.py (1 hunks)
  • packages/jumpstarter-cli-admin/jumpstarter_cli_admin/delete_test.py (1 hunks)
  • packages/jumpstarter-cli-admin/jumpstarter_cli_admin/import_res.py (1 hunks)
  • packages/jumpstarter-cli-admin/jumpstarter_cli_admin/import_res_test.py (1 hunks)
  • packages/jumpstarter-cli-client/jumpstarter_cli_client/__init__.py (1 hunks)
  • packages/jumpstarter-cli-client/jumpstarter_cli_client/client_config.py (1 hunks)
  • packages/jumpstarter-cli-client/jumpstarter_cli_client/client_shell.py (1 hunks)
  • packages/jumpstarter-cli-client/jumpstarter_cli_client/client_test.py (1 hunks)
  • packages/jumpstarter-cli-client/jumpstarter_cli_client/lease.py (1 hunks)
  • packages/jumpstarter-cli-exporter/jumpstarter_cli_exporter/exporter.py (1 hunks)
  • packages/jumpstarter-cli-exporter/jumpstarter_cli_exporter/exporter_config.py (1 hunks)
  • packages/jumpstarter-cli-exporter/jumpstarter_cli_exporter/exporter_test.py (1 hunks)
  • packages/jumpstarter-driver-can/jumpstarter_driver_can/client.py (1 hunks)
  • packages/jumpstarter-driver-can/jumpstarter_driver_can/client_test.py (1 hunks)
  • packages/jumpstarter-driver-can/jumpstarter_driver_can/driver.py (1 hunks)
  • packages/jumpstarter-driver-composite/jumpstarter_driver_composite/client.py (1 hunks)
  • packages/jumpstarter-driver-composite/jumpstarter_driver_composite/driver.py (1 hunks)
  • packages/jumpstarter-driver-composite/jumpstarter_driver_composite/driver_test.py (1 hunks)
  • packages/jumpstarter-driver-dutlink/examples/dutlink.py (1 hunks)
  • packages/jumpstarter-driver-dutlink/jumpstarter_driver_dutlink/driver.py (1 hunks)
  • packages/jumpstarter-driver-dutlink/jumpstarter_driver_dutlink/driver_test.py (1 hunks)
  • packages/jumpstarter-driver-http/jumpstarter_driver_http/client.py (1 hunks)
  • packages/jumpstarter-driver-http/jumpstarter_driver_http/driver.py (1 hunks)
  • packages/jumpstarter-driver-http/jumpstarter_driver_http/driver_test.py (1 hunks)
  • packages/jumpstarter-driver-network/jumpstarter_driver_network/adapters/fabric_test.py (1 hunks)
  • packages/jumpstarter-driver-network/jumpstarter_driver_network/adapters/novnc.py (1 hunks)
  • packages/jumpstarter-driver-network/jumpstarter_driver_network/adapters/novnc_test.py (1 hunks)
  • packages/jumpstarter-driver-network/jumpstarter_driver_network/driver.py (1 hunks)
  • packages/jumpstarter-driver-network/jumpstarter_driver_network/driver_test.py (1 hunks)
  • packages/jumpstarter-driver-opendal/jumpstarter_driver_opendal/adapter.py (1 hunks)
  • packages/jumpstarter-driver-opendal/jumpstarter_driver_opendal/client.py (1 hunks)
  • packages/jumpstarter-driver-opendal/jumpstarter_driver_opendal/driver.py (1 hunks)
  • packages/jumpstarter-driver-opendal/jumpstarter_driver_opendal/driver_test.py (1 hunks)
  • packages/jumpstarter-driver-power/jumpstarter_driver_power/client.py (1 hunks)
  • packages/jumpstarter-driver-power/jumpstarter_driver_power/client_test.py (1 hunks)
  • packages/jumpstarter-driver-power/jumpstarter_driver_power/driver.py (1 hunks)
  • packages/jumpstarter-driver-pyserial/jumpstarter_driver_pyserial/client.py (1 hunks)
  • packages/jumpstarter-driver-pyserial/jumpstarter_driver_pyserial/driver.py (1 hunks)
  • packages/jumpstarter-driver-pyserial/jumpstarter_driver_pyserial/driver_test.py (1 hunks)
  • packages/jumpstarter-driver-raspberrypi/jumpstarter_driver_raspberrypi/driver.py (1 hunks)
  • packages/jumpstarter-driver-raspberrypi/jumpstarter_driver_raspberrypi/driver_test.py (1 hunks)
  • packages/jumpstarter-driver-sdwire/jumpstarter_driver_sdwire/driver.py (1 hunks)
  • packages/jumpstarter-driver-sdwire/jumpstarter_driver_sdwire/driver_test.py (1 hunks)
  • packages/jumpstarter-driver-tftp/jumpstarter_driver_tftp/client.py (1 hunks)
  • packages/jumpstarter-driver-tftp/jumpstarter_driver_tftp/driver.py (1 hunks)
  • packages/jumpstarter-driver-tftp/jumpstarter_driver_tftp/driver_test.py (1 hunks)
  • packages/jumpstarter-driver-ustreamer/jumpstarter_driver_ustreamer/client.py (1 hunks)
  • packages/jumpstarter-driver-ustreamer/jumpstarter_driver_ustreamer/driver.py (1 hunks)
  • packages/jumpstarter-driver-ustreamer/jumpstarter_driver_ustreamer/driver_test.py (1 hunks)
  • packages/jumpstarter-imagehash/jumpstarter_imagehash/imagehash.py (1 hunks)
  • packages/jumpstarter-kubernetes/jumpstarter_kubernetes/clients.py (1 hunks)
  • packages/jumpstarter-kubernetes/jumpstarter_kubernetes/exporters.py (1 hunks)
  • packages/jumpstarter-testing/jumpstarter_testing/pytest.py (1 hunks)
  • packages/jumpstarter-testing/jumpstarter_testing/pytest_test.py (1 hunks)
  • packages/jumpstarter/conftest.py (1 hunks)
  • packages/jumpstarter/jumpstarter/client/base.py (1 hunks)
  • packages/jumpstarter/jumpstarter/client/client.py (1 hunks)
  • packages/jumpstarter/jumpstarter/client/core.py (1 hunks)
  • packages/jumpstarter/jumpstarter/client/lease.py (1 hunks)
  • packages/jumpstarter/jumpstarter/common/streams.py (1 hunks)
  • packages/jumpstarter/jumpstarter/common/utils.py (1 hunks)
  • packages/jumpstarter/jumpstarter/config/client.py (1 hunks)
  • packages/jumpstarter/jumpstarter/config/client_config_test.py (1 hunks)
  • packages/jumpstarter/jumpstarter/config/exporter.py (1 hunks)
  • packages/jumpstarter/jumpstarter/config/exporter_test.py (1 hunks)
  • packages/jumpstarter/jumpstarter/config/user_config_test.py (1 hunks)
  • packages/jumpstarter/jumpstarter/driver/base.py (1 hunks)
  • packages/jumpstarter/jumpstarter/exporter/exporter.py (1 hunks)
  • packages/jumpstarter/jumpstarter/exporter/session.py (1 hunks)
  • packages/jumpstarter/jumpstarter/listener_test.py (1 hunks)
  • pyproject.toml (1 hunks)
✅ Files skipped from review due to trivial changes (52)
  • packages/jumpstarter-driver-composite/jumpstarter_driver_composite/driver_test.py
  • packages/jumpstarter-driver-power/jumpstarter_driver_power/client.py
  • packages/jumpstarter/conftest.py
  • packages/jumpstarter-cli-client/jumpstarter_cli_client/client_test.py
  • packages/jumpstarter-driver-power/jumpstarter_driver_power/client_test.py
  • packages/jumpstarter-driver-raspberrypi/jumpstarter_driver_raspberrypi/driver_test.py
  • packages/jumpstarter-driver-network/jumpstarter_driver_network/adapters/fabric_test.py
  • packages/jumpstarter-driver-pyserial/jumpstarter_driver_pyserial/client.py
  • packages/jumpstarter-driver-can/jumpstarter_driver_can/driver.py
  • packages/jumpstarter-cli-client/jumpstarter_cli_client/init.py
  • packages/jumpstarter-driver-pyserial/jumpstarter_driver_pyserial/driver_test.py
  • packages/jumpstarter-cli-exporter/jumpstarter_cli_exporter/exporter_test.py
  • packages/jumpstarter-driver-can/jumpstarter_driver_can/client_test.py
  • packages/jumpstarter-driver-http/jumpstarter_driver_http/client.py
  • packages/jumpstarter-cli-client/jumpstarter_cli_client/lease.py
  • packages/jumpstarter-driver-dutlink/jumpstarter_driver_dutlink/driver.py
  • packages/jumpstarter-driver-ustreamer/jumpstarter_driver_ustreamer/driver.py
  • packages/jumpstarter/jumpstarter/common/streams.py
  • packages/jumpstarter-driver-network/jumpstarter_driver_network/adapters/novnc.py
  • packages/jumpstarter/jumpstarter/client/lease.py
  • packages/jumpstarter-driver-tftp/jumpstarter_driver_tftp/driver_test.py
  • packages/jumpstarter/jumpstarter/driver/base.py
  • packages/jumpstarter-driver-sdwire/jumpstarter_driver_sdwire/driver_test.py
  • packages/jumpstarter-driver-opendal/jumpstarter_driver_opendal/adapter.py
  • packages/jumpstarter-cli-admin/jumpstarter_cli_admin/import_res_test.py
  • packages/jumpstarter/jumpstarter/exporter/exporter.py
  • packages/jumpstarter-cli-admin/jumpstarter_cli_admin/delete.py
  • packages/jumpstarter-driver-composite/jumpstarter_driver_composite/driver.py
  • packages/jumpstarter-kubernetes/jumpstarter_kubernetes/clients.py
  • packages/jumpstarter-driver-opendal/jumpstarter_driver_opendal/client.py
  • packages/jumpstarter-cli-admin/jumpstarter_cli_admin/create.py
  • packages/jumpstarter-driver-power/jumpstarter_driver_power/driver.py
  • packages/jumpstarter/jumpstarter/exporter/session.py
  • packages/jumpstarter/jumpstarter/client/client.py
  • packages/jumpstarter-driver-can/jumpstarter_driver_can/client.py
  • packages/jumpstarter-cli-admin/jumpstarter_cli_admin/import_res.py
  • packages/jumpstarter-imagehash/jumpstarter_imagehash/imagehash.py
  • packages/jumpstarter-testing/jumpstarter_testing/pytest_test.py
  • packages/jumpstarter-cli-client/jumpstarter_cli_client/client_config.py
  • packages/jumpstarter-driver-tftp/jumpstarter_driver_tftp/client.py
  • packages/jumpstarter/jumpstarter/client/core.py
  • packages/jumpstarter-driver-ustreamer/jumpstarter_driver_ustreamer/client.py
  • packages/jumpstarter/jumpstarter/listener_test.py
  • packages/jumpstarter-cli-admin/jumpstarter_cli_admin/delete_test.py
  • packages/jumpstarter/jumpstarter/config/exporter.py
  • packages/jumpstarter/jumpstarter/config/client.py
  • packages/jumpstarter-driver-ustreamer/jumpstarter_driver_ustreamer/driver_test.py
  • packages/jumpstarter/jumpstarter/config/exporter_test.py
  • packages/jumpstarter-kubernetes/jumpstarter_kubernetes/exporters.py
  • packages/jumpstarter-driver-network/jumpstarter_driver_network/driver_test.py
  • packages/jumpstarter/jumpstarter/config/user_config_test.py
  • packages/jumpstarter-driver-tftp/jumpstarter_driver_tftp/driver.py
🔇 Additional comments (23)
packages/jumpstarter-driver-http/jumpstarter_driver_http/driver_test.py (1)

11-11: LGTM! Import restoration aligns with PR objectives.

The reintroduction of this import is correct as ClientStreamResource is used in the test_http_server function. The import placement follows the standard import grouping convention (stdlib → third-party → local).

packages/jumpstarter-driver-dutlink/jumpstarter_driver_dutlink/driver_test.py (1)

7-7: LGTM! Import restoration looks good.

The import of serve from jumpstarter.common.utils is correctly restored and is being used appropriately in the test context manager.

packages/jumpstarter-driver-opendal/jumpstarter_driver_opendal/driver_test.py (1)

11-11: LGTM! Import restoration looks good.

The import of serve from jumpstarter.common.utils is correctly restored and is being used appropriately in both test functions.

packages/jumpstarter-driver-dutlink/examples/dutlink.py (1)

8-8: LGTM! Import matches usage.

The added import of env from jumpstarter.common.utils aligns with its usage as a context manager in the script.

packages/jumpstarter-driver-network/jumpstarter_driver_network/adapters/novnc_test.py (1)

9-10: LGTM! Imports are correctly restored.

The restored imports from jumpstarter.common are essential for the test functionality, as they are actively used in the test_client_adapter_novnc function.

Let's verify these imports are consistently used across related test files:

✅ Verification successful

Imports are consistent with codebase patterns

The restored imports follow the established patterns across the codebase:

  • TemporaryTcpListener is consistently imported from jumpstarter.common in network-related tests
  • serve is uniformly used in context managers throughout the test files
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check usage patterns of TemporaryTcpListener and serve in test files
# Expected: Find consistent import patterns across test files

# Search for TemporaryTcpListener usage in test files
echo "Checking TemporaryTcpListener usage in tests:"
rg "TemporaryTcpListener" -g "*test.py"

# Search for serve usage in test files
echo -e "\nChecking serve usage in tests:"
rg "serve\(" -g "*test.py"

Length of output: 7136

packages/jumpstarter-cli-exporter/jumpstarter_cli_exporter/exporter_config.py (2)

4-4: LGTM! Import statements are appropriate.

The import of ExporterConfigV1Alpha1 is correctly placed and necessary for the config management functionality.


Line range hint 28-37: LGTM! Proper error handling and validation.

The function correctly validates config existence and uses proper exception chaining with informative error messages.

packages/jumpstarter-driver-opendal/jumpstarter_driver_opendal/driver.py (1)

Line range hint 1-24: LGTM! Export decorators are correctly applied.

The export decorators are properly applied to all public methods in the MockStorageMux class, maintaining consistency with the interface contract.

packages/jumpstarter-driver-network/jumpstarter_driver_network/driver.py (1)

Line range hint 1-82: LGTM! Appropriate use of exportstream decorator.

The exportstream decorator is correctly applied to all connect methods, properly indicating that these methods yield streams. The decorator order with @asynccontextmanager is maintained correctly.

packages/jumpstarter-cli-exporter/jumpstarter_cli_exporter/exporter.py (3)

6-7: LGTM! Import statement is correctly placed and used.

The new import of launch_shell from jumpstarter.common.utils is properly organized and utilized in the code.


Line range hint 19-26: Verify Python version compatibility for except syntax.*

The implementation uses the except* syntax for exception group handling, which requires Python 3.11+.

✅ Verification successful

Python 3.11+ requirement is properly declared

The use of except* syntax is safe as the package and the entire ecosystem explicitly require Python 3.11+.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check Python version requirement in project
rg -l "python.*3\.11" .

Length of output: 1163


Line range hint 63-64: Review security implications of unsafe shell launch.

The code uses unsafe=True with an empty allow list, which requires careful consideration:

  1. The SAFETY comment explains the trust assumption but could benefit from more detailed documentation
  2. Consider if any restrictions should be added to the allow list for defense in depth

Let's verify the security implications:

✅ Verification successful

Security implications of unsafe shell launch are appropriate

The unsafe=True parameter with empty allow list is intentional and properly documented. The SAFETY comment correctly explains that the exporter config is local and trusted. The implementation in utils.py properly encapsulates this trust decision through environment variables.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check documentation and usage patterns of launch_shell
rg -A 5 "launch_shell.*unsafe=True" 

# Look for any security-related comments or documentation
ast-grep --pattern 'def launch_shell($$$)'

Length of output: 203


Script:

#!/bin/bash
# Find launch_shell implementation
rg -B 5 -A 10 "def launch_shell"

# Get more context around the usage
rg -B 10 -A 10 "launch_shell\(path, allow=\[\], unsafe=True\)"

# Look for any security-related comments
rg -i "SAFETY|SECURITY|CAUTION|WARNING" --type py

Length of output: 5918

packages/jumpstarter-driver-raspberrypi/jumpstarter_driver_raspberrypi/driver.py (1)

1-6: LGTM! Imports are well-organized and necessary.

The imports are logically grouped and all are used in the implementation.

packages/jumpstarter-driver-composite/jumpstarter_driver_composite/client.py (1)

Line range hint 4-8: LGTM! Good inheritance structure.

The addition of DriverClient as the base class for CompositeClient establishes a proper inheritance hierarchy, maintaining consistency with other driver implementations in the codebase.

packages/jumpstarter-cli-client/jumpstarter_cli_client/client_shell.py (1)

2-3: LGTM! Consistent metadata filtering implementation.

The addition of MetadataFilter aligns with the project's approach to metadata filtering, as seen in other components like the testing framework.

packages/jumpstarter-driver-pyserial/jumpstarter_driver_pyserial/driver.py (1)

9-10: LGTM! Proper use of driver framework decorators.

The addition of @exportstream decorator to the connect method aligns with the driver framework's patterns while preserving the async context manager functionality.

packages/jumpstarter-testing/jumpstarter_testing/pytest.py (2)

6-9: LGTM! Enhanced testing framework with metadata filtering.

The addition of MetadataFilter and related imports enhances the testing framework while maintaining backward compatibility.


Line range hint 71-73: Consider investigating and properly fixing the gRPC server release issue.

The sleep workaround suggests an underlying issue with gRPC server cleanup that should be investigated and fixed properly.

packages/jumpstarter/jumpstarter/common/utils.py (1)

Line range hint 7-12: LGTM! Clean import organization.

The added imports are well-organized and necessary for the existing functionality in the file.

packages/jumpstarter/jumpstarter/client/base.py (1)

15-15: LGTM! Proper type import.

The BlockingStream import is correctly added and properly used for both type hints and implementation.

packages/jumpstarter-cli-admin/jumpstarter_cli_admin/create_test.py (1)

17-21: LGTM! Essential configuration imports for tests.

The configuration classes are properly imported and well-utilized throughout the test suite.

packages/jumpstarter/jumpstarter/config/client_config_test.py (1)

8-8: LGTM! Improved error handling specificity.

Using pydantic's ValidationError instead of ValueError provides more precise error handling for configuration validation failures.

pyproject.toml (1)

49-51: LGTM! The configuration aligns with the project structure.

The addition of known-local-folder configuration for isort in Ruff is correct and matches the project's workspace structure. This will help maintain consistent import organization by properly categorizing local imports from the specified directories.

Let's verify that the configuration works as expected:

✅ Verification successful

Import sorting configuration verified and working correctly

The Ruff isort configuration has been tested across the codebase and all files pass the import sorting checks, confirming that the known-local-folder setting is working as intended.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that the isort configuration correctly identifies local imports.

# Test: Check if any Python files in the specified directories have import sorting issues.
# Expect: No output if imports are correctly sorted according to the new configuration.
ruff check --select I .

Length of output: 44

@NickCao NickCao merged commit 4026424 into jumpstarter-dev:main Jan 27, 2025
9 of 10 checks passed
@bennyz bennyz deleted the ruff-settings branch January 27, 2025 14:10
@coderabbitai coderabbitai bot mentioned this pull request Feb 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants