Skip to content

Conversation

@getter111
Copy link

@getter111 getter111 commented Nov 20, 2025

Description

This PR adds video upload functionality to NAT, enabling multimodal workflows that require video processing. It integrates with NAT's existing object store infrastructure and includes a companion UI in the nat-ui submodule.

Key Changes

Backend:

  • Object Store Interface: Added list_objects() method to ObjectStore base class with implementation in S3ObjectStore (supports AWS S3 and MinIO). Returns metadata-only listings with optional prefix filtering and pagination
  • FastAPI Video Routes: New endpoints (POST /videos, GET /videos, DELETE /videos/{video_key}) for video upload, listing, and deletion with UUID-based naming (videos/{uuid}/{filename})
  • Testing: Added 20+ integration tests in test_video_upload_routes.py covering upload/list/delete operations with MinIO fixture
  • Documentation: Updated object-store.md with video upload examples and configuration patterns

Frontend:

  • Updated nat-ui submodule with video library components (see related PR below)
NAT.UI.Demo.mp4

Related PRs

This PR depends on NVIDIA/NeMo-Agent-Toolkit-UI#62

Closes

By Submitting this PR I confirm:

  • I am familiar with the Contributing Guidelines.
  • We require that all contributors "sign-off" on their commits. This certifies that the contribution is your original work, or you have rights to submit it under the same license, or a compatible license.
    • Any contribution which contains commits that are not Signed-Off will not be accepted.
  • When the PR is ready for review, new or existing tests cover these changes.
  • When the PR is ready for review, the documentation is up to date with these changes.

Summary by CodeRabbit

Release Notes

  • New Features

    • Object listing with optional prefix-based filtering and metadata retrieval without downloading full content
    • Video upload API with endpoints for uploading, listing, and managing videos
  • Documentation

    • Updated with examples of object listing and video management workflows
  • Tests

    • Added comprehensive tests for object listing and video upload functionality

✏️ Tip: You can customize this high-level summary in your review settings.

getter111 and others added 2 commits November 20, 2025 00:49
Backend:
- ObjectStoreListItem model (metadata only, no data)
- S3ObjectStore with pagination and path-style addressing
- InMemoryObjectStore for testing
- FastAPI video routes using videos/ prefix organization
- MinIO test fixture and 20 tests
- Updated documentation with examples

Frontend (nat-ui submodule):
- VideoLibrary, VideoUpload, VideoLibraryModal components
- videoUpload API client proxying through backend
- Settings integration and route constants

Signed-off-by: Alex Lin <[email protected]>
@getter111 getter111 requested a review from a team as a code owner November 20, 2025 03:44
@copy-pr-bot
Copy link

copy-pr-bot bot commented Nov 20, 2025

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@coderabbitai
Copy link

coderabbitai bot commented Nov 20, 2025

Walkthrough

The changes introduce a new list_objects() method to the ObjectStore interface for memory-efficient, prefix-filtered metadata retrieval returning ObjectStoreListItem objects (excluding data content). Implementations are added to in-memory and S3-based stores. Video upload endpoints (POST/GET/DELETE) are added to FastAPI for video management. Supporting tests, test infrastructure for MinIO integration, and documentation are included.

Changes

