Git Product home page Git Product logo

miniopy-async's Introduction

miniopy-async

Asynchronous MinIO Client SDK for Python

PyPI PyPI - Downloads PyPI - Python Version
GitHub repo size GitHub Workflow Status GitHub closed issues GitHub closed pull requests

Catalogue

Declaration

  • This project is based on Huseyn Mashadiyev's minio-async 1.0.0.
  • This project has fixed some bugs of minio-async and added some new features.
  • Miniopy-async 1.2 has been pulled requests to minio-async.

Minimum Requirements

  • Python>3.6

Build from source

git clone https://github.com/hlf20010508/miniopy-async.git
cd miniopy-async
python setup.py install

Installation

Install with pip

PyPI

pip install miniopy-async

Github Repository

pip install git+https://github.com/hlf20010508/miniopy-async.git

Install with pipenv

PyPI

pipenv install miniopy-async

Github Repository

pipenv install "miniopy-async@ git+https://github.com/hlf20010508/miniopy-async.git"

Quick Start

from miniopy_async import Minio
import asyncio

client = Minio(
    "play.min.io",
    access_key="Q3AM3UQ867SPQQA43P2F",
    secret_key="zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG",
    secure=True  # http for False, https for True
)


async def main():
    url = await client.presigned_get_object("my-bucket", "my-object")
    print('url:', url)


loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
from sanic import Sanic, response
from miniopy_async import Minio
from urllib import parse

app = Sanic(__name__)

client = Minio(
    "play.min.io",
    access_key="Q3AM3UQ867SPQQA43P2F",
    secret_key="zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG",
    secure=True  # http for False, https for True
)


# http://127.0.0.1:8000/download?bucket=my-bucket&fileName=testfile
@app.route('/download', methods=['GET'])
async def download(request):
    print('downloading ...')
    bucket=request.args.get('bucket')
    fileName=request.args.get('fileName')

    # decodeURI, for those which has other language in fileName, such as Chinese, Japanese, Korean
    fileName = parse.unquote(fileName)

    url = await client.presigned_get_object(bucket_name=bucket, object_name=fileName)
    return response.redirect(url)

More References

miniopy-async's People

Contributors

chasezheng avatar hakiergrzonzo avatar hlf20010508 avatar huseynmashadiyev avatar johannesloibl avatar miss85246 avatar nkukard avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

miniopy-async's Issues

fget_object downloads zero size files

Pick this example and replace key/secret/url with your minio setup:

import asyncio

from miniopy_async import Minio

client = Minio(
    "play.min.io",
    access_key="Q3AM3UQ867SPQQA43P2F",
    secret_key="zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG",
    secure=True  # http for False, https for True
)


async def main():
    # Download data of an object.
    print("example one")
    await client.fget_object("my-bucket", "my-object", "my-filename")


loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()

the file downloaded will be empty. Some debugging shows up that this code line is never executed (fget_object):

            async with aiofile.async_open(tmp_file_path, "wb") as tmp_file:
                async for data in response.content.iter_chunked(n=1024 * 1024):
                    await tmp_file.write(data)
                    ^^^^^^^^^^^^^^^^^^^^^^^^

The response.content here is always EOF because it has been already read at api._url_open :

 async with aiohttp.ClientSession() as session:
            response = await session.request(
                method,
                urlunsplit(url),
                data=body,
                headers=headers
            )
            await response.read()
            ^^^^^^^^^^^^^^^^^^^^

        if response.status in [200, 204, 206]:
            return response

It also looks like aiohttp.ClientSession needs to be created outside of get_object otherwise stream read from the session released upon exit of _url_open would not work either.

Consider distributing on conda-forge

Feature Request

๐Ÿ‘‹ Hi. Would you be open to distributing miniopy-async on conda-forge as well?

It looks like it would be pretty straightforward to do given that grayskull (which can build the recipe for you) passes without any missing dependencies.

$ grayskull pypi --list-missing-deps --strict-conda-forge miniopy-async



#### Initializing recipe for miniopy-async (pypi) ####

Recovering metadata from pypi...
Starting the download of the sdist package miniopy-async
miniopy-async 100% Time:  0:00:00   1.8 MiB/s|############################################################################################################################################################|
Checking for pyproject.toml
pyproject.toml not found.
Recovering information from setup.py
Executing injected distutils...
ERROR: Could not find an activated virtualenv (required).
ERROR:It was not possible to install setuptools.
Command: pip install setuptools --target=/tmp/pip-dir-0i63b_4n.
Error: Command '['/home/feickert/.pixi/envs/grayskull/bin/python3.12', '-m', 'pip', 'install', 'setuptools', '--target=/tmp/pip-dir-0i63b_4n']' returned non-zero exit status 3.
Recovering metadata from setup.cfg
Checking >> urllib3 100% |#########################################################################################################################################################|[Elapsed Time: 0:00:02]
Recovering license info from spdx.org ...
INFO:Best match for license Apache2.0 was Apache-2.0.
Best matches: ['Apache-2.0']
License type: Apache-2.0
License file: ['LICENSE']
Build requirements:
  <none>
Host requirements:
  - python >=3.7
  - pip
Run requirements:
  - python >=3.7
  - certifi
  - aiofile
  - aiohttp
  - urllib3

RED: Missing packages
GREEN: Packages available on conda-forge
All dependencies are already on conda-forge.

Maintainers:
   - hlf20010508

#### Recipe generated on /tmp for miniopy-async ####

I would be willing to help walk you through adding a package to conda-forge if this is the first time you've done this.

Is your feature request related to a problem? Please describe.

No, it is motivated by ssl-hep/ServiceX_frontend#352.

Describe the solution you'd like

Add miniopy-async to https://github.com/conda-forge/staged-recipes through making a PR with the recipe generated by grayskull.

Describe alternatives you've considered

None.

Can't import aiostream

Bug Report

Describe the bug

aiostream is not included in the dependencies

To Reproduce

# Inside new virtualenv
python setup.py install
python tests.py

Expected behavior

tests should be run

Screenshots or Outputs

Traceback (most recent call last):
  File "/home/erevilla/svn/miniopy-async/tests.py", line 19, in <module>
    from aiostream.stream import list as alist
ModuleNotFoundError: No module named 'aiostream'

Desktop:

  • OS: Ubuntu Linux, 20.04

Add snowball object

Feature Request

Is your feature request related to a problem? Please describe.

Minio has introduced snowball object. This type of object allows user to upload multiple files in single request. You can find more details in Minio blog and API docs

Describe the solution you'd like

This feature is already implemented in official Minio package minio under the method upload_snowball_objects. I think it is good idea to keep original naming. Source code can be found here

Custom metadata

Bug Report

Describe the bug

The values of custom metadata in put_object get converted into a list which leads to TypeError: Cannot serialize non-str key ['test_value'].

To Reproduce

Run

await minio.put_object(
    bucket_name=bucket_name,
    object_name=file_id,
    data=buffer,
    content_type="application/pdf",
    length=size,
    metadata={
        'test_key': 'test_value'
    }
)

Expected behavior

The resulting headers should be:

{"X-Amz-Meta-test_key": "test_value"}

not

{"X-Amz-Meta-test_key": ["test_value"]}

Additional context

The causing part is here:

def normalize_value(values):

Reorganize and format the code

I found that some code fragments do not conform to the format of pep8, which is not beautiful and easy to read. I hope I can reformat the code.

async def _get_region blocks forever

Bug Report

Describe the bug

put_object is running into a timeout, because of an indentation error in
api.py:473:

async with aiohttp.ClientSession() as session:
	response = await self._url_open(
		"GET",
		"us-east-1",
		bucket_name=bucket_name,
		query_params={"location": ""},
		session=session,
	)

element = ET.fromstring(await response.text())

await response is outside the context manager and the session already got closed, leading to a timeout after some minutes.
Indenting the line fixes the problem.
PR incoming.

warning msg: Unclosed client session, Unclosed connector

Bug Report

Describe the bug

I got this warning:

example one
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x105883820>
Unclosed connector
connections: ['[(<aiohttp.client_proto.ResponseHandler object at 0x1062769a0>, 0.497560541)]']
connector: <aiohttp.connector.TCPConnector object at 0x10626bfa0>
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x10626bfd0>
Unclosed connector
connections: ['[(<aiohttp.client_proto.ResponseHandler object at 0x106276820>, 0.524557333)]']
connector: <aiohttp.connector.TCPConnector object at 0x10628c460>
created my-object object; etag: 5d41402abc4b2a76b9719d911017c592, version-id: 5868d1d6-5085-43b1-bb43-425fded2f2a4

To Reproduce

Steps to reproduce the behavior:
My code is like this:

import io
from miniopy_async import Minio
import asyncio

client = Minio(
        "play.min.io",
        access_key="Q3AM3UQ867SPQQA43P2F",
        secret_key="zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG",
    )


async def main():
    # Upload data.
    print('example one')
    result = await client.put_object(
        "test", "my-object", io.BytesIO(b"hello"), 5,
    )
    print(
        "created {0} object; etag: {1}, version-id: {2}".format(
            result.object_name, result.etag, result.version_id,
        ),
    )


if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    loop.close()

Expected behavior

I think the sesson or connection should be closed automatically, or some close api to use.

Desktop:

  • OS: macos m1 pro
  • Browser [e.g. chrome, safari]
  • Version 13.0.1

Checksum in object stat/get

Hello

Bug Report

Describe the bug

As I understand from the S3 docs, when providing a "x-amz-checksum-X" header to put an object, the same header should be returned upon stat/get (HEAD/GET). It's currently not the case. Is it due to minio headers generation ? Reading the raw request in the stat does not yield any more result.

To Reproduce

upload a file via "put_object" with a "x-amz-checksum-X" header that is valid. Stat or Get the object.

Expected behavior

The header should be present

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.