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

fix: Fix XRootD storage plugin at least for file access #8

Merged
merged 19 commits into from
Aug 20, 2024

Conversation

MattMonk
Copy link
Collaborator

@MattMonk MattMonk commented Aug 4, 2024

This PR updates the storage plugin to allow read/write file access with XRootD, borrowing heavily from the XRootD remote provider in Snakemake<8 to allow remote input/output files.

It should also be possible to support StorageObjectGlob but I would have to think about it a bit more (or of course someone else would also be more than welcome to have a go!).

I tested this with the latest Snakemake (commit e8735c14 from a local editable install with Python 3.12.4) and could successfully:

  • Use a remote file as an input with retrieve=False
  • Use a remote file as an input with retrieve=True
  • Use a remote file as an output
  • Use remote files as inputs/outputs as above including wildcards in the file paths/URLs

Summary by CodeRabbit

  • New Features

    • Introduced a Snakemake storage plugin for reading and writing via the XRootD protocol, enhancing data handling in computational workflows.
    • Added improved error handling and retry logic for XRootD operations, increasing robustness during file interactions.
    • Implemented new URL management features, allowing for more flexible URL construction and validation.
    • Expanded documentation to clarify authentication options and the use of URL decorators.
  • Bug Fixes

    • Enhanced error management for file operations, ensuring issues are logged and handled appropriately.
  • Documentation

    • Updated documentation to reflect new plugin functionalities and usage guidelines, including details on input and output specifications.

@MattMonk MattMonk changed the title Fix XRootD storage plugin at least for file access fix: Fix XRootD storage plugin at least for file access Aug 4, 2024
Copy link
Contributor

@johanneskoester johanneskoester left a comment

Choose a reason for hiding this comment

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

Thanks a lot! Some questions below, sorry if they are stupid, I have actually no experience with xrootd. Another question: your description sounds like it did not work before, but the CI tests worked. Was my CI setup somehow artificial?

Comment on lines +44 to +46
xrootd_retry = retry(
tries=3, delay=3, backoff=2, logger=get_logger(), fail_callback=_raise_fatal_error
)
Copy link
Contributor

Choose a reason for hiding this comment

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

Why using a special retry decorator here and not the one provided by snakemake-interface-storage-plugin?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This was just because when I was testing it I would sometimes find that when it failed it would keep retrying on errors that should not really (imo) be retried on like access permissions problems. I figured maybe instead I could have a list of "veto" error codes that should not be re-tried and just fail straight away (thinking things like out of memory on the host side etc.)

I ended up re-defining the retry decorator here because I figured it was maybe the easiest way to get the custom callback function in to throw the "unretry-able" errors straight away instead of doing the usual retries but this extra decorator was a bit of an afterthought so happy to change/remove it!

Copy link
Contributor

Choose a reason for hiding this comment

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

I see. This is a good idea and we can keep it like this for now. Maybe we can reintegrate it with the plugin interface at some point.

snakemake_storage_plugin_xrootd/__init__.py Outdated Show resolved Hide resolved
snakemake_storage_plugin_xrootd/__init__.py Outdated Show resolved Hide resolved
snakemake_storage_plugin_xrootd/__init__.py Show resolved Hide resolved
Copy link
Contributor

coderabbitai bot commented Aug 14, 2024

Walkthrough

The recent updates introduce a Snakemake storage plugin for the XRootD protocol, enhancing data operations in computational workflows. Key improvements include robust error handling, an integrated retry mechanism for transient errors, and flexible URL management. Although the plugin currently supports only file-level operations, these enhancements significantly increase reliability and usability, positioning it as a valuable tool for scientific computing environments.

Changes

File(s) Change Summary
docs/intro.md Introduced a Snakemake storage plugin for the XRootD protocol, detailing file-level operation limitations and usability enhancements.
snakemake_storage_plugin_xrootd/init.py Enhanced functionality with a new exception class for unrecoverable errors, implemented retry logic, improved URL handling, and streamlined methods for better clarity and robustness.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Workflow
    participant XRootDProvider
    participant ErrorHandler

    User->>Workflow: Submit request for file operation
    Workflow->>XRootDProvider: Process request
    XRootDProvider->>ErrorHandler: Check for errors
    alt No errors
        XRootDProvider-->>Workflow: Return file operation result
    else Errors encountered
        XRootDProvider->>ErrorHandler: Log error
        ErrorHandler->>XRootDProvider: Retry operation
        XRootDProvider-->>Workflow: Return failure message
    end
Loading

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

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>.
    • 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 generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @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 as 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 resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

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.

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: 9

Outside diff range comments (1)
snakemake_storage_plugin_xrootd/__init__.py (1)

Line range hint 403-411:
Implement list_candidate_matches or remove the method.

The list_candidate_matches method is marked with a TODO but is not implemented. Either implement it or remove it if not needed.

Do you want me to help implement this method or open a GitHub issue to track this task?

Tools
Ruff

277-277: Missing type annotation for self in method

(ANN101)


282-282: Missing type annotation for self in method

(ANN101)


288-288: Missing return type annotation for public function cleanup

Add return type annotation: None

(ANN201)


288-288: Missing type annotation for self in method

(ANN101)


292-292: Unnecessary pass statement

Remove unnecessary pass

(PIE790)


295-295: Missing type annotation for self in method

(ANN101)


298-298: Missing type annotation for self in method

(ANN101)


298-298: Missing type annotation for function argument query

(ANN001)


315-315: Missing type annotation for self in method

(ANN101)


325-325: Missing type annotation for self in method

(ANN101)


335-335: Missing return type annotation for public function retrieve_object

Add return type annotation: None

(ANN201)


335-335: Missing type annotation for self in method

(ANN101)


360-360: Missing return type annotation for private function _makedirs

Add return type annotation: None

(ANN202)


360-360: Missing type annotation for self in method

(ANN101)


362-362: Unnecessary parentheses on raised exception

Remove unnecessary parentheses

(RSE102)


371-371: Missing return type annotation for public function store_object

Add return type annotation: None

(ANN201)


371-371: Missing type annotation for self in method

(ANN101)


381-381: Trailing comma missing

Add trailing comma

(COM812)


389-389: Missing return type annotation for public function remove

Add return type annotation: None

(ANN201)


389-389: Missing type annotation for self in method

(ANN101)


405-405: Missing type annotation for self in method

(ANN101)

Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

Commits

Files that changed from the base of the PR and between 58358ae and 21156a4.

Files ignored due to path filters (1)
  • pyproject.toml is excluded by !pyproject.toml
Files selected for processing (2)
  • docs/intro.md (1 hunks)
  • snakemake_storage_plugin_xrootd/init.py (5 hunks)
Additional context used
Path-based instructions (1)
snakemake_storage_plugin_xrootd/__init__.py (1)