Cohort / File(s) Summary
Object Store Model & Interface
src/nat/object_store/models.py, src/nat/object_store/interfaces.py
New ObjectStoreListItem(BaseModel) with fields: key, size, content_type, metadata, last_modified (no data payload). New abstract method list_objects(prefix: str | None = None) -> list[ObjectStoreListItem] added to ObjectStore interface.
Object Store Implementations
src/nat/object_store/in_memory_object_store.py, packages/nvidia_nat_s3/src/nat/plugins/s3/s3_object_store.py
Implemented list_objects() for in-memory store (filters by prefix, skips directory keys, returns metadata). S3 implementation uses paginator with prefix filtering, fetches per-object metadata via head_object, handles ClientError, supports path-style addressing for non-AWS endpoints.
FastAPI Video Upload Routes
src/nat/front_ends/fastapi/fastapi_front_end_plugin_worker.py
Added add_video_upload_route() method with POST (upload with metadata), GET (list by prefix), DELETE (idempotent) endpoints under /videos. Handles UUID-based path generation, filename sanitization, content-type validation, conflict resolution (409), and metadata propagation.
Test Infrastructure
packages/nvidia_nat_s3/tests/conftest.py
Session-scoped minio_server() fixture with port detection (is_port_open() helper) for MinIO integration tests; provides bucket and connection credentials.
Object Store Tests
packages/nvidia_nat_test/src/nat/test/object_store_tests.py
New test_list_objects() method covering various prefixes, empty results, metadata validation (keys, content_type, size), and cleanup.
Video Upload Route Tests
tests/nat/front_ends/fastapi/test_video_upload_routes.py
Integration tests for video endpoints: upload validation, content-type filtering, list enumeration, idempotent deletion, and end-to-end workflows using in-memory store.
Documentation
docs/source/store-and-retrieve/object-store.md
Added ObjectStoreListItem description, list_objects() usage examples with prefix filtering, File Server and Video Upload Integration sections with HTTP endpoints, expanded Error Handling (NoSuchKeyError).
External Submodule
external/nat-ui
Submodule reference updated from commit 8b91a7e... to 04efa5b...; no API or behavior changes.

Sequence Diagrams

sequenceDiagram
    participant Client
    participant FastAPI
    participant ObjectStore
    participant S3

    rect rgb(200, 220, 255)
    Note over Client,S3: list_objects() Flow
    Client->>FastAPI: GET /videos?prefix=videos/
    FastAPI->>ObjectStore: list_objects(prefix="videos/")
    ObjectStore->>S3: list_objects_v2(Prefix="videos/")
    S3-->>ObjectStore: [object_keys]
    loop Per object
        ObjectStore->>S3: head_object(key)
        S3-->>ObjectStore: {size, content_type, metadata, last_modified}
    end
    ObjectStore-->>FastAPI: [ObjectStoreListItem, ...]
    FastAPI-->>Client: [{key, size, content_type, ...}, ...]
    end

    rect rgb(220, 255, 220)
    Note over Client,S3: Video Upload Flow
    Client->>FastAPI: POST /videos (file + metadata)
    FastAPI->>FastAPI: Validate content_type
    FastAPI->>FastAPI: Sanitize filename, generate UUID
    FastAPI->>ObjectStore: put_object(key="videos/{uuid}/{filename}", data, metadata)
    ObjectStore->>S3: put_object(key, data, metadata)
    S3-->>ObjectStore: Success
    ObjectStore-->>FastAPI: Success
    FastAPI-->>Client: {video_key, filename, content_type, size, uuid}
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • S3 implementation: Paginator logic with per-object metadata fetching via head_object; error handling and path-style addressing configuration require careful validation.
  • FastAPI video endpoints: Filename sanitization, UUID path generation, content-type validation, and metadata propagation need verification for security (path traversal) and correctness.
  • Test fixtures: MinIO integration setup with port detection; verify fixture skips gracefully when service unavailable.
  • Consistency across stores: Verify all ObjectStore implementations (in-memory, S3) return consistent ObjectStoreListItem structure and handle prefix filtering identically.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 63.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately captures both main features added in this PR: video upload functionality and the list_objects method for ObjectStore, uses imperative mood, and is concise at 68 characters.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

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

Copy link

@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 (3)
packages/nvidia_nat_s3/tests/conftest.py (1)

31-55: LGTM! The MinIO fixture is well-designed.

The minio_server fixture provides good developer experience:

  • Automatically skips tests when MinIO isn't running
  • Comprehensive docstring with docker commands for setup
  • Session scope is appropriate for this shared resource
  • Clear skip message guides developers to start MinIO

Consider adding a return type hint to improve type safety:

 @pytest.fixture(scope="session")
-def minio_server():
+def minio_server() -> dict[str, str]:

This is a minor enhancement and fully optional.

src/nat/front_ends/fastapi/fastapi_front_end_plugin_worker.py (1)

