对 MinIO API 进行封装并上传到第三方库 Pyzjr

目录

本文介绍

上一节补充

使用官方的游乐场进行测试和开发

熟悉MinIO的API

创建客户端

操作桶

1、检查桶是否存在,如果不存在就创建一个桶

2、列出所有的存储桶名

3、删除储存桶

4、用于查看存储桶的对象

扫描二维码关注公众号,回复: 15597878 查看本文章

操作对象

1、删除对象

2、删除zip文件

3、下载对象

4、下载zip文件,自动解压

5、上传对象

6、上传文件夹为zip文件

预签署

1、可供上传文件的URL,时限为2小时

2、可供下载文件的URL,时限为2小时

封装Minio的操作

1、先下载pyzjr第三方库

2、UML图

参考文章


本文介绍

MinIO 是一个开源的对象存储服务,它提供了简单而强大的 API,用于管理和操作存储桶中的对象。本文介绍了如何对 MinIO 的 API 进行封装,将其封装为易于使用的函数,并将封装后的函数上传到第三方库 Pyzjr 中。

上一节补充

上一章需要补充的一点是需要Python的版本要做 3.7 及以上的版本。

使用官方的游乐场进行测试和开发

官方提供了一个MinIO服务器游乐场 https://play.min.io,可以随意使用此服务进行测试和开发。

好,现在我们先要用这个游乐场进行上传文件,熟悉操作。

from minio import Minio
from minio.error import S3Error

def main():
    # Create a client with the MinIO server playground, its access key
    # and secret key.
    client = Minio(
        "play.min.io",
        access_key="Q3AM3UQ867SPQQA43P2F",
        secret_key="zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG",
    )

    # Make 'ikun' bucket if not exist.
    found = client.bucket_exists("ikun")
    if not found:
        client.make_bucket("ikun")
    else:
        print("Bucket 'ikun' already exists")

    client.fput_object(
        "ikun", "ikun.mp4", "D:\Python_zjr\python_minio\ikun.mp4",
    )
    print(
        "'D:\Python_zjr\python_minio\ikun.mp4' is successfully uploaded as "
        "object 'ikun.mp4' to bucket 'ikun'."
    )
if __name__ == "__main__":
    try:
        main()
    except S3Error as exc:
        print("error occurred.", exc)

进入play.min.io,在搜索框中可以看见成功的创建了名为ikun的桶。点击进去,也发现了已经成功的上传了我们的视频文件。

熟悉MinIO的API

首先,我们了解了 MinIO 的基本概念和常用的 API 操作,包括创建存储桶、上传对象、下载对象、删除对象等。然后,通过使用 Python 的 MinIO 客户端库,我们将这些 API 操作封装为函数,使其更加易于使用和维护。封装的函数包括创建存储桶、上传对象、下载对象、删除对象等功能,并提供了一些灵活的参数选项。

创建客户端

from minio import Minio
from minio.error import S3Error

minioClient = Minio(
                  endpoint='play.minio.io:9000',
                  access_key='Q3AM3UQ867SPQQA43P2F',
                  secret_key='zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG'
                  )
  • endpoint:S3服务的主机名
  • access_key:用户ID
  • secret_key:密码
操作存储桶 操作对象 Presigned操作 存储桶策略/通知
make_bucket get_object presigned_get_object get_bucket_policy
list_buckets put_object presigned_put_object set_bucket_policy
bucket_exists copy_object presigned_post_policy get_bucket_notification
remove_bucket stat_object set_bucket_notification
list_objects remove_object remove_all_bucket_notification
list_objects_v2 remove_objects listen_bucket_notification
list_incomplete_uploads remove_incomplete_upload
fput_object
fget_object
get_partial_object

操作桶

1、检查桶是否存在,如果不存在就创建一个桶

def Foundbucket(client,bucket_name):
    found = client.bucket_exists(bucket_name)
    if not found:
        client.make_bucket(bucket_name)
    else:
        print(f"Bucket {bucket_name} already exists")

2、列出所有的存储桶名

def get_bucket_list(client):
    try:
        buckets = client.list_buckets()
        for bucket in buckets:
            print(bucket.name, bucket.creation_date)  # 获取桶的名称和创建时间
    except InvalidResponseError as err:
        print(err)

3、删除储存桶

def get_remove_bucket(client,bucket_name):
    try:
        client.remove_bucket(bucket_name)
        print("删除存储桶成功")
    except InvalidResponseError as err:
        print(err)

4、用于查看存储桶的对象

def get_bucket_files(client,bucket_name):
    try:
        objects = client.list_objects(bucket_name, prefix=None,
                                               recursive=True)
        for obj in objects:
        print(obj.bucket_name, obj.object_name.encode('utf-8'), obj.last_modified,
                      obj.etag, obj.size, obj.content_type)
    except InvalidResponseError as err:
        print(err)

操作对象

1、删除对象

def delete_object(client, bucket_name, objects):
    try:
        for obj in objects:
        client.remove_object(bucket_name, obj)
        print(f"Deleted {obj} under {bucket_name}")
    except InvalidResponseError as err:
        print(err)

2、删除zip文件

def delete_folder(client, bucket_name, folder_path):
    try:
        temp_dir = tempfile.mkdtemp()
        folder_name = os.path.basename(folder_path)
        zip_file = os.path.join(temp_dir, f"{folder_name}.zip")
        
        shutil.make_archive(zip_file[:-4], 'zip', folder_path)
        
        client.remove_object(bucket_name, f"{folder_name}.zip")
        print(f"Deleted {folder_name}.zip from bucket {bucket_name}")
        
        shutil.rmtree(temp_dir)
    except InvalidResponseError as err:
        print(err)

3、下载对象

def download_object(client, bucket_name, objects, filepath=None):
    try:
        if filepath is None:
            current_dir = os.path.dirname(os.path.abspath(__file__))  # 获取当前文件的目录
        else:
            current_dir = filepath
        for obj in objects:
            file_path = os.path.join(current_dir, obj)  # 拼接目录和文件名
            client.fget_object(bucket_name, obj, file_path)
            print(f"Downloaded object {obj} to {file_path}")
    except InvalidResponseError as err:
        print(err)

4、下载zip文件,自动解压

def download_folder(client, bucket_name, local_path):
    try:
        temp_dir = tempfile.mkdtemp()

        client.fget_object(bucket_name, f"{local_path}.zip", os.path.join(temp_dir, f"{local_path}.zip"))
        print(f"Downloaded {local_path}.zip from bucket {bucket_name}")
        shutil.unpack_archive(os.path.join(temp_dir, f"{local_path}.zip"), local_path)
        print(f"Extracted {local_path}.zip to {local_path}")

        shutil.rmtree(temp_dir)
    except InvalidResponseError as err:
        print(err)

5、上传对象

def upload_object(client, bucket_name, file_path):
    try:
        object_name = os.path.basename(file_path)  # 提取文件名作为对象名称
        with open(file_path, "rb") as file_data:
            file_size = os.path.getsize(file_path)
            client.put_object(bucket_name, object_name, file_data, file_size)
            print(f"Uploaded object {object_name} to bucket {bucket_name}")
    except IOError as e:
        print(f"Failed to open file: {file_path} - {e}")
    except S3Error as err:
        print(f"Error occurred: {err}")

6、上传文件夹为zip文件

def upload_folder(client, bucket_name, folder_path):
    try:
        temp_dir = tempfile.mkdtemp()
        folder_name = os.path.basename(folder_path)
        zip_file = os.path.join(temp_dir, f"{folder_name}.zip")

        shutil.make_archive(zip_file[:-4], 'zip', folder_path)

        with open(zip_file, "rb") as file_data:
            file_size = os.path.getsize(zip_file)
            client.put_object(bucket_name, f"{folder_name}.zip", file_data, file_size)
            print(f"Uploaded {folder_name}.zip to bucket {bucket_name}")

        shutil.rmtree(temp_dir)
    except IOError as e:
        print(f"Failed to compress folder: {folder_path} - {e}")
    except S3Error as err:
        print(f"Error occurred: {err}")

预签署

1、可供上传文件的URL,时限为2小时

def upload_url(self, client, bucket_name, object_name, expires_in=7200):
    try:
        # 生成预签名 URL
        url = client.presigned_put_object(bucket_name, object_name, expires=timedelta(seconds=expires_in))
        return url
    except Exception as e:
        print(f"Failed to generate presigned upload URL: {e}")
        return None

2、可供下载文件的URL,时限为2小时

def download_url(client, bucket_name, object_name, expires_in=7200):
    try:
        # 生成预签名 URL
        url = client.presigned_get_object(bucket_name, object_name, expires=timedelta(seconds=expires_in))
        return url
    except Exception as e:
        print(f"Failed to generate presigned download URL: {e}")
        return None

封装Minio的操作

第三方库 Pyzjr,它是一个开源的 Python 库。我将封装好的 MinIO API 函数上传到 Pyzjr 库中,可供我们团队轻松地使用这些函数,加速在 MinIO 上的开发工作。

1、先下载pyzjr第三方库

pip install pyzjr

版本大于等于0.0.9是有对minio的封装的。

2、UML图

下面是pyzjr中对minio的封装,与上面的函数相同。

想要对MinIO进行更多的操作的话,可以查看github文档,里面提供了很多写好的示例,如果想要进行操作,可以先去看看里面的示例代码进行修改。我这里封装的是我认为可能会用到的,不完整但足够使用了。

参考文章

Python的API参考文档(英文与中文):

Python Quickstart Guide — MinIO Object Storage for Linux

Minio SDKs - Python Client API文档 - 《Minio Cookbook 中文版》 - 书栈网 · BookStack

猜你喜欢

转载自blog.csdn.net/m0_62919535/article/details/131589948
今日推荐