Add streaming S3 import command with metadata identity and path filter support - #8
Conversation
Co-authored-by: Lundez <7490199+Lundez@users.noreply.github.com>
|
@copilot will this be able to import a "" path, "**/.jpg" (example filtetype) path or list of paths? If not, can we add support for that? |
Co-authored-by: Lundez <7490199+Lundez@users.noreply.github.com>
Co-authored-by: Lundez <7490199+Lundez@users.noreply.github.com>
Co-authored-by: Lundez <7490199+Lundez@users.noreply.github.com>
Co-authored-by: Lundez <7490199+Lundez@users.noreply.github.com>
Yes — it now supports repeatable |
There was a problem hiding this comment.
Pull request overview
This PR adds a streaming fluxel import command to bootstrap a repository from S3 (either blob-backed via blake3 or metadata-only via meta), and refactors core storage/repository plumbing to support S3-backed repositories with local per-client state, manifest sidecar indexes, and optimistic ref updates.
Changes:
- Add
fluxel importwith repeatable--pathfilters and--identity blake3|meta, streaming S3 listing/reads. - Introduce repository-store + client-state split (
LocalRepositoryStore/S3RepositoryStore,LocalClientState) plus manifest sidecar indexes for point/prefix lookups. - Expand CLI + tests + docs/CI to cover remote repo operations, metadata-only workflows, and S3 integration via Ministack.
Reviewed changes
Copilot reviewed 29 out of 37 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_s3_integration.py | Adds real S3 integration coverage for branch/merge/import/verify and conflict handling. |
| tests/test_mandatory_validation.py | Adds regression tests for metadata-only operations, manifest validation, sidecar index behavior, and conflict messaging. |
| tests/test_cli.py | Extends CLI tests for --repo semantics, S3 repo flows, import, mv/rm -m, staged reads, and error reporting. |
| tests/conftest.py | Adds fake S3 client + Ministack fixtures for unit + integration testing. |
| src/fluxel/core/storage.py | Adds S3 URI parsing, streaming list/head/open helpers, and source URI metadata helpers. |
| src/fluxel/core/repository_support.py | Adds path normalization, import pattern matching, and meta-identity helpers used across repo ops. |
| src/fluxel/core/repository_store.py | Introduces RepositoryStore abstraction with local + S3 implementations and S3 branch locking/CAS updates. |
| src/fluxel/core/repository.py | Refactors repository to use stores + client state; adds import_s3, merge, metadata-only remove_paths/move, and sidecar-backed lookups. |
| src/fluxel/core/manifest_index.py | Adds sidecar index format + lookup/iteration helpers to avoid full manifest scans. |
| src/fluxel/core/manifest.py | Changes manifest JSONL encoding to tagged arrays with stricter validation and line-aware errors; makes file walking deterministic. |
| src/fluxel/core/layout.py | Refactors layout initialization into a classmethod. |
| src/fluxel/core/index.py | Switches analytical index build to stream entries via repo store and load via CSV into DuckDB. |
| src/fluxel/core/filesystem.py | Uses store-backed blob reads + source-uri reads; adds repo caching; uses sidecar lookups for point/prefix reads. |
| src/fluxel/core/client_state.py | Adds local per-client state (HEAD, staging, branch snapshots) with atomic writes. |
| src/fluxel/core/init.py | Exposes new APIs/types (stores, client state, import/merge/move/remove, S3 helpers). |
| src/fluxel/core/SPEC.md | Adds placeholder spec doc. |
| src/fluxel/cli.py | Adds import, merge, mv, metadata-only rm -m; standardizes --repo; improves error handling and repeated --path parsing. |
| src/fluxel/init.py | Re-exports new public API and CLI entrypoints. |
| src/fluxel/.DS_Store | Adds a macOS junk file (should be removed). |
| src/.DS_Store | Adds a macOS junk file (should be removed). |
| scripts/run_s3_integration.sh | Adds script to run Ministack-backed integration tests locally/CI. |
| pyproject.toml | Updates project metadata, license, URLs, and pytest markers. |
| __MACOSX/tests/._pycache | Adds macOS archive junk (should be removed). |
| __MACOSX/src/fluxel/core/._pycache | Adds macOS archive junk (should be removed). |
| __MACOSX/src/fluxel/._pycache | Adds macOS archive junk (should be removed). |
| __MACOSX/src/fluxel/._.DS_Store | Adds macOS archive junk (should be removed). |
| __MACOSX/src/._.DS_Store | Adds macOS archive junk (should be removed). |
| ROADMAP.md | Adds project roadmap describing the architecture and planned phases. |
| README.md | Documents new --repo semantics, import/merge/mv/rm workflows, integration tests, and licensing notes. |
| NOTICE | Adds attribution + sponsorship notice aligned with AGPL distribution. |
| LICENSE | Adds AGPL-3.0-or-later license text. |
| ISSUES.MD | Updates CLI examples to use --repo. |
| CONTRIBUTING.md | Adds contributor guidance and test instructions. |
| CHANGELOG.md | Adds changelog entries for new import/index/store/client-state capabilities. |
| .gitignore | Ignores macOS junk artifacts going forward. |
| .github/workflows/ci.yml | Adds CI (unit + S3 integration via script) and rejects macOS junk files. |
| .github/FUNDING.yml | Adds GitHub Sponsors configuration. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| with NamedTemporaryFile(mode="wb", suffix=".idx", delete=False) as temp: | ||
| temp_path = Path(temp.name) | ||
| temp.write(response["Body"].read()) | ||
| self._manifest_index_cache[manifest_hash] = temp_path | ||
| return temp_path |
| def _matches_logical_prefix(path: str, logical_prefix: str) -> bool: | ||
| return path == logical_prefix or path.startswith(f"{logical_prefix}/") | ||
|
|
||
|
|
| metadata = describe_source_uri(source_uri) | ||
| if identity_mode == "blake3": | ||
| identity_value = self._store_blob_from_source_uri(source_uri) | ||
| blob_hash = identity_value if store_blob else None | ||
| elif identity_mode == "meta": |
| raise ValueError(f"S3 source cannot be bucket root: {raw_source}") | ||
|
|
||
| objects = list(iter_s3_objects(raw_source)) | ||
| if not objects: | ||
| raise FileNotFoundError(f"Cannot stage missing S3 path: {raw_source}") |
This adds an
importcommand for bootstrapping a repository from S3 without materializing the full object list in memory. It supports both canonical blob-backed imports and metadata-only imports so large datasets can be registered first and verified later.CLI surface
fluxel import <s3-uri> -m <message>--identity blake3and--identity meta--pathfilters for exact logical paths or glob patterns such as*and**/*.jpgStreaming S3 ingest
list_objects_v2incrementally instead of collecting the full listingMetadata-only import path
--identity meta, records logical path/size identity without reading object payloadssource_uriass3://...so imported entries remain readable before promotionverifyflow to promote imported metadata entries into canonical blobs laterSource URI handling
fluxel://...reads for metadata-only entries imported from S3Targeted correctness updates
Example:
Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.