Skip to content

Require minio-py >=7.2.19#160

Open
brianhelba wants to merge 1 commit intomasterfrom
minio-kwargs
Open

Require minio-py >=7.2.19#160
brianhelba wants to merge 1 commit intomasterfrom
minio-kwargs

Conversation

@brianhelba
Copy link
Copy Markdown
Collaborator

@brianhelba brianhelba commented Nov 24, 2025

This version now requires all arguments to be passed as keyword arguments.

Additionally, the signature of Minio.put_metadata has changed (metadata is now user_metadata), so at least v7.2.19 is now strictly required.

@brianhelba brianhelba force-pushed the minio-kwargs branch 2 times, most recently from 5e630b6 to 535b484 Compare November 24, 2025 17:46
@brianhelba brianhelba changed the title Pass all arguments to Minio as keyword arguments Pass all arguments to minio as keyword arguments Nov 24, 2025
@brianhelba brianhelba force-pushed the minio-kwargs branch 3 times, most recently from d60f74c to 696675f Compare November 24, 2025 18:44
Comment on lines +159 to +166
user_metadata = HTTPHeaderDict()
if self.object_metadata:
for metadata_key, metadata_value in self.object_metadata.items():
if isinstance(metadata_value, str):
user_metadata.add(metadata_key, metadata_value)
else:
for metadata_value_element in metadata_value:
user_metadata.add(metadata_key, metadata_value_element)
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Note, this change due to minio/minio-py#1534

I considered changing the type of MinioStorage.object_metadata as a breaking change. However, exposing that type as urllib3.HTTPHeaderDict seems less intuitive as an API for object metadata.

Note, the type of minio.Object.metadata is now Optional[Union[dict[str, str], HTTPHeaderDict]] (which I haven't tested and don't really know how to interpret), but that's not being exposed as part of our public API.

def fmt(o: Object) -> str:
if template is None:
return o.object_name
return o.object_name or ""
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Small bugfix here, detected by type checking.

raise CommandError(f"bucket {bucket_name} does not exist") from err
elif err.code == "NoSuchBucketPolicy":
raise CommandError(f"bucket {bucket_name} has no policy") from err
raise
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Small bugfix here, detected by type checking.

@brianhelba brianhelba force-pushed the minio-kwargs branch 2 times, most recently from dd43ab8 to 80e0b9e Compare November 24, 2025 19:04
user_metadata = HTTPHeaderDict()
if self.object_metadata:
for metadata_key, metadata_value in self.object_metadata.items():
if isinstance(metadata_value, str):
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I'm not sure how defensive to be here. We clearly type annotate that object_metadata must be a T.Mapping[str, str | Sequence[str]].

However, if someone did pass {'foo': 5} as metadata, I'm not sure if we should attempt to coerce that to a string or at least fail in a more obvious way.

Since str itself is a Sequence, I could check:

if isinstance(metadata_value, Sequence) and not isinstance(metadata_value, str)

logger = getLogger("minio_storage")

ObjectMetadataType = T.Mapping[str, T.Union[str, list[str], tuple[str]]]
ObjectMetadataType = T.Mapping[str, T.Union[str, Sequence[str]]]
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Slightly widened this, now that we're not bound by any upstream compatibility.

@brianhelba brianhelba requested a review from thomasf November 24, 2025 19:09
@brianhelba brianhelba force-pushed the minio-kwargs branch 2 times, most recently from 37c7a2d to dfda05e Compare November 24, 2025 19:24
def create_minio_client_from_settings(*, minio_kwargs=None):
endpoint = get_setting("MINIO_STORAGE_ENDPOINT")
kwargs = {
def create_minio_client_from_settings(**minio_kwargs: T.Any) -> minio.Minio:
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This is a slightly breaking change this function signature, but I think it results in a more sensible API. This will be released as part of a new minor version bump anyway.

@brianhelba
Copy link
Copy Markdown
Collaborator Author

@thomasf I'd appreciate a review on this.

I'm disappointed by upstream minio-py's attitude towards API breakage, but given the maintenance resources that django-minio-storage library has, I think the only option is to track the latest upstream version (and not try to support both old and new versions).

@brianhelba brianhelba changed the title Pass all arguments to minio as keyword arguments Require minio-py >=7.2.19 Nov 24, 2025
This version now requires all arguments to be passed as
keyword arguments.

Additionally, the signature of `Minio.put_metadata` has changed
(`metadata` is now `user_metadata`), so at least v7.2.19 is now
strictly required.
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.

2 participants