Pattern **/*.py: Do not suggest to add trailing commas.
Do not suggest type annotations for functions that are defined inside of functions or methods.
Do not suggest type annotation of the self argument of methods.

Markdownlint
docs/intro.md

1-1: null
First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)

Ruff
snakemake_storage_plugin_xrootd/__init__.py

34-34: Unnecessary pass statement

Remove unnecessary pass

(PIE790)


37-37: Missing return type annotation for private function _raise_fatal_error

Add return type annotation: None

(ANN202)


45-45: Trailing comma missing

Add trailing comma

(COM812)


94-94: Missing return type annotation for special method __post_init__

(ANN204)


94-94: Missing type annotation for self in method

(ANN101)


119-119: Missing return type annotation for private function _check_status

Add return type annotation: None

(ANN202)


119-119: Missing type annotation for self in method

(ANN101)


122-122: Avoid specifying long messages outside the exception class

(TRY003)


123-123: Unnecessary else after raise statement

(RET506)


124-124: Replace aliased errors with OSError

Replace IOError with builtin OSError

(UP024)


124-124: Avoid specifying long messages outside the exception class

(TRY003)


127-127: Missing type annotation for cls in classmethod

(ANN102)


145-145: Missing type annotation for self in method

(ANN101)


145-145: Unused method argument: query

(ARG002)


145-145: Unused method argument: operation

(ARG002)


145-145: Dynamically typed expressions (typing.Any) are disallowed in rate_limiter_key

(ANN401)


154-154: Missing type annotation for self in method

(ANN101)


159-159: Missing type annotation for self in method

(ANN101)


168-168: Unnecessary else after return statement

(RET505)


180-180: Missing type annotation for self in method

(ANN101)


187-190: Use ternary operator user_pass = f"{user}:{password}@" if password != "" else f"{user}@" instead of if-else-block

Replace if-else-block with user_pass = f"{user}:{password}@" if password != "" else f"{user}@"

(SIM108)


193-193: Replace aliased errors with OSError

Replace IOError with builtin OSError

(UP024)


193-195: Avoid specifying long messages outside the exception class

(TRY003)


194-194: Trailing comma missing

Add trailing comma

(COM812)


208-208: Replace aliased errors with OSError

Replace IOError with builtin OSError

(UP024)


208-211: Avoid specifying long messages outside the exception class

(TRY003)


210-210: Trailing comma missing

Add trailing comma

(COM812)


212-212: Unnecessary else after raise statement

(RET506)


213-213: Replace aliased errors with OSError

Replace IOError with builtin OSError

(UP024)


213-215: Avoid specifying long messages outside the exception class

(TRY003)


214-214: Trailing comma missing

Add trailing comma

(COM812)


228-228: Missing type annotation for cls in classmethod

(ANN102)


240-240: Unnecessary else after return statement

(RET505)


255-255: Missing return type annotation for special method __post_init__

(ANN204)


255-255: Missing type annotation for self in method

(ANN101)


282-282: Missing type annotation for self in method

(ANN101)


288-288: Missing return type annotation for public function cleanup

Add return type annotation: None

(ANN201)


288-288: Missing type annotation for self in method

(ANN101)


292-292: Unnecessary pass statement

Remove unnecessary pass

(PIE790)


295-295: Missing type annotation for self in method

(ANN101)


298-298: Missing type annotation for self in method

(ANN101)


298-298: Missing type annotation for function argument query

(ANN001)


315-315: Missing type annotation for self in method

(ANN101)


325-325: Missing type annotation for self in method

(ANN101)


335-335: Missing return type annotation for public function retrieve_object

Add return type annotation: None

(ANN201)


335-335: Missing type annotation for self in method

(ANN101)


360-360: Missing return type annotation for private function _makedirs

Add return type annotation: None

(ANN202)


360-360: Missing type annotation for self in method

(ANN101)


362-362: Unnecessary parentheses on raised exception

Remove unnecessary parentheses

(RSE102)


371-371: Missing return type annotation for public function store_object

Add return type annotation: None

(ANN201)


371-371: Missing type annotation for self in method

(ANN101)


381-381: Trailing comma missing

Add trailing comma

(COM812)


389-389: Missing return type annotation for public function remove

Add return type annotation: None

(ANN201)


389-389: Missing type annotation for self in method

(ANN101)

Additional comments not posted (2)
snakemake_storage_plugin_xrootd/__init__.py (2)

83-87: Ensure url_decorator is correctly documented and tested.

The url_decorator is a new feature that allows for URL modification. Ensure this is well-documented and tested to avoid unexpected behavior.


294-310: Ensure the retry decorator is applied consistently.

The @xrootd_retry decorator should be consistently applied to methods that can benefit from retry logic, such as exists and _exists.

Verification successful

Consistent Application of @xrootd_retry Decorator Verified

The @xrootd_retry decorator is consistently applied to methods interacting with the XRootD system, except for retrieve_object, which is commented out. This might be intentional. Please review if this exception is appropriate.

  • Methods with @xrootd_retry: exists, mtime, size, _makedirs, store_object, remove
  • Commented out: retrieve_object
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the consistent application of the `@xrootd_retry` decorator.

# Test: Search for the usage of `@xrootd_retry` in the codebase.
rg --type python '@xrootd_retry'

Length of output: 63


Script:

#!/bin/bash
# Description: Verify the consistent application of the `@xrootd_retry` decorator.

# Find all Python files and search for `@xrootd_retry` within them.
fd --extension py --exec rg '@xrootd_retry' {}

Length of output: 176


Script:

#!/bin/bash
# Description: Capture surrounding lines of each `@xrootd_retry` usage to identify decorated methods.

# Find all Python files and search for `@xrootd_retry`, including context lines.
fd --extension py --exec rg --context 3 '@xrootd_retry' {}

Length of output: 1457

Tools
Ruff

295-295: Missing type annotation for self in method

(ANN101)


298-298: Missing type annotation for self in method

(ANN101)


298-298: Missing type annotation for function argument query

(ANN001)

docs/intro.md Show resolved Hide resolved
snakemake_storage_plugin_xrootd/__init__.py Outdated Show resolved Hide resolved
snakemake_storage_plugin_xrootd/__init__.py Outdated Show resolved Hide resolved
snakemake_storage_plugin_xrootd/__init__.py Outdated Show resolved Hide resolved
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
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: 7

Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

Commits

Files that changed from the base of the PR and between 21156a4 and 8e8e3e5.

Files selected for processing (1)
  • snakemake_storage_plugin_xrootd/init.py (5 hunks)
Additional context used
Path-based instructions (1)
snakemake_storage_plugin_xrootd/__init__.py (1)

Pattern **/*.py: Do not suggest to add trailing commas.
Do not suggest type annotations for functions that are defined inside of functions or methods.
Do not suggest type annotation of the self argument of methods.

Ruff
snakemake_storage_plugin_xrootd/__init__.py

34-34: Unnecessary pass statement

Remove unnecessary pass

(PIE790)


37-37: Missing return type annotation for private function _raise_fatal_error

Add return type annotation: None

(ANN202)


45-45: Trailing comma missing

Add trailing comma

(COM812)


94-94: Missing return type annotation for special method __post_init__

(ANN204)


94-94: Missing type annotation for self in method

(ANN101)


119-119: Missing return type annotation for private function _check_status

Add return type annotation: None

(ANN202)


119-119: Missing type annotation for self in method

(ANN101)


122-122: Avoid specifying long messages outside the exception class

(TRY003)


123-123: Unnecessary else after raise statement

(RET506)


124-124: Replace aliased errors with OSError

Replace IOError with builtin OSError

(UP024)


124-124: Avoid specifying long messages outside the exception class

(TRY003)


127-127: Missing type annotation for cls in classmethod

(ANN102)


145-145: Missing type annotation for self in method

(ANN101)


145-145: Unused method argument: query

(ARG002)


145-145: Unused method argument: operation

(ARG002)


145-145: Dynamically typed expressions (typing.Any) are disallowed in rate_limiter_key

(ANN401)


154-154: Missing type annotation for self in method

(ANN101)


159-159: Missing type annotation for self in method

(ANN101)


168-168: Unnecessary else after return statement

(RET505)


180-180: Missing type annotation for self in method

(ANN101)


187-190: Use ternary operator user_pass = f"{user}:{password}@" if password != "" else f"{user}@" instead of if-else-block

Replace if-else-block with user_pass = f"{user}:{password}@" if password != "" else f"{user}@"

(SIM108)


193-193: Replace aliased errors with OSError

Replace IOError with builtin OSError

(UP024)


193-195: Avoid specifying long messages outside the exception class

(TRY003)


194-194: Trailing comma missing

Add trailing comma

(COM812)


208-208: Replace aliased errors with OSError

Replace IOError with builtin OSError

(UP024)


208-211: Avoid specifying long messages outside the exception class

(TRY003)


210-210: Trailing comma missing

Add trailing comma

(COM812)


212-212: Unnecessary else after raise statement

(RET506)


213-213: Replace aliased errors with OSError

Replace IOError with builtin OSError

(UP024)


213-215: Avoid specifying long messages outside the exception class

(TRY003)


214-214: Trailing comma missing

Add trailing comma

(COM812)


228-228: Missing type annotation for cls in classmethod

(ANN102)


240-240: Unnecessary else after return statement

(RET505)


254-254: Missing return type annotation for special method __post_init__

(ANN204)


254-254: Missing type annotation for self in method

(ANN101)


281-281: Missing type annotation for self in method

(ANN101)


287-287: Missing return type annotation for public function cleanup

Add return type annotation: None

(ANN201)


287-287: Missing type annotation for self in method

(ANN101)


291-291: Unnecessary pass statement

Remove unnecessary pass

(PIE790)


294-294: Missing type annotation for self in method

(ANN101)


297-297: Missing type annotation for self in method

(ANN101)


297-297: Missing type annotation for function argument query

(ANN001)


314-314: Missing type annotation for self in method

(ANN101)


324-324: Missing type annotation for self in method

(ANN101)


334-334: Missing return type annotation for public function retrieve_object

Add return type annotation: None

(ANN201)


334-334: Missing type annotation for self in method

(ANN101)


359-359: Missing return type annotation for private function _makedirs

Add return type annotation: None

(ANN202)


359-359: Missing type annotation for self in method

(ANN101)


361-361: Unnecessary parentheses on raised exception

Remove unnecessary parentheses

(RSE102)


370-370: Missing return type annotation for public function store_object

Add return type annotation: None

(ANN201)


370-370: Missing type annotation for self in method

(ANN101)


380-380: Trailing comma missing

Add trailing comma

(COM812)


388-388: Missing return type annotation for public function remove

Add return type annotation: None

(ANN201)


388-388: Missing type annotation for self in method

(ANN101)

Additional comments not posted (3)
snakemake_storage_plugin_xrootd/__init__.py (3)

2-10: Imports look good!

The import section is well-organized and includes necessary modules for the functionality.


83-87: The addition of url_decorator looks good!

The url_decorator field provides flexibility for URL decoration, enhancing URL management capabilities.


131-141: Example queries look good!

The method provides clear and useful example queries for the storage provider.

snakemake_storage_plugin_xrootd/__init__.py Show resolved Hide resolved
snakemake_storage_plugin_xrootd/__init__.py Outdated Show resolved Hide resolved
snakemake_storage_plugin_xrootd/__init__.py Outdated Show resolved Hide resolved
snakemake_storage_plugin_xrootd/__init__.py Outdated Show resolved Hide resolved
snakemake_storage_plugin_xrootd/__init__.py Outdated Show resolved Hide resolved
snakemake_storage_plugin_xrootd/__init__.py Outdated Show resolved Hide resolved
snakemake_storage_plugin_xrootd/__init__.py Outdated Show resolved Hide resolved
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: 12

Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

Commits

Files that changed from the base of the PR and between 8e8e3e5 and 16150f4.

Files selected for processing (2)
  • docs/intro.md (1 hunks)
  • snakemake_storage_plugin_xrootd/init.py (5 hunks)
Additional context used
Path-based instructions (1)
snakemake_storage_plugin_xrootd/__init__.py (1)

Pattern **/*.py: Do not suggest to add trailing commas.
Do not suggest type annotations for functions that are defined inside of functions or methods.
Do not suggest type annotation of the self argument of methods.

LanguageTool
docs/intro.md

[uncategorized] ~5-~5: Possible missing comma found.
Context: ... specifying any options relating to the URLs in which case all of the information mu...

(AI_HYDRA_LEO_MISSING_COMMA)


[style] ~5-~5: Consider removing “of” to be more concise
Context: ...ions relating to the URLs in which case all of the information must be contained in the UR...

(ALL_OF_THE)

Markdownlint
docs/intro.md

1-1: null
First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)

Ruff
snakemake_storage_plugin_xrootd/__init__.py

43-43: Trailing comma missing

Add trailing comma

(COM812)


92-92: Missing return type annotation for special method __post_init__

(ANN204)


92-92: Missing type annotation for self in method

(ANN101)


117-117: Missing return type annotation for private function _check_status

Add return type annotation: None

(ANN202)


117-117: Missing type annotation for self in method

(ANN101)


120-120: Avoid specifying long messages outside the exception class

(TRY003)


121-121: Unnecessary else after raise statement

(RET506)


122-122: Avoid specifying long messages outside the exception class

(TRY003)


125-125: Missing type annotation for cls in classmethod

(ANN102)


143-143: Missing type annotation for self in method

(ANN101)


143-143: Unused method argument: query

(ARG002)


143-143: Unused method argument: operation

(ARG002)


143-143: Dynamically typed expressions (typing.Any) are disallowed in rate_limiter_key

(ANN401)


152-152: Missing type annotation for self in method

(ANN101)


157-157: Missing type annotation for self in method

(ANN101)


166-166: Unnecessary else after return statement

(RET505)


178-178: Missing type annotation for self in method

(ANN101)


185-188: Use ternary operator user_pass = f"{user}:{password}@" if password != "" else f"{user}@" instead of if-else-block

Replace if-else-block with user_pass = f"{user}:{password}@" if password != "" else f"{user}@"

(SIM108)


191-193: Avoid specifying long messages outside the exception class

(TRY003)


192-192: Trailing comma missing

Add trailing comma

(COM812)


206-209: Avoid specifying long messages outside the exception class

(TRY003)


208-208: Trailing comma missing

Add trailing comma

(COM812)


210-210: Unnecessary else after raise statement

(RET506)


211-213: Avoid specifying long messages outside the exception class

(TRY003)


212-212: Trailing comma missing

Add trailing comma

(COM812)


226-226: Missing type annotation for cls in classmethod

(ANN102)


238-238: Unnecessary else after return statement

(RET505)


252-252: Missing return type annotation for special method __post_init__

(ANN204)


252-252: Missing type annotation for self in method

(ANN101)


279-279: Missing type annotation for self in method

(ANN101)


285-285: Missing return type annotation for public function cleanup

Add return type annotation: None

(ANN201)


285-285: Missing type annotation for self in method

(ANN101)


289-289: Unnecessary pass statement

Remove unnecessary pass

(PIE790)


292-292: Missing type annotation for self in method

(ANN101)


295-295: Missing type annotation for self in method

(ANN101)


295-295: Missing type annotation for function argument query

(ANN001)


312-312: Missing type annotation for self in method

(ANN101)


322-322: Missing type annotation for self in method

(ANN101)


332-332: Missing return type annotation for public function retrieve_object

Add return type annotation: None

(ANN201)


332-332: Missing type annotation for self in method

(ANN101)


357-357: Missing return type annotation for private function _makedirs

Add return type annotation: None

(ANN202)


357-357: Missing type annotation for self in method

(ANN101)


367-367: Missing return type annotation for public function store_object

Add return type annotation: None

(ANN201)


367-367: Missing type annotation for self in method

(ANN101)


377-377: Trailing comma missing

Add trailing comma

(COM812)


385-385: Missing return type annotation for public function remove

Add return type annotation: None

(ANN201)


385-385: Missing type annotation for self in method

(ANN101)

Additional comments not posted (4)
snakemake_storage_plugin_xrootd/__init__.py (4)

29-33: LGTM!

The XRootDFatalException class is well-defined and serves its purpose of preventing retries for certain errors.


Line range hint 44-87: LGTM!

The addition of the url_decorator field in StorageProviderSettings enhances flexibility in URL handling.

Tools
Ruff

92-92: Missing return type annotation for special method __post_init__

(ANN204)


92-92: Missing type annotation for self in method

(ANN101)


117-117: Missing return type annotation for private function _check_status

Add return type annotation: None

(ANN202)


117-117: Missing type annotation for self in method

(ANN101)


120-120: Avoid specifying long messages outside the exception class

(TRY003)


121-121: Unnecessary else after raise statement

(RET506)


122-122: Avoid specifying long messages outside the exception class

(TRY003)


125-125: Missing type annotation for cls in classmethod

(ANN102)


143-143: Missing type annotation for self in method

(ANN101)


143-143: Unused method argument: query

(ARG002)


143-143: Unused method argument: operation

(ARG002)


143-143: Dynamically typed expressions (typing.Any) are disallowed in rate_limiter_key

(ANN401)


152-152: Missing type annotation for self in method

(ANN101)


157-157: Missing type annotation for self in method

(ANN101)


166-166: Unnecessary else after return statement

(RET505)


178-178: Missing type annotation for self in method

(ANN101)


185-188: Use ternary operator user_pass = f"{user}:{password}@" if password != "" else f"{user}@" instead of if-else-block

Replace if-else-block with user_pass = f"{user}:{password}@" if password != "" else f"{user}@"

(SIM108)


191-193: Avoid specifying long messages outside the exception class

(TRY003)


192-192: Trailing comma missing

Add trailing comma

(COM812)


206-209: Avoid specifying long messages outside the exception class

(TRY003)


208-208: Trailing comma missing

Add trailing comma

(COM812)


210-210: Unnecessary else after raise statement

(RET506)


211-213: Avoid specifying long messages outside the exception class

(TRY003)


212-212: Trailing comma missing

Add trailing comma

(COM812)


226-226: Missing type annotation for cls in classmethod

(ANN102)


238-238: Unnecessary else after return statement

(RET505)


252-252: Missing return type annotation for special method __post_init__

(ANN204)


252-252: Missing type annotation for self in method

(ANN101)


261-261: Missing return type annotation for public function inventory

Add return type annotation: None

(ANN201)


261-261: Missing type annotation for self in method

(ANN101)


35-38: Add a return type annotation for _raise_fatal_error.

Consider adding a return type annotation to indicate that this function returns None.

def _raise_fatal_error(exception: Type[Exception]) -> None:

Likely invalid or redundant comment.


247-259: Ensure __post_init__ is called after is_valid_query.

The comment suggests uncertainty about whether is_valid_query is called before __post_init__. Ensure this sequence is correct to avoid potential issues.

Tools
Ruff

252-252: Missing return type annotation for special method __post_init__

(ANN204)


252-252: Missing type annotation for self in method

(ANN101)

docs/intro.md Show resolved Hide resolved
docs/intro.md Outdated Show resolved Hide resolved
snakemake_storage_plugin_xrootd/__init__.py Outdated Show resolved Hide resolved
snakemake_storage_plugin_xrootd/__init__.py Outdated Show resolved Hide resolved
snakemake_storage_plugin_xrootd/__init__.py Show resolved Hide resolved
snakemake_storage_plugin_xrootd/__init__.py Outdated Show resolved Hide resolved
snakemake_storage_plugin_xrootd/__init__.py Show resolved Hide resolved
snakemake_storage_plugin_xrootd/__init__.py Show resolved Hide resolved
snakemake_storage_plugin_xrootd/__init__.py Outdated Show resolved Hide resolved
snakemake_storage_plugin_xrootd/__init__.py Outdated Show resolved Hide resolved
@MattMonk
Copy link
Collaborator Author

@johanneskoester in the end I put back the options for specifying the host/port/username/password as optional arguments so that it can be used with "fully-formed" URLs or simpler ones which specify some of the information via the storage provider as they could still be useful (and not that much extra effort to include them).

I did have one question however but I was unsure if this is just because I missed something or if it is the expected behaviour:
When I specify a host with the provider, if I then use retrieve=False the input is passed "as-is" rather than the parsed URL with the host in. For example:

storage:
    provider="xrootd",
    retrieve=False,
    host="eosuser.cern.ch"

rule some_rule:
    input: storage.xrootd("root://eos/user/m/mmonk/some_file.root")
    output: "test.root"
    shell: "python some_script.py {input} {output}"

I can see internally it correctly renders the URL to "root://eosuser.cern.ch//eos/user/m/mmonk/some_file.root" to check that it exists but then passes "root://eos/user/m/mmonk/some_file.root" as the input to the script instead of the rendered one.
Using retrieve=True it picks up the right URL and is able to download it so it's only a problem with retrieve=False but I was unsure if that is what it is snakemake is supposed to do or I've just missed something somewhere.

Sorry if that's a bit of an unclear question, hopefully that makes sense!

@johanneskoester
Copy link
Contributor

Good point. I did not foresee that there might be the requirement to return a modified URL when retrieve is set to false. I now think about how to best implement that.

@johanneskoester
Copy link
Contributor

Btw. do you want to become a maintainer of this plugin? You are certainly much better suited than I am.

@johanneskoester
Copy link
Contributor

johanneskoester commented Aug 19, 2024

@MattMonk I have added a skeleton for modifying the query. This uses the new method postprocess_query from StorageProviderBase. You can simply modify the query URL there as needed and then return it. That (together with snakemake/snakemake#3031) should solve exactly the use case that you have here because the modified query will end up in the storage object but also in the string that is passed on to scripts and commands in case of retrieve=False.

@MattMonk
Copy link
Collaborator Author

Aha fantastic! Many thanks for putting the postprocess_query together on the snakemake side -- I'll get the skeleton filled out.

Yeah I'd be more than happy to be added as a maintainer for this, thanks!

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: 6

Outside diff range comments (1)
snakemake_storage_plugin_xrootd/__init__.py (1)

Line range hint 255-295: Remove unnecessary pass statement.

The pass statement is not needed in this context as the method is already defined with a docstring.

- pass
Tools
Ruff

280-280: Missing type annotation for self in method

(ANN101)


285-285: Missing type annotation for self in method

(ANN101)


291-291: Missing return type annotation for public function cleanup

Add return type annotation: None

(ANN201)


291-291: Missing type annotation for self in method

(ANN101)


295-295: Unnecessary pass statement

Remove unnecessary pass

(PIE790)


298-298: Missing type annotation for self in method

(ANN101)


301-301: Missing type annotation for self in method

(ANN101)


301-301: Missing type annotation for function argument query

(ANN001)


318-318: Missing type annotation for self in method

(ANN101)


328-328: Missing type annotation for self in method

(ANN101)


338-338: Missing return type annotation for public function retrieve_object

Add return type annotation: None

(ANN201)


338-338: Missing type annotation for self in method

(ANN101)


363-363: Missing return type annotation for private function _makedirs

Add return type annotation: None

(ANN202)


363-363: Missing type annotation for self in method

(ANN101)


373-373: Missing return type annotation for public function store_object

Add return type annotation: None

(ANN201)


373-373: Missing type annotation for self in method

(ANN101)


383-383: Trailing comma missing

Add trailing comma

(COM812)


391-391: Missing return type annotation for public function remove

Add return type annotation: None

(ANN201)


391-391: Missing type annotation for self in method

(ANN101)


407-407: Missing type annotation for self in method

(ANN101)

Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

Commits

Files that changed from the base of the PR and between 16150f4 and cb605f5.

Files ignored due to path filters (1)
  • pyproject.toml is excluded by !pyproject.toml
Files selected for processing (2)
  • docs/further.md (1 hunks)
  • snakemake_storage_plugin_xrootd/init.py (5 hunks)
Additional context used
Path-based instructions (1)
snakemake_storage_plugin_xrootd/__init__.py (1)

Pattern **/*.py: Do not suggest to add trailing commas for improving formatting.
Do not try to improve formatting.
Do not suggest type annotations for functions that are defined inside of functions or methods.
Do not suggest type annotation of the self argument of methods.
Do not suggest type annotation of the cls argument of classmethods.
Do not suggest return type annotation if a function or method does not explicitly return anything.

Markdownlint
docs/further.md

1-1: null
First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)

Ruff
snakemake_storage_plugin_xrootd/__init__.py

43-43: Trailing comma missing

Add trailing comma

(COM812)


92-92: Missing return type annotation for special method __post_init__

(ANN204)


92-92: Missing type annotation for self in method

(ANN101)


117-117: Missing return type annotation for private function _check_status

Add return type annotation: None

(ANN202)


117-117: Missing type annotation for self in method

(ANN101)


120-120: Avoid specifying long messages outside the exception class

(TRY003)


121-121: Unnecessary else after raise statement

(RET506)


122-122: Avoid specifying long messages outside the exception class

(TRY003)


125-125: Missing type annotation for cls in classmethod

(ANN102)


143-143: Missing type annotation for self in method

(ANN101)


143-143: Unused method argument: query

(ARG002)


143-143: Unused method argument: operation

(ARG002)


143-143: Dynamically typed expressions (typing.Any) are disallowed in rate_limiter_key

(ANN401)


152-152: Missing type annotation for self in method

(ANN101)


157-157: Missing type annotation for self in method

(ANN101)


166-166: Unnecessary else after return statement

(RET505)


174-174: Unnecessary else after return statement

(RET505)


181-181: Missing type annotation for self in method

(ANN101)


188-191: Use ternary operator user_pass = f"{user}:{password}@" if password != "" else f"{user}@" instead of if-else-block

Replace if-else-block with user_pass = f"{user}:{password}@" if password != "" else f"{user}@"

(SIM108)


194-196: Avoid specifying long messages outside the exception class

(TRY003)


195-195: Trailing comma missing

Add trailing comma

(COM812)


209-212: Avoid specifying long messages outside the exception class

(TRY003)


211-211: Trailing comma missing

Add trailing comma

(COM812)


213-213: Unnecessary else after raise statement

(RET506)


214-216: Avoid specifying long messages outside the exception class

(TRY003)


215-215: Trailing comma missing

Add trailing comma

(COM812)


229-229: Missing type annotation for cls in classmethod

(ANN102)


241-241: Unnecessary else after return statement

(RET505)


244-244: Missing type annotation for self in method

(ANN101)


260-260: Missing return type annotation for special method __post_init__

(ANN204)


260-260: Missing type annotation for self in method

(ANN101)


285-285: Missing type annotation for self in method

(ANN101)


291-291: Missing return type annotation for public function cleanup

Add return type annotation: None

(ANN201)


291-291: Missing type annotation for self in method

(ANN101)


295-295: Unnecessary pass statement

Remove unnecessary pass

(PIE790)


298-298: Missing type annotation for self in method

(ANN101)


301-301: Missing type annotation for self in method

(ANN101)


301-301: Missing type annotation for function argument query

(ANN001)


318-318: Missing type annotation for self in method

(ANN101)


328-328: Missing type annotation for self in method

(ANN101)


338-338: Missing return type annotation for public function retrieve_object

Add return type annotation: None

(ANN201)


338-338: Missing type annotation for self in method

(ANN101)


363-363: Missing return type annotation for private function _makedirs

Add return type annotation: None

(ANN202)


363-363: Missing type annotation for self in method

(ANN101)


373-373: Missing return type annotation for public function store_object

Add return type annotation: None

(ANN201)


373-373: Missing type annotation for self in method

(ANN101)


383-383: Trailing comma missing

Add trailing comma

(COM812)


391-391: Missing return type annotation for public function remove

Add return type annotation: None

(ANN201)


391-391: Missing type annotation for self in method

(ANN101)

Additional comments not posted (6)
snakemake_storage_plugin_xrootd/__init__.py (6)

2-3: LGTM!

The imports and the custom exception class XRootDFatalException are appropriate for the functionality being implemented.

Also applies to: 8-10, 29-33


Line range hint 44-85: LGTM!

The StorageProviderSettings class is well-defined, and the addition of the url_decorator field enhances URL customization flexibility.

Tools
Ruff

92-92: Missing return type annotation for special method __post_init__

(ANN204)


92-92: Missing type annotation for self in method

(ANN101)


117-117: Missing return type annotation for private function _check_status

Add return type annotation: None

(ANN202)


117-117: Missing type annotation for self in method

(ANN101)


120-120: Avoid specifying long messages outside the exception class

(TRY003)


121-121: Unnecessary else after raise statement

(RET506)


122-122: Avoid specifying long messages outside the exception class

(TRY003)


125-125: Missing type annotation for cls in classmethod

(ANN102)


143-143: Missing type annotation for self in method

(ANN101)


143-143: Unused method argument: query

(ARG002)


143-143: Unused method argument: operation

(ARG002)


143-143: Dynamically typed expressions (typing.Any) are disallowed in rate_limiter_key

(ANN401)


152-152: Missing type annotation for self in method

(ANN101)


157-157: Missing type annotation for self in method

(ANN101)


166-166: Unnecessary else after return statement

(RET505)


174-174: Unnecessary else after return statement

(RET505)


181-181: Missing type annotation for self in method

(ANN101)


188-191: Use ternary operator user_pass = f"{user}:{password}@" if password != "" else f"{user}@" instead of if-else-block

Replace if-else-block with user_pass = f"{user}:{password}@" if password != "" else f"{user}@"

(SIM108)


194-196: Avoid specifying long messages outside the exception class

(TRY003)


