Skip to content

test: Add test to verify model registry access for different users created from the run#283

Merged
fege merged 36 commits intoopendatahub-io:mainfrom
fege:rbac_tests
May 22, 2025
Merged

test: Add test to verify model registry access for different users created from the run#283
fege merged 36 commits intoopendatahub-io:mainfrom
fege:rbac_tests

Conversation

@fege
Copy link
Copy Markdown
Contributor

@fege fege commented May 2, 2025

Description

How Has This Been Tested?

Merge criteria:

  • The commits are squashed in a cohesive manner and have meaningful messages.
  • Testing instructions have been added in the PR body (for PRs involving changes that are not immediately obvious).
  • The developer has manually tested the changes and verified that the changes work

Summary by CodeRabbit

  • New Features

    • Added comprehensive tests for user and group permissions related to Model Registry access, including scenarios for group membership and direct user role binding.
    • Introduced utilities for managing temporary OpenShift test users and groups, enabling automated creation and cleanup of test user sessions.
    • Provided helper functions for building Model Registry client arguments and verifying user/group access in test environments.
    • Added a context manager to switch OpenShift CLI contexts temporarily during operations.
    • Enhanced test infrastructure with reusable fixtures for dynamic group and user session management.
  • Tests

    • Implemented end-to-end RBAC tests for Model Registry, covering user, group, and service account access scenarios.
    • Enhanced test infrastructure with reusable fixtures and utility functions to streamline RBAC testing workflows.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented May 2, 2025

Walkthrough

The changes introduce a comprehensive RBAC (Role-Based Access Control) testing framework for the Model Registry component. New utilities manage ephemeral OpenShift test users and groups via HTPasswd IDPs, enable dynamic context switching, and provide helper functions for Model Registry client setup. Multiple test cases verify user and group permissions through direct and group-based role bindings.

Changes

File(s) Change Summary
tests/model_registry/rbac/conftest.py Added fixtures for creating OpenShift groups and managing test IDP user sessions. Updated the mr_access_role_binding fixture to use a dynamic role kind. Removed redundant log statement after role deletion.
tests/model_registry/rbac/utils.py New utility module: provides functions for building Model Registry client arguments, asserting registry access, and retrieving client args for RBAC tests.
tests/model_registry/rbac/test_mr_rbac.py New test module: implements RBAC tests for Model Registry, covering user/group permissions, group creation, role binding, and direct user access, using the new fixtures and utilities.
tests/model_registry/rbac/test_mr_rbac_sa.py Removed local build_mr_client_args function, now importing it from the new utility module. Removed unused Protocols import.
utilities/user_utils.py New module: defines UserTestSession dataclass and context manager for creating and cleaning up ephemeral OpenShift HTPasswd test users, handling IDP and secret management, context switching, and login automation with retries and cleanup.
utilities/infra.py Added a context manager to switch OpenShift CLI contexts temporarily and restore the original context after use.
tests/model_registry/rbac/group_utils.py Added a context manager function to create and automatically clean up OpenShift groups during tests.

Sequence Diagram(s)

sequenceDiagram
    participant Test as RBAC Test
    participant UserUtils as User Utils
    participant OpenShift as OpenShift Cluster
    participant MR as Model Registry

    Test->>UserUtils: create_test_idp()
    UserUtils->>OpenShift: Create htpasswd secret, add IDP
    UserUtils->>OpenShift: Login as test user, create context
    UserUtils-->>Test: Return UserTestSession

    Test->>OpenShift: Create group and add user
    Test->>OpenShift: Bind group/user to MR access role
    Test->>MR: Attempt Model Registry access with user token
    MR-->>Test: Allow or deny based on RBAC

    Test->>UserUtils: cleanup_test_idp()
    UserUtils->>OpenShift: Remove IDP, delete secret, cleanup context
Loading

Suggested labels

Verified, commented-by-fege, lgtm-by-fege

Suggested reviewers

  • dbasunag
  • lugi0

Poem

In the warren of clusters, a rabbit does code,
Creating test users with secrets bestowed.
Groups are assembled, permissions are tried,
The Model Registry’s doors swing open wide.
With fixtures and helpers, the tests all advance—
A hop, a skip, in the RBAC dance!
🐇✨

Note

⚡️ AI Code Reviews for VS Code, Cursor, Windsurf

CodeRabbit now has a plugin for VS Code, Cursor and Windsurf. This brings AI code reviews directly in the code editor. Each commit is reviewed immediately, finding bugs before the PR is raised. Seamless context handoff to your AI code agent ensures that you can easily incorporate review feedback.
Learn more here.


Note

⚡️ Faster reviews with caching

CodeRabbit now supports caching for code and dependencies, helping speed up reviews. This means quicker feedback, reduced wait times, and a smoother review experience overall. Cached data is encrypted and stored securely. This feature will be automatically enabled for all accounts on May 30th. To opt out, configure Review - Disable Cache at either the organization or repository level. If you prefer to disable all data retention across your organization, simply turn off the Data Retention setting under your Organization Settings.
Enjoy the performance boost—your workflow just got faster.


📜 Recent review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 0f0b014 and 603a22b.

📒 Files selected for processing (3)
  • tests/model_registry/rbac/test_mr_rbac.py (1 hunks)
  • tests/model_registry/rbac/test_mr_rbac_sa.py (1 hunks)
  • utilities/infra.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • utilities/infra.py
  • tests/model_registry/rbac/test_mr_rbac_sa.py
  • tests/model_registry/rbac/test_mr_rbac.py
✨ Finishing Touches
  • 📝 Generate Docstrings

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.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

Support

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

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.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @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.

@fege
Copy link
Copy Markdown
Contributor Author

fege commented May 2, 2025

/wip

@github-actions
Copy link
Copy Markdown

github-actions bot commented May 2, 2025

The following are automatically added/executed:

  • PR size label.
  • Run pre-commit
  • Run tox
  • Add PR author as the PR assignee

Available user actions:

  • To mark a PR as WIP, add /wip in a comment. To remove it from the PR comment /wip cancel to the PR.
  • To block merging of a PR, add /hold in a comment. To un-block merging of PR comment /hold cancel.
  • To mark a PR as approved, add /lgtm in a comment. To remove, add /lgtm cancel.
    lgtm label removed on each new commit push.
  • To mark PR as verified comment /verified to the PR, to un-verify comment /verified cancel to the PR.
    verified label removed on each new commit push.
  • To Cherry-pick a merged PR /cherry-pick <target_branch_name> to the PR. If <target_branch_name> is valid,
    and the current PR is merged, a cherry-picked PR would be created and linked to the current PR.
Supported labels

{'/hold', '/verified', '/wip', '/lgtm'}

@fege
Copy link
Copy Markdown
Contributor Author

fege commented May 2, 2025

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented May 2, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
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: 1

🧹 Nitpick comments (6)
tests/model_registry/utils.py (2)

161-184: Consider handling multiple services case consistently

The function correctly retrieves the model registry service, but it doesn't handle the case of multiple services in the same way as the existing get_mr_service_by_label function. For consistency, consider raising TooManyServicesError if multiple services are found.

    services = list(
        Service.get(
            dyn_client=admin_client, namespace=namespace, label_selector="app=model-registry,component=model-registry"
        )
    )
    if not services:
        raise RuntimeError(f"Model Registry service not found in namespace {namespace}")
+   if len(services) > 1:
+       raise TooManyServicesError(services)
    return services[0]

161-184: Use more specific exception type

Consider using a more specific exception type like ResourceNotFoundError instead of RuntimeError for consistency with the rest of the codebase.

    services = list(
        Service.get(
            dyn_client=admin_client, namespace=namespace, label_selector="app=model-registry,component=model-registry"
        )
    )
    if not services:
-       raise RuntimeError(f"Model Registry service not found in namespace {namespace}")
+       raise ResourceNotFoundError(f"Model Registry service not found in namespace {namespace}")
    return services[0]
tests/model_registry/test_user_permission.py (4)

67-68: Extract test users into constants

Consider extracting the hardcoded user names into constants at the module level for better maintainability and readability.

+# Define user constants at the module level
+CLUSTER_ADMIN_USER = "htpasswd-cluster-admin-user"
+NON_ADMIN_USER = "ldap-user1"
+
 @pytest.mark.parametrize(
     "user_name, password, context_manager",
     [
-        ("htpasswd-cluster-admin-user", os.environ.get("ADMIN_PASSWORD"), nullcontext()),
-        ("ldap-user1", os.environ.get("NON_ADMIN_PASSWORD"), pytest.raises(ForbiddenException)),
+        (CLUSTER_ADMIN_USER, os.environ.get("ADMIN_PASSWORD"), nullcontext()),
+        (NON_ADMIN_USER, os.environ.get("NON_ADMIN_PASSWORD"), pytest.raises(ForbiddenException)),
     ],
 )

84-84: Use better assertion format

For more informative error messages, consider using a more descriptive assertion format with a message explaining what's being checked.

-    assert model_registry_instance.name == MR_INSTANCE_NAME
+    assert model_registry_instance.name == MR_INSTANCE_NAME, f"Model registry instance name should be {MR_INSTANCE_NAME}, but got {model_registry_instance.name}"

90-96: Consider capturing and verifying the client instance

The test only checks if client creation succeeds or fails, but doesn't perform any operations with the client to further verify proper access. Consider storing the created client and performing a basic operation to verify functionality.

    with context_manager:
-        ModelRegistryClient(
+        client = ModelRegistryClient(
            server_address=f"https://{server}",
            port=int(port),
            author="opendatahub-test",
            user_token=user_token,
            is_secure=False,
        )
+        if user_name == "htpasswd-cluster-admin-user":
+            # Verify admin can perform operations by making a basic API call
+            client.get_registered_models()

1-97: Add logging for test progress and diagnostics

The test could benefit from additional logging to help diagnose issues during test runs, especially when working with external services and authentication.

Add logging at key points in the test:

    def test_user_permission(
        self: Self,
        updated_dsc_component_state_scope_class,
        model_registry_instance,
        admin_client: DynamicClient,
        user_name,
        password,
        context_manager,
    ):
+        LOGGER.info(f"Testing model registry access for user: {user_name}")
        assert model_registry_instance.name == MR_INSTANCE_NAME
        user_token = get_token(user_name=user_name, password=password, admin_client=admin_client)
+        LOGGER.info(f"Successfully obtained token for user: {user_name}")

        svc = get_model_registry_service(admin_client=admin_client, namespace=TEST_NAMESPACE)
        server, port = get_endpoint_from_mr_service(svc, Protocols.REST).split(":")
+        LOGGER.info(f"Connecting to model registry at: https://{server}:{port}")
        with context_manager:
            ModelRegistryClient(
                server_address=f"https://{server}",
                port=int(port),
                author="opendatahub-test",
                user_token=user_token,
                is_secure=False,
            )
+            LOGGER.info(f"User {user_name} access test completed successfully")
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 560f952 and b6074c4.

📒 Files selected for processing (2)
  • tests/model_registry/test_user_permission.py (1 hunks)
  • tests/model_registry/utils.py (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
tests/model_registry/utils.py (1)
tests/conftest.py (1)
  • admin_client (50-51)
tests/model_registry/test_user_permission.py (4)
tests/model_registry/utils.py (2)
  • get_endpoint_from_mr_service (43-47)
  • get_model_registry_service (161-184)
utilities/constants.py (3)
  • DscComponents (146-164)
  • Protocols (87-94)
  • ManagementState (151-153)
tests/conftest.py (1)
  • admin_client (50-51)
tests/model_registry/conftest.py (2)
  • updated_dsc_component_state_scope_class (223-250)
  • model_registry_instance (142-172)

@fege
Copy link
Copy Markdown
Contributor Author

fege commented May 2, 2025

@coderabbitat review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented May 2, 2025

Tip

For best results, initiate chat on the files or code changes.

@fege I noticed that you may have misspelled my username. The correct format is "@coderabbitai review" (without the "at" at the end).

I see that you've already successfully triggered a review in a previous comment, so your PR should already be in the review queue. If you're trying to trigger another review, please use "@coderabbitai review" or "@coderabbitai full review" for a complete review from scratch.

@fege
Copy link
Copy Markdown
Contributor Author

fege commented May 2, 2025

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented May 2, 2025

✅ Actions performed

Full review triggered.

Copy link
Copy Markdown
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: 1

♻️ Duplicate comments (1)
tests/model_registry/test_user_permission.py (1)

24-26: Document and restrict TLS bypass to test environments

We're deliberately using --insecure-skip-tls-verify=true which bypasses TLS verification.

🧹 Nitpick comments (4)
tests/model_registry/utils.py (1)

166-190: Consider consistent error handling for multiple services

The implementation correctly retrieves Model Registry services, but doesn't handle multiple matching services in the same way as get_mr_service_by_label. If multiple services match the label selector, this function silently returns the first one without warning about the ambiguity.

Consider applying a similar approach as in get_mr_service_by_label for consistency:

def get_model_registry_service(admin_client: DynamicClient, namespace: str) -> Service:
    """
    Get the Model Registry service.

    Retrieves the Model Registry service from the specified namespace.
    Args:
        admin_client (DynamicClient): OCP Client to use.
        namespace (str): Namespace where the Model Registry service is located.

    Returns:
        Service: The Model Registry service.

    Raises:
        RuntimeError: if no Model Registry service is found.
+       TooManyServicesError: if more than one Model Registry service is found.
    """

    services = list(
        Service.get(
            dyn_client=admin_client, namespace=namespace, label_selector="app=model-registry,component=model-registry"
        )
    )
    if not services:
        raise RuntimeError(f"Model Registry service not found in namespace {namespace}")
+   if len(services) > 1:
+       raise TooManyServicesError(services)
    return services[0]
tests/model_registry/test_user_permission.py (3)

36-51: Consider more robust endpoint parsing

The current implementation assumes the endpoint format is always "server:port", which might not be robust in all environments.

Consider using a more resilient parsing approach:

def assert_mr_client(user_token, admin_client, context):
    """
    Initiate MR client
    """
    svc = get_model_registry_service(admin_client=admin_client, namespace=TEST_NAMESPACE)
    server, port = get_endpoint_from_mr_service(svc, Protocols.REST).split(":")
+   # Ensure endpoint is properly parsed even if it contains multiple colons (e.g., IPv6)
+   # Example format: "hostname:port" or "192.168.0.1:8080"
+   parts = get_endpoint_from_mr_service(svc, Protocols.REST).rsplit(":", 1)
+   if len(parts) == 2:
+       server, port = parts
+   else:
+       raise ValueError(f"Invalid endpoint format: {get_endpoint_from_mr_service(svc, Protocols.REST)}")

    with context:
        ModelRegistryClient(
            server_address=f"https://{server}",
            port=int(port),
            author="opendatahub-test",
            user_token=user_token,
            is_secure=False,
        )

128-131: Fix typo in log message

There's a typo in the log message.

-    LOGGER.info("User has no acces to MR")
+    LOGGER.info("User has no access to MR")
-    LOGGER.info("Add user hthe model registry users group")
+    LOGGER.info("Add user to the model registry users group")

136-137: Fix typo in log message

There's a typo in the log message.

-    LOGGER.info("User has acces to MR")
+    LOGGER.info("User has access to MR")
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 560f952 and 5ddf96a.

📒 Files selected for processing (2)
  • tests/model_registry/test_user_permission.py (1 hunks)
  • tests/model_registry/utils.py (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
tests/model_registry/utils.py (1)
tests/conftest.py (1)
  • admin_client (50-51)
tests/model_registry/test_user_permission.py (4)
tests/model_registry/utils.py (2)
  • get_endpoint_from_mr_service (48-52)
  • get_model_registry_service (166-189)
utilities/constants.py (3)
  • DscComponents (146-164)
  • Protocols (87-94)
  • ManagementState (151-153)
tests/conftest.py (1)
  • admin_client (50-51)
tests/model_registry/conftest.py (2)
  • updated_dsc_component_state_scope_class (224-255)
  • model_registry_instance (143-173)

@rhods-ci-bot rhods-ci-bot added the Verified Verified pr in Jenkins label May 22, 2025
lugi0
lugi0 previously approved these changes May 22, 2025
Copy link
Copy Markdown
Contributor

@lugi0 lugi0 left a comment

Choose a reason for hiding this comment

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

few suggestions but looks good in general

Copy link
Copy Markdown
Collaborator

@dbasunag dbasunag left a comment

Choose a reason for hiding this comment

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

Couple of comments. Looks good otherwise. Thank you for addressing all the open comments.

Copy link
Copy Markdown
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

🧹 Nitpick comments (1)
tests/model_registry/rbac/group_utils.py (1)

36-44: LGTM: Clean implementation with proper resource lifecycle management

The implementation correctly uses the Group resource as a context manager, handling both creation and cleanup automatically. The logging statements provide valuable visibility into the group lifecycle during test execution.

Consider adding basic error handling to log any exceptions that might occur during group creation, which could help with debugging test failures:

-    with Group(
-        client=admin_client,
-        name=group_name,
-        users=users or [],
-        wait_for_resource=wait_for_resource,
-    ) as _:
-        LOGGER.info(f"Group {group_name} created successfully.")
-        yield group_name
-        LOGGER.info(f"Group {group_name} deletion initiated by context manager.")
+    try:
+        with Group(
+            client=admin_client,
+            name=group_name,
+            users=users or [],
+            wait_for_resource=wait_for_resource,
+        ) as _:
+            LOGGER.info(f"Group {group_name} created successfully.")
+            yield group_name
+            LOGGER.info(f"Group {group_name} deletion initiated by context manager.")
+    except Exception as e:
+        LOGGER.error(f"Error during group {group_name} lifecycle: {e}")
+        raise
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 2099d45 and 1d0d469.

📒 Files selected for processing (4)
  • tests/model_registry/rbac/conftest.py (3 hunks)
  • tests/model_registry/rbac/group_utils.py (1 hunks)
  • tests/model_registry/rbac/test_mr_rbac.py (1 hunks)
  • tests/model_registry/rbac/utils.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • tests/model_registry/rbac/utils.py
  • tests/model_registry/rbac/conftest.py
  • tests/model_registry/rbac/test_mr_rbac.py
🧰 Additional context used
🧬 Code Graph Analysis (1)
tests/model_registry/rbac/group_utils.py (1)
tests/conftest.py (1)
  • admin_client (52-53)
🔇 Additional comments (5)
tests/model_registry/rbac/group_utils.py (5)

1-7: LGTM: Appropriate imports and logger setup

The imports are well-organized and include all necessary dependencies. Good practice to use a dedicated logger instance with the module name.


10-16: LGTM: Well-defined function signature with proper type annotations

The context manager is correctly defined with appropriate type hints. The function signature clearly indicates what parameters are required and which are optional, with sensible defaults.


17-35: LGTM: Comprehensive and well-structured docstring

The docstring clearly explains the purpose, parameters, return value, and includes a practical usage example. This follows best practices for Python documentation.


39-39: LGTM: Defensive handling of optional users parameter

Good use of users or [] to handle the case when no users are provided. This ensures a valid empty list is passed to the Group constructor.


14-14:

Details

✅ Verification successful

Verify Python version compatibility for union type syntax

The use of list[str] | None for type annotation uses the union type operator (|) which is only supported in Python 3.10+. Ensure your project's minimum Python version requirement is compatible with this syntax, or consider using Optional[List[str]] from the typing module for broader compatibility.


🏁 Script executed:

#!/bin/bash
# Check the project's Python version requirements
grep -r "python_requires" --include="*.py" --include="setup.py" --include="pyproject.toml" .
# Check if there are any Python version constraints in requirements files
grep -r "^python" --include="requirements*.txt" .

Length of output: 140


I didn’t find any python_requires in setup.py/setup.cfg or a requires-python/Poetry entry in pyproject.toml. Let’s check a few more common places for Python version constraints:


🏁 Script executed:

#!/bin/bash
# Check setup.cfg for python_requires
grep -R "python_requires" --include=setup.cfg .

# Check pyproject.toml for PEP 621 requires-python
grep -R "requires-python" --include=pyproject.toml .

# Check Poetry-style Python constraint in pyproject.toml
grep -R "^\s*python\s*=" --include=pyproject.toml .

# Check Pipfile for a Python version requirement
grep -R "python_version" --include=Pipfile .

Length of output: 245


No action needed—project targets Python 3.12 so list[str] | None is supported

I verified that pyproject.toml includes:

requires-python = "==3.12.*"

Since Python 3.12 ≥ 3.10, the use of PEP 604 union syntax is fully compatible.

dbasunag
dbasunag previously approved these changes May 22, 2025
lugi0
lugi0 previously approved these changes May 22, 2025
@fege fege dismissed stale reviews from lugi0 and dbasunag via 603a22b May 22, 2025 15:25
@github-actions
Copy link
Copy Markdown

Status of building tag latest: success.
Status of pushing tag latest to image registry: success.

Comment on lines +64 to +65
mr_client = ModelRegistryClient(**client_args)
assert mr_client is not None, "Client initialization failed after granting permissions"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

shouldn't be safer to check a return code or some specific error msg saying the initialization failed because of permissions?

This was referenced Jun 16, 2025
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