751-778: Simplify redundant exception handling.

The delete operation correctly implements:

  • Security validation (key must start with videos/)
  • Idempotent behavior (deleting non-existent videos returns success)
  • Proper error handling with appropriate status codes

However, there's redundant exception handling with two consecutive except NoSuchKeyError blocks (lines 760-762 and 765-767) that perform the same action.

Simplify by removing the redundant catch block:

         try:
             try:
                 await object_store_client.delete_object(video_key)
             except NoSuchKeyError:
                 logger.info(f"Video {video_key} not found during delete - treating as success (idempotent)")
-                return {"message": "Video deleted successfully (was already deleted)", "video_key": video_key}
+            return {"message": "Video deleted successfully", "video_key": video_key}
-            return {"message": "Video deleted successfully", "video_key": video_key}
-        except NoSuchKeyError as e:
-            logger.info(f"Video {video_key} not found: {e}")
-            return {"message": "Video deleted successfully (was already deleted)", "video_key": video_key}
         except HTTPException:
             raise
         except Exception as e:

This maintains the same idempotent behavior with clearer logic flow.

docs/source/store-and-retrieve/object-store.md (1)

253-253: Consider adding example output to console command blocks. Markdownlint (MD014) flags lines 253, 257, and 261 as showing commands without output. For consistency with documentation conventions and to match similar patterns, consider either: (1) adding example response output below each command, or (2) removing the $ prompt to format as plain code blocks. Note: Similar curl examples at lines 210, 214, 218, 222 use the same format, so this may be a false positive or style inconsistency that could be addressed project-wide.

Also applies to: 257-257, 261-261

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b00007e and 90f666c.

