Skip to content

chore: add hf retries to files - #322

Merged
mckornfield merged 4 commits into
mainfrom
hf-retry-attempts/mck
Jul 1, 2026
Merged

mckornfield merged 4 commits into
mainfrom
hf-retry-attempts/mck

Conversation

@mckornfield

@mckornfield mckornfield commented Jun 12, 2026 •

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features

    • Added configurable retry settings for HuggingFace operations: hf_retry_attempts, hf_retry_initial_delay_seconds, and hf_retry_max_delay_seconds.
  • Improvements

    • Enhanced resilience for HuggingFace file operations with centralized error handling and automatic retry logic for transient failures.
  • Documentation

    • Updated configuration reference with new HuggingFace retry settings.

@mckornfield
mckornfield requested review from a team as code owners June 12, 2026 21:47
@github-actions github-actions Bot added the chore label Jun 12, 2026
@coderabbitai

coderabbitai Bot commented Jun 12, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds three FilesConfig fields (hf_retry_attempts, hf_retry_initial_delay_seconds, hf_retry_max_delay_seconds) and implements centralized HuggingFace Hub error mapping and retry via _map_hf_http_error(), _sleep_before_retry(), and _run_hf_request(). All backend methods (resolve_config, list_files, get_file, validate_storage, download) are refactored to use these shared utilities.

Changes

HuggingFace Transient Retry Handling

Layer / File(s) Summary
Retry configuration schema, docs, and CI
services/core/files/src/nmp/core/files/config.py, services/core/files/tests/test_files_config.py, docs/set-up/config-reference.mdx, .github/workflows/ci.yaml
FilesConfig gains hf_retry_attempts (≥1) and two non-negative delay fields. Config reference documents them. CI sets these as env vars in both integration and e2e test jobs. Tests assert defaults, env-var overrides, YAML loading, and ValidationError on invalid inputs.
Centralized error mapping and _run_hf_request
services/core/files/src/nmp/core/files/app/backends/huggingface.py
Imports updated. Adds _map_hf_http_error(), _retry_after_seconds() (numeric/HTTP-date), _sleep_before_retry(), and _run_hf_request(). The runner executes blocking Hub calls in a thread, retrying up to hf_retry_attempts for HuggingfaceUnavailableError with Retry-After/exponential backoff; non-transient errors are mapped and raised immediately.
Backend methods migrated to _run_hf_request
services/core/files/src/nmp/core/files/app/backends/huggingface.py
resolve_config, _get_hf_file_metadata, list_files, get_file, and validate_storage each have their direct threaded Hub calls replaced with _run_hf_request(), removing all local HfHubHTTPError mapping branches.
download streaming retry loop
services/core/files/src/nmp/core/files/app/backends/huggingface.py
download rewritten with an attempt loop over download_url_streaming: retries only HuggingfaceUnavailableError from aiohttp before any chunk is yielded; applies _sleep_before_retry() between attempts; propagates non-retryable errors immediately.
Backend retry test helpers and cases
services/core/files/tests/test_huggingface_backend.py
Adds AsyncMock, _clear_files_config_cache(), and _hf_http_error(). New/updated tests: list_files network error retry, download exhausted-attempts path, get_file 429 with env-var override asserting specific backoff delays, and resolve_config 429-then-succeed with Retry-After: 0.

Possibly Related PRs

  • NVIDIA-NeMo/nemo-platform#259: Adds test fixtures that patch validate_storage, resolve_config, and HfApi.repo_info—the same methods this PR refactors to use _run_hf_request().
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 79.41% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding HuggingFace retry logic to the files service. It's concise, specific, and directly reflects the substantial refactoring across config, backend implementation, and tests.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch hf-retry-attempts/mck

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
services/core/files/src/nmp/core/files/app/backends/huggingface.py (1)

178-192: 📐 Maintainability & Code Quality | 💤 Low value

Line 192 is unreachable.