195-195: Trailing comma missing

Add trailing comma

(COM812)


209-212: Avoid specifying long messages outside the exception class

(TRY003)


211-211: Trailing comma missing

Add trailing comma

(COM812)


213-213: Unnecessary else after raise statement

(RET506)


214-216: Avoid specifying long messages outside the exception class

(TRY003)


215-215: Trailing comma missing

Add trailing comma

(COM812)


229-229: Missing type annotation for cls in classmethod

(ANN102)


241-241: Unnecessary else after return statement

(RET505)


244-244: Missing type annotation for self in method

(ANN101)


260-260: Missing return type annotation for special method __post_init__

(ANN204)


260-260: Missing type annotation for self in method

(ANN101)


267-267: Missing return type annotation for public function inventory

Add return type annotation: None

(ANN201)


267-267: Missing type annotation for self in method

(ANN101)


125-139: LGTM!

The example_queries method provides clear and useful examples for users.

Tools
Ruff

125-125: Missing type annotation for cls in classmethod

(ANN102)


142-157: LGTM!

The rate limiter methods provide basic functionality suitable for the current implementation.

Tools
Ruff

143-143: Missing type annotation for self in method

(ANN101)


143-143: Unused method argument: query

(ARG002)


143-143: Unused method argument: operation

(ARG002)


143-143: Dynamically typed expressions (typing.Any) are disallowed in rate_limiter_key

(ANN401)


152-152: Missing type annotation for self in method

(ANN101)


157-157: Missing type annotation for self in method

(ANN101)


297-401: LGTM!

The file operation methods are well-implemented with appropriate retry logic and error handling.

Tools
Ruff

298-298: Missing type annotation for self in method

(ANN101)


301-301: Missing type annotation for self in method

(ANN101)


301-301: Missing type annotation for function argument query

(ANN001)


318-318: Missing type annotation for self in method

(ANN101)


328-328: Missing type annotation for self in method

(ANN101)


338-338: Missing return type annotation for public function retrieve_object

Add return type annotation: None

(ANN201)


338-338: Missing type annotation for self in method

(ANN101)


363-363: Missing return type annotation for private function _makedirs

Add return type annotation: None

(ANN202)


363-363: Missing type annotation for self in method

(ANN101)


373-373: Missing return type annotation for public function store_object

Add return type annotation: None

(ANN201)


373-373: Missing type annotation for self in method

(ANN101)


383-383: Trailing comma missing

Add trailing comma

(COM812)


391-391: Missing return type annotation for public function remove

Add return type annotation: None

(ANN201)


391-391: Missing type annotation for self in method

(ANN101)


Line range hint 405-411: LGTM!

The list_candidate_matches method is appropriately marked with a TODO comment and raises a NotImplementedError for future implementation.

Tools
Ruff

280-280: Missing type annotation for self in method

(ANN101)


285-285: Missing type annotation for self in method

(ANN101)


291-291: Missing return type annotation for public function cleanup

Add return type annotation: None

(ANN201)


291-291: Missing type annotation for self in method

(ANN101)


295-295: Unnecessary pass statement

Remove unnecessary pass

(PIE790)


298-298: Missing type annotation for self in method

(ANN101)


301-301: Missing type annotation for self in method

(ANN101)


301-301: Missing type annotation for function argument query

(ANN001)


318-318: Missing type annotation for self in method

(ANN101)


328-328: Missing type annotation for self in method

(ANN101)


338-338: Missing return type annotation for public function retrieve_object

Add return type annotation: None

(ANN201)


338-338: Missing type annotation for self in method

(ANN101)


363-363: Missing return type annotation for private function _makedirs

Add return type annotation: None

(ANN202)


363-363: Missing type annotation for self in method

(ANN101)


373-373: Missing return type annotation for public function store_object

Add return type annotation: None

(ANN201)


373-373: Missing type annotation for self in method

(ANN101)


383-383: Trailing comma missing

Add trailing comma

(COM812)


391-391: Missing return type annotation for public function remove

Add return type annotation: None

(ANN201)


391-391: Missing type annotation for self in method

(ANN101)


407-407: Missing type annotation for self in method

(ANN101)

docs/further.md Show resolved Hide resolved
snakemake_storage_plugin_xrootd/__init__.py Show resolved Hide resolved
snakemake_storage_plugin_xrootd/__init__.py Outdated Show resolved Hide resolved
snakemake_storage_plugin_xrootd/__init__.py Outdated Show resolved Hide resolved
snakemake_storage_plugin_xrootd/__init__.py Outdated Show resolved Hide resolved
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

Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

Commits

Files that changed from the base of the PR and between cb605f5 and 9932e11.

Files selected for processing (1)
  • snakemake_storage_plugin_xrootd/init.py (5 hunks)
Additional context used
Path-based instructions (1)
snakemake_storage_plugin_xrootd/__init__.py (1)

Pattern **/*.py: Do not suggest to add trailing commas for improving formatting.
Do not try to improve formatting.
Do not suggest type annotations for functions that are defined inside of functions or methods.
Do not suggest type annotation of the self argument of methods.
Do not suggest type annotation of the cls argument of classmethods.
Do not suggest return type annotation if a function or method does not explicitly return anything.

Ruff
snakemake_storage_plugin_xrootd/__init__.py

43-43: Trailing comma missing

Add trailing comma

(COM812)


92-92: Missing return type annotation for special method __post_init__

(ANN204)


92-92: Missing type annotation for self in method

(ANN101)


117-117: Missing return type annotation for private function _check_status

Add return type annotation: None

(ANN202)


117-117: Missing type annotation for self in method

(ANN101)


120-120: Avoid specifying long messages outside the exception class

(TRY003)


121-121: Avoid specifying long messages outside the exception class

(TRY003)


124-124: Missing type annotation for cls in classmethod

(ANN102)


142-142: Missing type annotation for self in method

(ANN101)


142-142: Unused method argument: query

(ARG002)


142-142: Unused method argument: operation

(ARG002)


142-142: Dynamically typed expressions (typing.Any) are disallowed in rate_limiter_key

(ANN401)


151-151: Missing type annotation for self in method

(ANN101)


156-156: Missing type annotation for self in method

(ANN101)


178-178: Missing type annotation for self in method

(ANN101)


185-188: Use ternary operator user_pass = f"{user}:{password}@" if password != "" else f"{user}@" instead of if-else-block

Replace if-else-block with user_pass = f"{user}:{password}@" if password != "" else f"{user}@"

(SIM108)


191-193: Avoid specifying long messages outside the exception class

(TRY003)


192-192: Trailing comma missing

Add trailing comma

(COM812)


206-209: Avoid specifying long messages outside the exception class

(TRY003)


208-208: Trailing comma missing

Add trailing comma

(COM812)


210-210: Unnecessary else after raise statement

(RET506)


211-213: Avoid specifying long messages outside the exception class

(TRY003)


212-212: Trailing comma missing

Add trailing comma

(COM812)


226-226: Missing type annotation for cls in classmethod

(ANN102)


240-240: Missing type annotation for self in method

(ANN101)


256-256: Missing return type annotation for special method __post_init__

(ANN204)


256-256: Missing type annotation for self in method

(ANN101)


281-281: Missing type annotation for self in method

(ANN101)


287-287: Missing return type annotation for public function cleanup

Add return type annotation: None

(ANN201)


287-287: Missing type annotation for self in method

(ANN101)


291-291: Unnecessary pass statement

Remove unnecessary pass

(PIE790)


294-294: Missing type annotation for self in method

(ANN101)


297-297: Missing type annotation for self in method

(ANN101)


297-297: Missing type annotation for function argument query

(ANN001)


314-314: Missing type annotation for self in method

(ANN101)


324-324: Missing type annotation for self in method

(ANN101)


334-334: Missing return type annotation for public function retrieve_object

Add return type annotation: None

(ANN201)


334-334: Missing type annotation for self in method

(ANN101)


359-359: Missing return type annotation for private function _makedirs

Add return type annotation: None

(ANN202)


359-359: Missing type annotation for self in method

(ANN101)


369-369: Missing return type annotation for public function store_object

Add return type annotation: None

(ANN201)


369-369: Missing type annotation for self in method

(ANN101)


379-379: Trailing comma missing

Add trailing comma

(COM812)


387-387: Missing return type annotation for public function remove

Add return type annotation: None

(ANN201)


387-387: Missing type annotation for self in method

(ANN101)

Additional comments not posted (13)
snakemake_storage_plugin_xrootd/__init__.py (13)

2-4: Imports look good.

The imports are appropriate and consistent with the functionality provided in the file.


29-33: Custom exception class is well-defined.

The XRootDFatalException class is appropriately defined for handling non-retryable XRootD errors.


35-38: Error handling function is correctly implemented.

The _raise_fatal_error function is well-suited for handling fatal exceptions by logging and re-raising them.


41-44: Retry settings are hardcoded as per current requirements.

While making them configurable could add flexibility, the current setup is acceptable based on previous discussions.

Tools
Ruff

43-43: Trailing comma missing

Add trailing comma

(COM812)


81-85: Addition of url_decorator enhances flexibility.

The url_decorator field in StorageProviderSettings allows for more flexible URL construction, which is a beneficial enhancement.


240-243: Postprocess query method is correctly implemented.

The postprocess_query method effectively utilizes the _parse_url method to modify the query URL.

Tools
Ruff

240-240: Missing type annotation for self in method

(ANN101)


251-259: Initialization logic in StorageObject is appropriate.

The __post_init__ method correctly initializes attributes using the _parse_url method.

Tools
Ruff

256-256: Missing return type annotation for special method __post_init__

(ANN204)


256-256: Missing type annotation for self in method

(ANN101)


293-309: Existence check methods are well-implemented.

The exists and _exists methods correctly handle file existence checks using XRootD status.

Tools
Ruff

294-294: Missing type annotation for self in method

(ANN101)


297-297: Missing type annotation for self in method

(ANN101)


297-297: Missing type annotation for function argument query

(ANN001)


313-330: Modification time and size retrieval methods are correct.

The mtime and size methods are well-implemented and handle status checks appropriately.

Tools
Ruff

314-314: Missing type annotation for self in method

(ANN101)


324-324: Missing type annotation for self in method

(ANN101)


333-353: Retrieve object method is correctly implemented.

The retrieve_object method effectively uses client.CopyProcess to download files and handles status checks.

Tools
Ruff

334-334: Missing return type annotation for public function retrieve_object

Add return type annotation: None

(ANN201)


334-334: Missing type annotation for self in method

(ANN101)


368-384: Store object method is correctly implemented.

The store_object method effectively uses client.CopyProcess to upload files and handles status checks.

Tools
Ruff

369-369: Missing return type annotation for public function store_object

Add return type annotation: None

(ANN201)


369-369: Missing type annotation for self in method

(ANN101)


379-379: Trailing comma missing

Add trailing comma

(COM812)


386-396: Remove method is correctly implemented.

The remove method effectively deletes files or directories and handles status checks.

Tools
Ruff

387-387: Missing return type annotation for public function remove

Add return type annotation: None

(ANN201)


387-387: Missing type annotation for self in method

(ANN101)


Line range hint 401-409: Placeholder for listing candidate matches is appropriate.

The list_candidate_matches method is correctly marked as not implemented, with a TODO comment indicating future support.

Tools
Ruff

276-276: Missing type annotation for self in method

(ANN101)


281-281: Missing type annotation for self in method

(ANN101)


287-287: Missing return type annotation for public function cleanup

Add return type annotation: None

(ANN201)


287-287: Missing type annotation for self in method

(ANN101)


291-291: Unnecessary pass statement

Remove unnecessary pass

(PIE790)


294-294: Missing type annotation for self in method

(ANN101)


297-297: Missing type annotation for self in method

(ANN101)


297-297: Missing type annotation for function argument query

(ANN001)


314-314: Missing type annotation for self in method

(ANN101)


324-324: Missing type annotation for self in method

(ANN101)


334-334: Missing return type annotation for public function retrieve_object

Add return type annotation: None

(ANN201)


334-334: Missing type annotation for self in method

(ANN101)


359-359: Missing return type annotation for private function _makedirs

Add return type annotation: None

(ANN202)


359-359: Missing type annotation for self in method

(ANN101)


369-369: Missing return type annotation for public function store_object

Add return type annotation: None

(ANN201)


369-369: Missing type annotation for self in method

(ANN101)


379-379: Trailing comma missing

Add trailing comma

(COM812)


387-387: Missing return type annotation for public function remove

Add return type annotation: None

(ANN201)


387-387: Missing type annotation for self in method

(ANN101)


403-403: Missing type annotation for self in method

(ANN101)

snakemake_storage_plugin_xrootd/__init__.py Outdated Show resolved Hide resolved
snakemake_storage_plugin_xrootd/__init__.py Show resolved Hide resolved
snakemake_storage_plugin_xrootd/__init__.py Outdated Show resolved Hide resolved
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
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

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 9932e11 and 2fbd91d.

Files selected for processing (1)
  • docs/intro.md (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • docs/intro.md

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

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 2fbd91d and 0c55905.

Files selected for processing (1)
  • snakemake_storage_plugin_xrootd/init.py (5 hunks)
Additional context used
Path-based instructions (1)
snakemake_storage_plugin_xrootd/__init__.py (1)

Pattern **/*.py: Do not try to improve formatting.
Do not suggest type annotations for functions that are defined inside of functions or methods.
Do not suggest type annotation of the self argument of methods.
Do not suggest type annotation of the cls argument of classmethods.
Do not suggest return type annotation if a function or method does not contain a return statement.

Learnings (1)
snakemake_storage_plugin_xrootd/__init__.py (2)
Learnt from: johanneskoester
PR: snakemake/snakemake-storage-plugin-xrootd#8
File: snakemake_storage_plugin_xrootd/__init__.py:358-367
Timestamp: 2024-08-20T11:08:05.501Z
Learning: Do not suggest return type annotations for functions or methods that do not contain a `return` statement.
Learnt from: johanneskoester
PR: snakemake/snakemake-storage-plugin-xrootd#8
File: snakemake_storage_plugin_xrootd/__init__.py:117-121
Timestamp: 2024-08-20T11:07:48.841Z
Learning: Do not suggest return type annotations for functions or methods that do not contain a `return` statement.
Additional comments not posted (21)
snakemake_storage_plugin_xrootd/__init__.py (21)

31-34: Custom exception class for XRootD errors looks good.

The XRootDFatalException class is well-defined and serves its purpose in preventing retries for certain XRootD errors.


37-40: Error handling function is correctly implemented.

The _raise_fatal_error function properly raises XRootDFatalException and logs a warning.


43-46: Hardcoded retry settings are acceptable for now.

The retry settings are hardcoded, and a TODO comment suggests making them configurable in the future. This is acceptable given the current requirements.


83-87: Enhanced URL management with url_decorator.

The addition of the url_decorator field in StorageProviderSettings enhances flexibility in URL management, while the removal of query_params simplifies configuration.


119-123: Error handling in _check_status is well-implemented.

The _check_status method correctly raises XRootDFatalException for non-retryable errors and WorkflowError for others.


126-140: Example queries are clear and informative.

The example_queries method provides useful examples of valid queries for the XRootD storage provider.


143-151: Rate limiter key is correctly implemented.

The rate_limiter_key method returns a constant key for rate limiting, which is appropriate for XRootD.


162-167: Password obfuscation in URLs is well-handled.

The _no_pass_url method effectively removes passwords from URLs for safe printing.


169-174: Parameter obfuscation in URLs is well-handled.

The _no_params_url method effectively removes parameters from URLs for safe printing.


176-178: Comprehensive URL obfuscation is well-implemented.

The _safe_to_print_url method combines password and parameter obfuscation for safe URL printing.


180-228: URL parsing and construction are well-implemented.

The _parse_url method effectively handles user and password combinations using Python's match statement, ensuring valid URL construction.


245-248: Query postprocessing with URL decorator is effective.

The postprocess_query method correctly applies the URL decorator to enhance query functionality.


262-265: Initialization in __post_init__ is well-implemented.

The __post_init__ method correctly initializes URL parsing and file system setup for StorageObject.


298-300: File existence check with retry mechanism is effective.

The exists method correctly checks for file existence using the _exists helper and the retry mechanism.


302-315: Detailed file existence check is well-implemented.

The _exists method correctly handles file existence checks and specific error codes, ensuring robust error handling.


318-325: Modification time retrieval is well-implemented.

The mtime method correctly retrieves the modification time of a file and handles errors appropriately.


328-335: File size retrieval is well-implemented.

The size method correctly retrieves the size of a file and handles errors appropriately.


338-358: File retrieval is well-implemented.

The retrieve_object method correctly handles file downloads to a local path and includes robust error checking.


364-371: Directory creation is well-implemented.

The _makedirs method correctly ensures necessary directories are created before file operations.


373-389: File storage is well-implemented.

The store_object method correctly handles file uploads to a remote location and includes robust error checking.


391-401: File removal is well-implemented.

The remove method correctly handles file deletions from storage and includes robust error checking.

@MattMonk
Copy link
Collaborator Author

One more thing I've realised is that if a password is supplied this will of course end up in the root url like root://my_username@my_password:eosuser.cern.ch//eos/some_file which is then printed in the snakemake output in plaintext...

I guess then if we want to keep this option some change would have to be made so that when snakemake prints out the input/output files when it runs the rule to use the censored version instead.

I'm not sure how much work that would be, possibly for now we could drop support for using a password with this plugin and add it back later or possibly not at all if it's a bit too much of a risk having something that puts your password in plaintext in the URL it uses to access the file? I think using the password field in the URL is not the usual way of authenticating remote files with it anyway

@johanneskoester
Copy link
Contributor

Yes, good point. On the other hand, this will mostly be used in trusted environments. My suggestion is to keep that functionality, but issue a warning with logger.warning() and also put a warning into the help text of the password setting.

@MattMonk
Copy link
Collaborator Author

Okay yeah that makes sense! I'll do that and then I think otherwise this is ready to go from my side

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

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 0c55905 and 5982755.

Files selected for processing (2)
  • docs/intro.md (1 hunks)
  • snakemake_storage_plugin_xrootd/init.py (5 hunks)
Files skipped from review due to trivial changes (1)
  • docs/intro.md
Additional context used
Path-based instructions (1)
snakemake_storage_plugin_xrootd/__init__.py (1)

Pattern **/*.py: Do not try to improve formatting.
Do not suggest type annotations for functions that are defined inside of functions or methods.
Do not suggest type annotation of the self argument of methods.
Do not suggest type annotation of the cls argument of classmethods.
Do not suggest return type annotation if a function or method does not contain a return statement.

Learnings (1)
snakemake_storage_plugin_xrootd/__init__.py (2)
Learnt from: johanneskoester
PR: snakemake/snakemake-storage-plugin-xrootd#8
File: snakemake_storage_plugin_xrootd/__init__.py:358-367
Timestamp: 2024-08-20T11:08:05.501Z
Learning: Do not suggest return type annotations for functions or methods that do not contain a `return` statement.
Learnt from: johanneskoester
PR: snakemake/snakemake-storage-plugin-xrootd#8
File: snakemake_storage_plugin_xrootd/__init__.py:117-121
Timestamp: 2024-08-20T11:07:48.841Z
Learning: Do not suggest return type annotations for functions or methods that do not contain a `return` statement.
Additional comments not posted (14)
snakemake_storage_plugin_xrootd/__init__.py (14)

2-3: Imports are appropriate for type hinting.

The imported modules from typing are suitable for the type annotations used in the code.


31-34: Custom exception XRootDFatalException is well-defined.

This class is a clear and specific way to handle unrecoverable errors in the XRootD context.


37-40: Function _raise_fatal_error is well-implemented.

The function effectively handles fatal exceptions with appropriate logging.


43-46: Retry configuration is clear and appropriate.

The retry settings are well-defined, and the use of _raise_fatal_error as a callback is suitable for handling fatal errors. The decision not to make it configurable is acknowledged.


86-90: url_decorator field adds flexibility for URL manipulation.

This field allows for customizable URL modifications, enhancing the provider's flexibility.


98-127: Initialization and no-retry codes are well-defined.

The __post_init__ method thoroughly initializes settings, and the no-retry error codes are clearly specified.


129-133: _check_status method effectively handles error checking.

The method distinguishes between fatal and retryable errors, using WorkflowError for user-exposed issues.


140-150: example_queries method provides clear examples.

The examples and descriptions are helpful for users constructing queries for the XRootD storage provider.


172-188: URL helper methods enhance security and robustness.

The methods effectively remove sensitive information from URLs, improving security.


190-238: _parse_url method is well-implemented with match statement.

The method simplifies URL construction and validation, effectively handling user and password combinations.


255-258: postprocess_query method effectively applies global settings.

The method ensures consistent URL handling by integrating _parse_url logic.


272-275: __post_init__ method in StorageObject is well-defined.

The method ensures correct configuration with parsed URL and file system setup.


308-411: File operation methods in StorageObject are robust and resilient.

The methods effectively use xrootd_retry and _check_status for error handling and resilience against transient errors.


373-382: _makedirs method is correctly implemented for directory creation.

The method ensures necessary directories are created, using retry and error handling mechanisms.

@johanneskoester johanneskoester merged commit b7981cc into snakemake:main Aug 20, 2024
5 checks passed
johanneskoester pushed a commit that referenced this pull request Aug 20, 2024
🤖 I have created a release *beep* *boop*
---


##
[0.1.3](v0.1.2...v0.1.3)
(2024-08-20)


### Bug Fixes

* Fix XRootD storage plugin at least for file access
([#8](#8))
([b7981cc](b7981cc))
* update dependencies
([#9](#9))
([417e73d](417e73d))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
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