📒 Files selected for processing (10)
  • docs/source/store-and-retrieve/object-store.md (4 hunks)
  • external/nat-ui (1 hunks)
  • packages/nvidia_nat_s3/src/nat/plugins/s3/s3_object_store.py (3 hunks)
  • packages/nvidia_nat_s3/tests/conftest.py (1 hunks)
  • packages/nvidia_nat_test/src/nat/test/object_store_tests.py (2 hunks)
  • src/nat/front_ends/fastapi/fastapi_front_end_plugin_worker.py (4 hunks)
  • src/nat/object_store/in_memory_object_store.py (2 hunks)
  • src/nat/object_store/interfaces.py (2 hunks)
  • src/nat/object_store/models.py (2 hunks)
  • tests/nat/front_ends/fastapi/test_video_upload_routes.py (1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**/*

⚙️ CodeRabbit configuration file

**/*: # Code Review Instructions

  • Ensure the code follows best practices and coding standards. - For Python code, follow
    PEP 20 and
    PEP 8 for style guidelines.
  • Check for security vulnerabilities and potential issues. - Python methods should use type hints for all parameters and return values.
    Example:
    def my_function(param1: int, param2: str) -> bool:
        pass
  • For Python exception handling, ensure proper stack trace preservation:
    • When re-raising exceptions: use bare raise statements to maintain the original stack trace,
      and use logger.error() (not logger.exception()) to avoid duplicate stack trace output.
    • When catching and logging exceptions without re-raising: always use logger.exception()
      to capture the full stack trace information.

Documentation Review Instructions - Verify that documentation and comments are clear and comprehensive. - Verify that the documentation doesn't contain any TODOs, FIXMEs or placeholder text like "lorem ipsum". - Verify that the documentation doesn't contain any offensive or outdated terms. - Verify that documentation and comments are free of spelling mistakes, ensure the documentation doesn't contain any

words listed in the ci/vale/styles/config/vocabularies/nat/reject.txt file, words that might appear to be
spelling mistakes but are listed in the ci/vale/styles/config/vocabularies/nat/accept.txt file are OK.

Misc. - All code (except .mdc files that contain Cursor rules) should be licensed under the Apache License 2.0,

and should contain an Apache License 2.0 header comment at the top of each file.

  • Confirm that copyright years are up-to date whenever a file is changed.

Files:

  • external/nat-ui
  • src/nat/object_store/models.py
  • docs/source/store-and-retrieve/object-store.md
  • tests/nat/front_ends/fastapi/test_video_upload_routes.py
  • packages/nvidia_nat_s3/tests/conftest.py
  • packages/nvidia_nat_s3/src/nat/plugins/s3/s3_object_store.py
  • packages/nvidia_nat_test/src/nat/test/object_store_tests.py
  • src/nat/object_store/interfaces.py
  • src/nat/object_store/in_memory_object_store.py
  • src/nat/front_ends/fastapi/fastapi_front_end_plugin_worker.py
src/nat/**/*

⚙️ CodeRabbit configuration file

This directory contains the core functionality of the toolkit. Changes should prioritize backward compatibility.

Files:

  • src/nat/object_store/models.py
  • src/nat/object_store/interfaces.py
  • src/nat/object_store/in_memory_object_store.py
  • src/nat/front_ends/fastapi/fastapi_front_end_plugin_worker.py
docs/source/**/*

⚙️ CodeRabbit configuration file

This directory contains the source code for the documentation. All documentation should be written in Markdown format. Any image files should be placed in the docs/source/_static directory.

Files:

  • docs/source/store-and-retrieve/object-store.md
tests/**/*.py

⚙️ CodeRabbit configuration file

tests/**/*.py: - Ensure that tests are comprehensive, cover edge cases, and validate the functionality of the code. - Test functions should be named using the test_ prefix, using snake_case. - Any frequently repeated code should be extracted into pytest fixtures. - Pytest fixtures should define the name argument when applying the pytest.fixture decorator. The fixture
function being decorated should be named using the fixture_ prefix, using snake_case. Example:
@pytest.fixture(name="my_fixture")
def fixture_my_fixture():
pass

Files:

  • tests/nat/front_ends/fastapi/test_video_upload_routes.py
packages/**/*

⚙️ CodeRabbit configuration file

packages/**/*: - This directory contains optional plugin packages for the toolkit, each should contain a pyproject.toml file. - The pyproject.toml file should declare a dependency on nvidia-nat or another package with a name starting
with nvidia-nat-. This dependency should be declared using ~=<version>, and the version should be a two
digit version (ex: ~=1.0).

  • Not all packages contain Python code, if they do they should also contain their own set of tests, in a
    tests/ directory at the same level as the pyproject.toml file.

Files:

  • packages/nvidia_nat_s3/tests/conftest.py
  • packages/nvidia_nat_s3/src/nat/plugins/s3/s3_object_store.py
  • packages/nvidia_nat_test/src/nat/test/object_store_tests.py
🧠 Learnings (2)
📚 Learning: 2025-11-14T20:33:53.944Z
Learnt from: AnuradhaKaruppiah
Repo: NVIDIA/NeMo-Agent-Toolkit PR: 1181
File: packages/nvidia_nat_test/tests/test_test_llm.py:419-484
Timestamp: 2025-11-14T20:33:53.944Z
Learning: The NVIDIA NeMo-Agent-Toolkit project uses pytest-asyncio in strict mode (the default), which requires pytest.mark.asyncio decorator on all async test functions. All async tests in packages/nvidia_nat_test/tests/test_test_llm.py consistently follow this pattern.

Applied to files:

  • packages/nvidia_nat_s3/tests/conftest.py
📚 Learning: 2025-08-23T02:55:39.346Z
Learnt from: willkill07
Repo: NVIDIA/NeMo-Agent-Toolkit PR: 649
File: src/nat/cli/commands/object_store/object_store.py:32-42
Timestamp: 2025-08-23T02:55:39.346Z
Learning: In the NAT object store plugin architecture, config classes like S3ObjectStoreClientConfig, MySQLObjectStoreClientConfig, and RedisObjectStoreClientConfig are defined in the object_store.py files (e.g., nat.plugins.s3.object_store), while the implementation classes are in separate files (e.g., nat.plugins.s3.s3_object_store). The registration functions are also in the object_store.py files.

Applied to files:

  • packages/nvidia_nat_s3/src/nat/plugins/s3/s3_object_store.py
  • packages/nvidia_nat_test/src/nat/test/object_store_tests.py
  • src/nat/object_store/in_memory_object_store.py
🧬 Code graph analysis (6)
tests/nat/front_ends/fastapi/test_video_upload_routes.py (3)
src/nat/object_store/in_memory_object_store.py (2)
  • in_memory_object_store (99-100)
  • InMemoryObjectStoreConfig (30-34)
packages/nvidia_nat_test/src/nat/test/functions.py (1)
  • EchoFunctionConfig (28-29)
packages/nvidia_nat_test/src/nat/test/utils.py (1)
  • build_nat_client (93-123)
packages/nvidia_nat_s3/src/nat/plugins/s3/s3_object_store.py (3)
src/nat/object_store/interfaces.py (2)
  • ObjectStore (23-99)
  • list_objects (88-99)
src/nat/object_store/models.py (1)
  • ObjectStoreListItem (43-65)
src/nat/object_store/in_memory_object_store.py (1)
  • list_objects (75-95)
packages/nvidia_nat_test/src/nat/test/object_store_tests.py (5)
examples/object_store/user_report/tests/test_objext_store_example_user_report_tool.py (1)
  • object_store (44-46)
src/nat/object_store/models.py (2)
  • ObjectStoreListItem (43-65)
  • ObjectStoreItem (23-40)
src/nat/object_store/interfaces.py (4)
  • ObjectStore (23-99)
  • put_object (32-44)
  • list_objects (88-99)
  • delete_object (75-85)
packages/nvidia_nat_s3/src/nat/plugins/s3/s3_object_store.py (3)
  • put_object (96-125)
  • list_objects (174-221)
  • delete_object (158-172)
src/nat/object_store/in_memory_object_store.py (3)
  • put_object (47-51)
  • list_objects (75-95)
  • delete_object (67-72)
src/nat/object_store/interfaces.py (3)
src/nat/object_store/models.py (1)
  • ObjectStoreListItem (43-65)
packages/nvidia_nat_s3/src/nat/plugins/s3/s3_object_store.py (1)
  • list_objects (174-221)
src/nat/object_store/in_memory_object_store.py (1)
  • list_objects (75-95)
src/nat/object_store/in_memory_object_store.py (3)
src/nat/object_store/models.py (1)
  • ObjectStoreListItem (43-65)
src/nat/utils/type_utils.py (1)
  • override (56-57)
packages/nvidia_nat_s3/src/nat/plugins/s3/s3_object_store.py (1)
  • list_objects (174-221)
src/nat/front_ends/fastapi/fastapi_front_end_plugin_worker.py (5)
src/nat/builder/workflow_builder.py (2)
  • get_object_store_client (887-891)
  • get_object_store_client (1418-1426)
packages/nvidia_nat_test/src/nat/test/tool_test_runner.py (1)
  • get_object_store_client (265-275)
packages/nvidia_nat_s3/src/nat/plugins/s3/s3_object_store.py (3)
  • put_object (96-125)
  • list_objects (174-221)
  • delete_object (158-172)
src/nat/object_store/in_memory_object_store.py (3)
  • put_object (47-51)
  • list_objects (75-95)
  • delete_object (67-72)
src/nat/object_store/models.py (1)
  • ObjectStoreItem (23-40)
🪛 markdownlint-cli2 (0.18.1)
docs/source/store-and-retrieve/object-store.md

253-253: Dollar signs used before commands without showing output

(MD014, commands-show-output)


257-257: Dollar signs used before commands without showing output

(MD014, commands-show-output)


261-261: Dollar signs used before commands without showing output

(MD014, commands-show-output)

🪛 Ruff (0.14.5)
packages/nvidia_nat_s3/src/nat/plugins/s3/s3_object_store.py

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

(TRY003)


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

(TRY003)


219-219: Use explicit conversion flag

Replace with conversion flag

(RUF010)

src/nat/front_ends/fastapi/fastapi_front_end_plugin_worker.py

677-677: Do not perform function call File in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)


702-702: Use explicit conversion flag

Replace with conversion flag

(RUF010)


741-741: Consider moving this statement to an else block

(TRY300)


744-744: Use explicit conversion flag

Replace with conversion flag

(RUF010)


764-764: Consider moving this statement to an else block

(TRY300)


772-772: Use explicit conversion flag

Replace with conversion flag

(RUF010)

🔇 Additional comments (26)
external/nat-ui (1)

1-1: Submodule configuration is valid, but code verification requires access to the external repository.

The external/nat-ui submodule is properly configured in .gitmodules and points to https://github.com/NVIDIA/NeMo-Agent-Toolkit-UI.git. The commit SHA 04efa5b129b962decf56238d3bde3f66e907d2ab is a valid 40-character hex reference. However, to verify the actual frontend code changes (VideoLibrary, VideoUpload, VideoLibraryModal components, and videoUpload.ts API client), you will need to inspect the commit in the external NVIDIA/NeMo-Agent-Toolkit-UI repository directly.

Confirm that the external repository commit contains the intended frontend implementation and that the changes integrate correctly with your video processing backend routes.

src/nat/object_store/models.py (2)

16-16: LGTM!

The datetime import is correctly placed and necessary for the new last_modified field in ObjectStoreListItem.


43-65: LGTM!

