Skip to content

feat(artifacts): add LocalFileArtifactService for local file system storage #2408

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

eduramirezh
Copy link

This adds a new LocalFileArtifactService implementation that stores artifacts
on the local file system instead of cloud storage or memory, providing developers
with a local persistence option for development, testing, and deployment scenarios.

Key features:

  • File system storage with configurable base path (defaults to ./adk_artifacts)
  • Maintains consistent directory structure with user/session namespacing
  • Stores MIME type metadata in separate .metadata.json files
  • Full async support using asyncio.to_thread() for non-blocking I/O
  • Proper error handling for corrupted metadata and missing files
  • Sequential integer versioning starting from version 0

Changes:

  • Add LocalFileArtifactService class implementing BaseArtifactService interface
  • Add comprehensive standalone unit tests for all functionality
  • Integrate with existing parametrized tests for consistency validation
  • Export new service in artifacts/init.py
  • Fix minor typo in CONTRIBUTING.md

Testing Plan

Unit Tests

All unit tests pass with comprehensive coverage:

Standalone Tests (24 tests):

  • test_local_file_artifact_service.py covers:
    • Basic CRUD operations (save/load/delete)
    • Version management and specific version loading
    • User-namespaced vs session-scoped file handling
    • MIME type preservation across different content types
    • Directory structure validation
    • Error handling (corrupted metadata, missing files)
    • Edge cases (nonexistent versions, empty lists)

Integration Tests (24 additional tests):

  • Extended existing parametrized tests in test_artifact_service.py
  • Added LOCAL_FILE variant to all existing test cases
  • Validates consistency with InMemoryArtifactService and GcsArtifactService

Test Results:

========================= 48 passed, 1 warning in 1.75s =========================

Note: The 1 warning is a pre-existing Pydantic warning unrelated to this change.

Code Quality:

  • pylint: 10.00/10 (perfect score)
  • mypy: Success, no type errors
  • Formatted with pyink and isort per repository standards

Manual E2E Testing

The LocalFileArtifactService can be manually tested by:

  1. Basic Usage:

    from google.adk.artifacts import LocalFileArtifactService
    service = LocalFileArtifactService(base_path="./test_artifacts")
  2. Directory Structure Verification:
    After saving artifacts, verify correct file system layout:

    • Regular files: ./test_artifacts/{app}/{user}/{session}/{filename}/{version}
    • User files: ./test_artifacts/{app}/{user}/user/{filename}/{version}
    • Metadata files: {path}.metadata.json alongside each artifact
  3. Integration Testing:
    Can be used as drop-in replacement for other artifact services in any
    existing ADK application or workflow.

This implementation maintains full API compatibility with existing artifact
services while providing local file system persistence capabilities.

…torage

This adds a new LocalFileArtifactService implementation that stores artifacts
on the local file system instead of cloud storage or memory, providing developers
with a local persistence option for development, testing, and deployment scenarios.

Key features:
- File system storage with configurable base path (defaults to ./adk_artifacts)
- Maintains consistent directory structure with user/session namespacing
- Stores MIME type metadata in separate .metadata.json files
- Full async support using asyncio.to_thread() for non-blocking I/O
- Proper error handling for corrupted metadata and missing files
- Sequential integer versioning starting from version 0

Changes:
- Add LocalFileArtifactService class implementing BaseArtifactService interface
- Add comprehensive standalone unit tests for all functionality
- Integrate with existing parametrized tests for consistency validation
- Export new service in artifacts/__init__.py
- Fix minor typo in CONTRIBUTING.md

## Testing Plan

### Unit Tests
All unit tests pass with comprehensive coverage:

**Standalone Tests (24 tests):**
- test_local_file_artifact_service.py covers:
  - Basic CRUD operations (save/load/delete)
  - Version management and specific version loading
  - User-namespaced vs session-scoped file handling
  - MIME type preservation across different content types
  - Directory structure validation
  - Error handling (corrupted metadata, missing files)
  - Edge cases (nonexistent versions, empty lists)

**Integration Tests (24 additional tests):**
- Extended existing parametrized tests in test_artifact_service.py
- Added LOCAL_FILE variant to all existing test cases
- Validates consistency with InMemoryArtifactService and GcsArtifactService

**Test Results:**
```
========================= 48 passed, 1 warning in 1.75s =========================
```

Note: The 1 warning is a pre-existing Pydantic warning unrelated to this change.

**Code Quality:**
- pylint: 10.00/10 (perfect score)
- mypy: Success, no type errors
- Formatted with pyink and isort per repository standards

### Manual E2E Testing
The LocalFileArtifactService can be manually tested by:

1. **Basic Usage:**
   ```python
   from google.adk.artifacts import LocalFileArtifactService
   service = LocalFileArtifactService(base_path="./test_artifacts")
   ```

2. **Directory Structure Verification:**
   After saving artifacts, verify correct file system layout:
   - Regular files: `./test_artifacts/{app}/{user}/{session}/{filename}/{version}`
   - User files: `./test_artifacts/{app}/{user}/user/{filename}/{version}`
   - Metadata files: `{path}.metadata.json` alongside each artifact

3. **Integration Testing:**
   Can be used as drop-in replacement for other artifact services in any
   existing ADK application or workflow.

This implementation maintains full API compatibility with existing artifact
services while providing local file system persistence capabilities.
@adk-bot adk-bot added bot triaged [Bot] This issue is triaged by ADK bot services [Component] This issue is related to runtime services, e.g. sessions, memory, artifacts, etc labels Aug 7, 2025
@adk-bot adk-bot requested a review from DeanChensj August 7, 2025 10:06
@adk-bot
Copy link
Collaborator

adk-bot commented Aug 7, 2025

Response from ADK Triaging Agent

Hello @eduramirezh, thank you for creating this PR!

This PR is a new feature, could you please associate a GitHub issue with this PR? If there is no existing issue, could you please create one?

This information will help reviewers to review your PR more efficiently. Thanks!

@eduramirezh
Copy link
Author

Related issue: #2410

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bot triaged [Bot] This issue is triaged by ADK bot services [Component] This issue is related to runtime services, e.g. sessions, memory, artifacts, etc
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants