diff --git a/pyo3-object_store/src/prefix.rs b/pyo3-object_store/src/prefix.rs index 6cf4861c..698fd05e 100644 --- a/pyo3-object_store/src/prefix.rs +++ b/pyo3-object_store/src/prefix.rs @@ -83,7 +83,7 @@ impl MaybePrefixedStore { size: meta.size, location: self.strip_prefix(meta.location), e_tag: meta.e_tag, - version: None, + version: meta.version, } } } @@ -120,7 +120,7 @@ fn strip_meta(prefix: Option<&Path>, meta: ObjectMeta) -> ObjectMeta { size: meta.size, location: strip_prefix(prefix, meta.location), e_tag: meta.e_tag, - version: None, + version: meta.version, } } #[async_trait::async_trait] diff --git a/pyproject.toml b/pyproject.toml index cc61c951..8a5db8d5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -115,7 +115,7 @@ markers = [ "network: mark the test as requiring a network connection", "parallel_threads: mark test for concurrent thread execution", ] -thread_unsafe_fixtures = ["minio_bucket", "minio_store"] +thread_unsafe_fixtures = ["minio_bucket", "minio_store", "minio_versioned_store"] [tool.mypy] files = ["obstore/python"] diff --git a/tests/conftest.py b/tests/conftest.py index 806d4360..3d822263 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -11,6 +11,8 @@ import pytest import requests from minio import Minio +from minio.commonconfig import ENABLED +from minio.versioningconfig import VersioningConfig from requests.exceptions import RequestException from obstore.store import S3Store @@ -52,6 +54,7 @@ def pytest_collection_modifyitems(items: list[pytest.Item]) -> None: from obstore.store import ClientConfig, S3Config TEST_BUCKET_NAME = "test-bucket" +TEST_VERSIONED_BUCKET_NAME = "test-versioned-bucket" def find_available_port() -> int: @@ -131,6 +134,11 @@ def minio_config() -> Generator[tuple[S3Config, ClientConfig], Any, None]: secure=False, ) minio_client.make_bucket(TEST_BUCKET_NAME) + minio_client.make_bucket(TEST_VERSIONED_BUCKET_NAME) + minio_client.set_bucket_versioning( + TEST_VERSIONED_BUCKET_NAME, + VersioningConfig(ENABLED), + ) s3_config: S3Config = { "bucket": TEST_BUCKET_NAME, @@ -170,6 +178,14 @@ def minio_store(minio_bucket: tuple[S3Config, ClientConfig]) -> S3Store: return S3Store(config=minio_bucket[0], client_options=minio_bucket[1]) +@pytest.fixture +def minio_versioned_store(minio_config: tuple[S3Config, ClientConfig]) -> S3Store: + """Create an S3Store for a MinIO bucket with versioning enabled.""" + config = minio_config[0].copy() + config["bucket"] = TEST_VERSIONED_BUCKET_NAME + return S3Store(config=config, client_options=minio_config[1]) + + def wait_for_minio(endpoint: str, timeout: int): start_time = time.time() while time.time() - start_time < timeout: diff --git a/tests/test_get.py b/tests/test_get.py index 7f5ffe03..583772ab 100644 --- a/tests/test_get.py +++ b/tests/test_get.py @@ -1,9 +1,14 @@ from __future__ import annotations +from typing import TYPE_CHECKING + import pytest from obstore.store import MemoryStore +if TYPE_CHECKING: + from obstore.store import S3Store + def test_stream_sync(): store = MemoryStore() @@ -236,3 +241,13 @@ def test_access_getresult_attributes_after_reading_stream(): # Validate that we can access the range _after_ consuming the buffer r = resp.range assert r == (0, 4400) + + +def test_get_version(minio_versioned_store: S3Store): + # https://github.com/developmentseed/obstore/issues/806 + # `get` should return the object version that `put` created. + put_result = minio_versioned_store.put("file1.txt", b"foo") + assert put_result["version"] is not None + + resp = minio_versioned_store.get("file1.txt") + assert resp.meta["version"] == put_result["version"] diff --git a/tests/test_head.py b/tests/test_head.py index a2494d5b..e038f944 100644 --- a/tests/test_head.py +++ b/tests/test_head.py @@ -38,3 +38,13 @@ def test_head_with_prefix(minio_bucket: tuple[S3Config, ClientConfig]): store.put("file1.txt", b"foo") assert store.head("file1.txt")["path"] == "file1.txt" + + +def test_head_version(minio_versioned_store: S3Store): + # https://github.com/developmentseed/obstore/issues/806 + # `head` should return the object version that `put` created. + put_result = minio_versioned_store.put("file1.txt", b"foo") + assert put_result["version"] is not None + + meta = minio_versioned_store.head("file1.txt") + assert meta["version"] == put_result["version"]