The ObjectStoreListItem model is well-structured with:

  • Comprehensive docstring following numpy-style format
  • Proper type hints for all fields
  • Consistent with the existing ObjectStoreItem pattern
  • Appropriate use of optional fields for metadata that may not always be available
tests/nat/front_ends/fastapi/test_video_upload_routes.py (3)

29-44: LGTM!

The test fixtures are well-structured:

  • object_store_name provides a configurable store identifier
  • client fixture properly configures an async test client with InMemoryObjectStore for isolated testing
  • Uses build_nat_client utility correctly
  • EchoFunctionConfig serves as an appropriate dummy workflow for these integration tests

47-121: LGTM!

The upload and list test methods provide excellent coverage:

  • Verifies all response fields (video_key, filename, content_type, size, uuid)
  • Tests rejection of non-video files with proper status codes
  • Validates listing functionality in both empty and populated states
  • Uses set comprehensions effectively to verify presence of uploaded videos

122-181: LGTM!

The delete and workflow tests are comprehensive:

  • Validates successful deletion and removal from listings
  • Tests idempotent behavior (deleting already-deleted videos returns 200)
  • Enforces security constraint that video keys must start with "videos/"
  • Full workflow test validates end-to-end integration across all operations
src/nat/object_store/in_memory_object_store.py (2)

27-27: LGTM!

The import of ObjectStoreListItem is correctly placed alongside the existing ObjectStoreItem import.


74-95: LGTM!

The list_objects implementation is correct:

  • Proper concurrency control with async with self._lock
  • Correct prefix filtering using startswith
  • Appropriately skips directory markers (keys ending with /)
  • Size calculation using len(item.data) is correct for in-memory bytes
  • Setting last_modified=None is appropriate since the in-memory store doesn't persist modification timestamps
src/nat/object_store/interfaces.py (2)

20-20: LGTM!

The import of ObjectStoreListItem is correctly placed with other model imports.


87-99: LGTM!

The abstract list_objects method is well-defined:

  • Properly decorated with @abstractmethod
  • Clear docstring explaining the purpose, parameters, and return value
  • Type hints present for all parameters and return type
  • Signature is consistent with implementations in both InMemoryObjectStore and S3ObjectStore
packages/nvidia_nat_s3/tests/conftest.py (1)

22-28: LGTM!

The is_port_open helper function is well-implemented:

  • Proper type hints for all parameters and return value
  • 1-second timeout is reasonable for local connections
  • Catches appropriate exceptions for port connectivity checks
packages/nvidia_nat_test/src/nat/test/object_store_tests.py (2)

27-27: LGTM!

The import of ObjectStoreListItem is correctly placed for use in the new test_list_objects method.


120-178: LGTM!