The loop always either returns on line 181, raises on line 183, or raises on line 190. This raise can never execute. Harmless defensive code, but could be removed or replaced with an assertion to clarify intent.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@services/core/files/src/nmp/core/files/app/backends/huggingface.py` around
lines 178 - 192, The final raise in _run_hf_request is unreachable because the
loop always returns or raises; remove the trailing "raise
HuggingfaceBackendError(...)" and replace it with an explicit assertion to
document intent (e.g., assert False or raise AssertionError("unreachable in
_run_hf_request")). Update surrounding references to
_HF_TRANSIENT_RETRY_ATTEMPTS, EntryNotFoundError, HfHubHTTPError,
_map_hf_http_error, HuggingfaceUnavailableError, and _sleep_before_retry as
needed to ensure control flow is still clear.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@services/core/files/src/nmp/core/files/app/backends/huggingface.py`:
- Around line 178-192: The final raise in _run_hf_request is unreachable because
the loop always returns or raises; remove the trailing "raise
HuggingfaceBackendError(...)" and replace it with an explicit assertion to
document intent (e.g., assert False or raise AssertionError("unreachable in
_run_hf_request")). Update surrounding references to
_HF_TRANSIENT_RETRY_ATTEMPTS, EntryNotFoundError, HfHubHTTPError,
_map_hf_http_error, HuggingfaceUnavailableError, and _sleep_before_retry as
needed to ensure control flow is still clear.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 78b3df66-4bfd-4a24-ba49-ef418aa09363

📥 Commits

Reviewing files that changed from the base of the PR and between fc132aa and b2e345e.

📒 Files selected for processing (2)
  • services/core/files/src/nmp/core/files/app/backends/huggingface.py
  • services/core/files/tests/test_huggingface_backend.py

@github-actions

github-actions Bot commented Jun 12, 2026 •

Copy link
Copy Markdown
Contributor
Suite Lines Covered Line Rate Branch Rate
Unit Tests 22208/29406 75.5% 60.3%
Integration Tests 12804/28086 45.6% 19.1%

@mckornfield
mckornfield requested a review from a team as a code owner June 15, 2026 17:48
Comment thread services/core/files/src/nmp/core/files/app/backends/huggingface.py Outdated
@mckornfield
mckornfield force-pushed the hf-retry-attempts/mck branch from d919c31 to 488ae5b Compare June 16, 2026 13:52
@github-actions

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@openapi/ga/individual/platform.openapi.yaml`:
- Around line 53-58: The entrypoint field is currently defined as a free-form
string type with only examples provided, which does not enforce the valid values
and weakens client generation and validation. Replace the type declaration for
the entrypoint field with an enum constraint that explicitly lists the three
allowed values: allow, has_permissions, and has_role. This ensures the schema
enforces the contract at the definition level rather than relying only on
documentation examples.

In `@openapi/ga/openapi.yaml`:
- Around line 49-59: The entrypoint parameter in the OpenAPI schema currently
accepts any string value, but the documentation and examples show only three
valid values: allow, has_permissions, and has_role. Add an enum constraint to
the schema field of the entrypoint parameter to restrict it to these three
documented values, ensuring that generated clients will properly validate the
input according to the API contract.

In `@openapi/openapi.yaml`:
- Around line 52-58: The `entrypoint` parameter is currently defined as a string
type with examples, but examples in OpenAPI do not constrain valid values -
generated clients will still permit any string. Replace the `examples` field in
the entrypoint schema with an `enum` field containing the allowed values (allow,
has_permissions, has_role) to properly enforce the contract that only these
specific values are valid.
- Around line 67-87: The OpenAPI documentation for the authz endpoint is missing
documented responses for 401 (Unauthorized) and 403 (Forbidden) status codes
that the middleware returns for non-service principals, and it does not account
for the fact that FastAPI HTTPException wraps error response bodies under a
`detail` field. Update the responses block in the authz endpoint to include 401
and 403 response definitions, and modify the schemas for the 400 and 500
responses to reflect that their bodies are wrapped in the `detail` envelope as
produced by the actual FastAPI exception handling behavior observed in the
middleware and endpoint implementations.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 775814b6-c871-4eff-9ae6-fff68d0ab4d0

📥 Commits

Reviewing files that changed from the base of the PR and between 1003019 and 488ae5b.

⛔ Files ignored due to path filters (1)
  • sdk/stainless.yaml is excluded by !sdk/**
📒 Files selected for processing (10)
  • .github/workflows/ci.yaml
  • docs/set-up/config-reference.mdx
  • openapi/ga/individual/platform.openapi.yaml
  • openapi/ga/openapi.yaml
  • openapi/openapi.yaml
  • services/core/auth/src/nmp/core/auth/assets/static-authz.yaml
  • services/core/files/src/nmp/core/files/app/backends/huggingface.py
  • services/core/files/src/nmp/core/files/config.py
  • services/core/files/tests/test_files_config.py
  • services/core/files/tests/test_huggingface_backend.py
💤 Files with no reviewable changes (5)
  • services/core/auth/src/nmp/core/auth/assets/static-authz.yaml
  • services/core/files/src/nmp/core/files/config.py
  • services/core/files/tests/test_files_config.py
  • services/core/files/tests/test_huggingface_backend.py
  • services/core/files/src/nmp/core/files/app/backends/huggingface.py

Comment thread openapi/ga/individual/platform.openapi.yaml Outdated
Comment thread openapi/ga/openapi.yaml Outdated
Comment thread openapi/openapi.yaml Outdated
Comment thread openapi/openapi.yaml Outdated
@mckornfield
mckornfield force-pushed the hf-retry-attempts/mck branch from 488ae5b to fbac457 Compare June 16, 2026 19:57

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@services/core/auth/src/nmp/core/auth/assets/static-authz.yaml`:
- Line 324: The permission key `auth.authz.create` is being granted in the
`Editor` role but is not declared in the `authz.permissions` registry section of
the YAML file. Add a declaration for the `auth.authz.create` permission in the
`authz.permissions` section to ensure consistency with the policy's registry
contract and prevent evaluation-time issues. The new permission entry should
follow the same format and structure as existing permission declarations in that
section.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: e045c8f7-a131-4ecd-b839-e09670bbcb9a

📥 Commits

Reviewing files that changed from the base of the PR and between 488ae5b and fbac457.

⛔ Files ignored due to path filters (12)
  • sdk/python/nemo-platform/.nmpcontext/stainless.yaml is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/resources/files/api.md is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/resources/files/filesets.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/types/__init__.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/types/files/__init__.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/types/files/fileset.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/types/files/fileset_create_params.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/types/files/fileset_metadata_param.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/types/shared/__init__.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/types/shared/fileset_metadata.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/types/shared_params/fileset_metadata_param.py is excluded by !sdk/**
  • sdk/stainless.yaml is excluded by !sdk/**
📒 Files selected for processing (7)
  • .github/workflows/ci.yaml
  • docs/set-up/config-reference.mdx
  • services/core/auth/src/nmp/core/auth/assets/static-authz.yaml
  • services/core/files/src/nmp/core/files/app/backends/huggingface.py
  • services/core/files/src/nmp/core/files/config.py
  • services/core/files/tests/test_files_config.py
  • services/core/files/tests/test_huggingface_backend.py
🚧 Files skipped from review as they are similar to previous changes (4)
  • docs/set-up/config-reference.mdx
  • services/core/files/tests/test_files_config.py
  • .github/workflows/ci.yaml
  • services/core/files/tests/test_huggingface_backend.py

Comment thread services/core/auth/src/nmp/core/auth/assets/static-authz.yaml Outdated
@mckornfield
mckornfield force-pushed the hf-retry-attempts/mck branch 3 times, most recently from 64982a7 to 7be2172 Compare June 26, 2026 21:53
Signed-off-by: Matt Kornfield <mkornfield@nvidia.com>
Signed-off-by: Matt Kornfield <mkornfield@nvidia.com>
@mckornfield
mckornfield force-pushed the hf-retry-attempts/mck branch from 7be2172 to 28a5be6 Compare June 29, 2026 21:18
Comment thread sdk/stainless.yaml Outdated
Comment thread services/core/files/src/nmp/core/files/app/backends/huggingface.py
Comment thread services/core/files/src/nmp/core/files/app/backends/huggingface.py Outdated
Comment thread services/core/files/src/nmp/core/files/app/backends/huggingface.py Outdated
Comment thread services/core/files/src/nmp/core/files/app/backends/huggingface.py Outdated

@matthewgrossman matthewgrossman left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

couple comments you could throw at the agent and see what it spits out ¯_(ツ)_/¯

Signed-off-by: Matt Kornfield <mkornfield@nvidia.com>
@svvarom
svvarom self-requested a review June 30, 2026 20:40
Comment thread services/core/files/src/nmp/core/files/app/backends/huggingface.py Outdated
Signed-off-by: Matt Kornfield <mkornfield@nvidia.com>
@mckornfield
mckornfield enabled auto-merge July 1, 2026 16:43
@mckornfield
mckornfield added this pull request to the merge queue Jul 1, 2026
Merged via the queue into main with commit 773c426 Jul 1, 2026
54 checks passed
@mckornfield
mckornfield deleted the hf-retry-attempts/mck branch July 1, 2026 17:06
arpitsardhana pushed a commit that referenced this pull request Jul 9, 2026
* chore: add hf retries to files

Signed-off-by: Matt Kornfield <mkornfield@nvidia.com>

* chore: flaky test patch

Signed-off-by: Matt Kornfield <mkornfield@nvidia.com>

* chore: improve flow of huggingface retries

Signed-off-by: Matt Kornfield <mkornfield@nvidia.com>

* chore: attempt to use retry headers

Signed-off-by: Matt Kornfield <mkornfield@nvidia.com>

---------

Signed-off-by: Matt Kornfield <mkornfield@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants