minio / minio-py

MinIO Client SDK for Python
https://docs.min.io/docs/python-client-quickstart-guide.html
Apache License 2.0
851 stars 325 forks source link

Does MinIO's server support conditional headers such as If-Match and If-None-Match in methods like set_object_tags? #1414

Closed sachin2004nit closed 6 months ago

sachin2004nit commented 6 months ago

Amazon S3 provides support for IfMatch tag. while setting put_object_tagging,

response = s3.list_objects_v2(
            Bucket=bucket_name,
            Prefix='',  # Adjust prefix as needed
            Delimiter=''
        )

for file_obj in files:
       files = [obj for obj in response['Contents'] if obj['Key'].endswith(file_filter)]
       tag_response = s3.get_object_tagging(Bucket=bucket_name, Key=file_key)
       tags = tag_response['TagSet']
       etag = file_obj['ETag'].strip('"')

                # Attempt to update the file's tag conditionally
                s3.put_object_tagging(
                    Bucket=bucket_name,
                    Key=file_key,
                    Tagging={
                        'TagSet': [
                            {
                                'Key': processing_tag_key,
                                'Value': processing_tag_value
                            }
                        ]
                    },
                    IfMatch=etag  # Conditional update using ETag
                )

1) Does MinIO supports similar mechanism using set_object_tags. or may be a check before updating objects (A timestamp) check to verify of already updated with a different timestamp. inside set_object_tagging call. 2) if i change the code like following

def set_object_tags(
        self,
        bucket_name: str,
        object_name: str,
        tags: Tags,
        version_id: str | None = None,
        if_match: str | None = None,  # Add if_match as a new parameter
):
    """
    Set tags configuration to an object.

    :param bucket_name: Name of the bucket.
    :param object_name: Object name in the bucket.
    :param version_id: Version ID of the Object.
    :param tags: :class:`Tags <Tags>` object.
    :param if_match: ETag value to use in the If-Match header for conditional requests.
    Example::
        tags = Tags.new_object_tags()
        tags["Project"] = "Project One"
        tags["User"] = "jsmith"
        client.set_object_tags("my-bucket", "my-object", tags)
    """
    check_bucket_name(bucket_name, s3_check=self._base_url.is_aws_host)
    check_non_empty_string(object_name)
    if not isinstance(tags, Tags):
        raise ValueError("tags must be Tags type")

    body = marshal(Tagging(tags))
    query_params = {"versionId": version_id} if version_id else {}
    query_params["tagging"] = ""

    # Create headers dictionary with Content-MD5 and optional If-Match header
    headers = {"Content-MD5": cast(str, md5sum_hash(body))}
    if if_match:
        headers["If-Match"] = if_match

    self._execute(
        "PUT",
        bucket_name,
        object_name=object_name,
        body=body,
        headers=headers,  # Pass the headers dictionary
        query_params=cast(DictType, query_params),
    )

Will minIO server side support the above changes?

balamurugana commented 6 months ago

As per AWS S3 Specification, it is not supported.

sachin2004nit commented 6 months ago

As per AWS S3 Specification, it is not supported.

They are silent in documentation.

sachin2004nit commented 6 months ago

Even if they don't support it' can i write this and commit .. and raise a PR.. So will minIO be able to support it? i have seen code of minio-python sdk only. In case u want me to write change code at server level. please specify the github url. i will look into it..and see the feasibility and if possible will raise a PR with changes.