The test_list_objects method provides comprehensive coverage:

  • Uses UUID for test isolation to prevent conflicts between parallel test runs
  • Tests multiple prefix scenarios (exact match, partial match, non-existent)
  • Verifies all ObjectStoreListItem fields (key, size, content_type, metadata)
  • Includes proper cleanup to avoid test pollution
  • Instance type checking (isinstance(obj, ObjectStoreListItem)) ensures correct return types
packages/nvidia_nat_s3/src/nat/plugins/s3/s3_object_store.py (3)

20-20: LGTM!

The new imports are correctly placed:

  • Config from botocore.client enables path-style addressing configuration
  • ObjectStoreListItem is needed for the return type of list_objects

Also applies to: 27-27


60-63: LGTM!

The path-style addressing configuration is well-implemented:

  • Correctly detects non-AWS endpoints (MinIO, local S3-compatible services)
  • Case-insensitive check using .lower() is appropriate
  • Clear comment explaining the rationale (avoiding DNS-based virtual host lookups)
  • Essential for local S3-compatible storage systems like MinIO

174-221: LGTM! The S3 list_objects implementation is well-structured.

The implementation correctly handles:

  • Pagination using list_objects_v2 paginator for efficient handling of large buckets
  • Optional prefix filtering
  • Skipping directory markers (keys ending with /)
  • Fetching per-object metadata via head_object with graceful fallback on failure
  • Proper error logging with exc_info=True and exception chaining with from e

The error handling follows the coding guidelines correctly—using logger.error() (not logger.exception()) when raising a new exception type.

src/nat/front_ends/fastapi/fastapi_front_end_plugin_worker.py (4)

21-21: LGTM!

The new imports are appropriate:

  • uuid for generating unique video identifiers
  • File and Form from FastAPI for handling multipart form data in video uploads

Also applies to: 33-34


310-310: LGTM!

The call to add_video_upload_route is properly placed alongside other route registrations in the add_routes method.


677-710: LGTM! The upload_video function implements proper security measures.

The implementation correctly handles:

  • Content type validation (must start with video/)
  • Path traversal prevention using os.path.basename()
  • UUID-based naming to prevent collisions
  • Proper error handling with appropriate HTTP status codes (409 for conflicts, 500 for errors)
  • Comprehensive metadata storage (original filename and user metadata)

Note: The static analysis warning about File(...) in argument defaults is a false positive—this is the idiomatic FastAPI pattern for dependency injection and is the correct way to declare file upload parameters.


717-749: LGTM! The list_videos function is well-implemented.

The implementation correctly:

  • Lists objects with the videos/ prefix
  • Parses the UUID-based key structure (videos/{uuid}/{filename})
  • Handles filenames containing slashes using '/'.join(parts[2:])
  • Provides sensible defaults (content_type defaults to video/mp4)
  • Sorts results by upload time (most recent first)
  • Handles missing last_modified timestamps gracefully (in-memory store case)
docs/source/store-and-retrieve/object-store.md (6)

1-16: License header and copyright year are current.


41-52: ObjectStoreListItem documentation is clear and well-structured. The distinction from ObjectStoreItem and emphasis on memory efficiency is helpful.


54-84: ObjectStore interface documentation is accurate and complete. The type hints for the new list_objects() method are correct, and the method is properly documented in the operations list.


173-185: Usage examples for list_objects() are well-demonstrated. The examples clearly show both basic listing and prefix filtering patterns, with helpful explanation of efficiency benefits.


225-265: Video Upload Integration section is well-documented. Configuration examples are clear, HTTP endpoints are properly described, and the reference to list_objects(prefix="videos/") for accessing uploaded videos integrates nicely with the earlier usage examples.


270-289: Running Tests and Error Handling sections provide valuable guidance. Test commands cover all components (in-memory store, FastAPI routes, S3 integration), and the updated error handling documentation correctly mentions NoSuchKeyError for retrieval/deletion operations.

@getter111 getter111 changed the title feat: Add video upload functionality and video library UI to NAT for multimodal workflows feat: Add video upload and list_objects functionality to ObjectStore Nov 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant