django-minio-backend


Namedjango-minio-backend JSON
Version 3.6.0 PyPI version JSON
download
home_pagehttps://github.com/theriverman/django-minio-backend
SummaryThe django-minio-backend provides a wrapper around the MinIO Python Library.
upload_time2024-03-24 11:34:53
maintainerNone
docs_urlNone
authorKristof Daja (theriverman)
requires_pythonNone
licenseMIT License | Copyright (c) 2024 Kristof Daja
keywords
VCS
bugtrack_url
requirements Django minio Pillow setuptools
Travis-CI No Travis.
coveralls test coverage No coveralls.
            [![django-app-tests](https://github.com/theriverman/django-minio-backend/actions/workflows/django-tests.yml/badge.svg)](https://github.com/theriverman/django-minio-backend/actions/workflows/django-tests.yml)
[![publish-py-dist-to-pypi](https://github.com/theriverman/django-minio-backend/actions/workflows/publish-to-pypi.yml/badge.svg)](https://github.com/theriverman/django-minio-backend/actions/workflows/publish-to-pypi.yml)
[![PYPI](https://img.shields.io/pypi/v/django-minio-backend.svg)](https://pypi.python.org/pypi/django-minio-backend)

# django-minio-backend
The **django-minio-backend** provides a wrapper around the 
[MinIO Python SDK](https://docs.min.io/docs/python-client-quickstart-guide.html).
See [minio/minio-py](https://github.com/minio/minio-py) for the source.

## Integration
1. Get and install the package:
```bash
pip install django-minio-backend
```

2. Add `django_minio_backend` to `INSTALLED_APPS`:
```python
INSTALLED_APPS = [
    # '...'
    'django_minio_backend',  # https://github.com/theriverman/django-minio-backend
]
```

If you would like to enable on-start consistency check, install via `DjangoMinioBackendConfig`:
```python
INSTALLED_APPS = [
    # '...'
    'django_minio_backend.apps.DjangoMinioBackendConfig',  # https://github.com/theriverman/django-minio-backend
]
``` 
Then add the following parameter to your settings file:
```python
MINIO_CONSISTENCY_CHECK_ON_START = True
```

**Note:** The on-start consistency check equals to manually calling `python manage.py initialize_buckets`. <br>
It is recommended to turn *off* this feature during development by setting `MINIO_CONSISTENCY_CHECK_ON_START` to `False`, 
because this operation can noticeably slow down Django's boot time when many buckets are configured.

3. Add the following parameters to your `settings.py`:
```python
from datetime import timedelta
from typing import List, Tuple

MINIO_ENDPOINT = 'minio.your-company.co.uk'
MINIO_EXTERNAL_ENDPOINT = "external-minio.your-company.co.uk"  # Default is same as MINIO_ENDPOINT
MINIO_EXTERNAL_ENDPOINT_USE_HTTPS = True  # Default is same as MINIO_USE_HTTPS
MINIO_REGION = 'us-east-1'  # Default is set to None
MINIO_ACCESS_KEY = 'yourMinioAccessKey'
MINIO_SECRET_KEY = 'yourVeryS3cr3tP4ssw0rd'
MINIO_USE_HTTPS = True
MINIO_URL_EXPIRY_HOURS = timedelta(days=1)  # Default is 7 days (longest) if not defined
MINIO_CONSISTENCY_CHECK_ON_START = True
MINIO_PRIVATE_BUCKETS = [
    'django-backend-dev-private',
]
MINIO_PUBLIC_BUCKETS = [
    'django-backend-dev-public',
]
MINIO_POLICY_HOOKS: List[Tuple[str, dict]] = []
# MINIO_MEDIA_FILES_BUCKET = 'my-media-files-bucket'  # replacement for MEDIA_ROOT
# MINIO_STATIC_FILES_BUCKET = 'my-static-files-bucket'  # replacement for STATIC_ROOT
MINIO_BUCKET_CHECK_ON_SAVE = True  # Default: True // Creates bucket if missing, then save

# Custom HTTP Client (OPTIONAL)
import os
import certifi
import urllib3
timeout = timedelta(minutes=5).seconds
ca_certs = os.environ.get('SSL_CERT_FILE') or certifi.where()
MINIO_HTTP_CLIENT: urllib3.poolmanager.PoolManager = urllib3.PoolManager(
    timeout=urllib3.util.Timeout(connect=timeout, read=timeout),
    maxsize=10,
    cert_reqs='CERT_REQUIRED',
    ca_certs=ca_certs,
    retries=urllib3.Retry(
        total=5,
        backoff_factor=0.2,
        status_forcelist=[500, 502, 503, 504]
    )
)
```

4. Implement your own Attachment handler and integrate **django-minio-backend**:
```python
from django.db import models
from django_minio_backend import MinioBackend, iso_date_prefix

class PrivateAttachment(models.Model):   
    file = models.FileField(verbose_name="Object Upload",
                            storage=MinioBackend(bucket_name='django-backend-dev-private'),
                            upload_to=iso_date_prefix)
```

5. Initialize the buckets & set their public policy (OPTIONAL):<br>
This `django-admin` command creates both the private and public buckets in case one of them does not exists,
and sets the *public* bucket's privacy policy from `private`(default) to `public`.<br>
```bash
python manage.py initialize_buckets
```

Code reference: [initialize_buckets.py](django_minio_backend/management/commands/initialize_buckets.py).

### Static Files Support
**django-minio-backend** allows serving static files from MinIO.
To learn more about Django static files, see [Managing static files](https://docs.djangoproject.com/en/3.2/howto/static-files/), and [STATICFILES_STORAGE](https://docs.djangoproject.com/en/3.2/ref/settings/#staticfiles-storage).

To enable static files support, update your `settings.py`:
```python
STATICFILES_STORAGE = 'django_minio_backend.models.MinioBackendStatic'
MINIO_STATIC_FILES_BUCKET = 'my-static-files-bucket'  # replacement for STATIC_ROOT
# Add the value of MINIO_STATIC_FILES_BUCKET to one of the pre-configured bucket lists. eg.:
# MINIO_PRIVATE_BUCKETS.append(MINIO_STATIC_FILES_BUCKET)
# MINIO_PUBLIC_BUCKETS.append(MINIO_STATIC_FILES_BUCKET)
```

The value of `STATIC_URL` is ignored, but it must be defined otherwise Django will throw an error.

**IMPORTANT**<br>
The value set in `MINIO_STATIC_FILES_BUCKET` must be added either to `MINIO_PRIVATE_BUCKETS` or `MINIO_PUBLIC_BUCKETS`,
otherwise **django-minio-backend** will raise an exception. This setting determines the privacy of generated file URLs which can be unsigned public or signed private.  

**Note:** If `MINIO_STATIC_FILES_BUCKET` is not set, the default value (`auto-generated-bucket-static-files`) will be used. Policy setting for default buckets is **private**.

### Default File Storage Support
**django-minio-backend** can be configured as a default file storage.
To learn more, see [DEFAULT_FILE_STORAGE](https://docs.djangoproject.com/en/3.2/ref/settings/#default-file-storage).

To configure **django-minio-backend** as the default file storage, update your `settings.py`:
```python
DEFAULT_FILE_STORAGE = 'django_minio_backend.models.MinioBackend'
MINIO_MEDIA_FILES_BUCKET = 'my-media-files-bucket'  # replacement for MEDIA_ROOT
# Add the value of MINIO_STATIC_FILES_BUCKET to one of the pre-configured bucket lists. eg.:
# MINIO_PRIVATE_BUCKETS.append(MINIO_STATIC_FILES_BUCKET)
# MINIO_PUBLIC_BUCKETS.append(MINIO_STATIC_FILES_BUCKET)
```

The value of `MEDIA_URL` is ignored, but it must be defined otherwise Django will throw an error.

**IMPORTANT**<br>
The value set in `MINIO_MEDIA_FILES_BUCKET` must be added either to `MINIO_PRIVATE_BUCKETS` or `MINIO_PUBLIC_BUCKETS`,
otherwise **django-minio-backend** will raise an exception. This setting determines the privacy of generated file URLs which can be unsigned public or signed private.

**Note:** If `MINIO_MEDIA_FILES_BUCKET` is not set, the default value (`auto-generated-bucket-media-files`) will be used. Policy setting for default buckets is **private**.

### Health Check
To check the connection link between Django and MinIO, use the provided `MinioBackend.is_minio_available()` method.<br>
It returns a `MinioServerStatus` instance which can be quickly evaluated as boolean.<br>

**Example:**
```python
from django_minio_backend import MinioBackend

minio_available = MinioBackend().is_minio_available()  # An empty string is fine this time
if minio_available:
    print("OK")
else:
    print("NOK")
    print(minio_available.details)
```

### Policy Hooks
You can configure **django-minio-backend** to automatically execute a set of pre-defined policy hooks. <br>
Policy hooks can be defined in `settings.py` by adding `MINIO_POLICY_HOOKS` which must be a list of tuples. <br>
Policy hooks are automatically picked up by the `initialize_buckets` management command.

For an exemplary policy, see the implementation of `def set_bucket_to_public(self)` 
in [django_minio_backend/models.py](django_minio_backend/models.py) or the contents 
of [examples/policy_hook.example.py](examples/policy_hook.example.py).

### Consistency Check On Start
When enabled, the `initialize_buckets` management command gets called automatically when Django starts. <br>
This command connects to the configured minIO server and checks if all buckets defined in `settings.py`. <br>
In case a bucket is missing or its configuration differs, it gets created and corrected.

### Reference Implementation
For a reference implementation, see [Examples](examples).

## Behaviour
The following list summarises the key characteristics of **django-minio-backend**:
  * Bucket existence is **not** checked on a save by default.
    To enable this guard, set `MINIO_BUCKET_CHECK_ON_SAVE = True` in your `settings.py`.
  * Bucket existences are **not** checked on Django start by default.
    To enable this guard, set `MINIO_CONSISTENCY_CHECK_ON_START = True` in your `settings.py`.
  * Many configuration errors are validated through `AppConfig` but not every error can be captured there.
  * Files with the same name in the same bucket are **not** replaced on save by default. Django will store the newer file with an altered file name
    To allow replacing existing files, pass the `replace_existing=True` kwarg to `MinioBackend`.
    For example: `image = models.ImageField(storage=MinioBackend(bucket_name='images-public', replace_existing=True))`
  * Depending on your configuration, **django-minio-backend** may communicate over two kind of interfaces: internal and external.
    If your `settings.py` defines a different value for `MINIO_ENDPOINT` and `MINIO_EXTERNAL_ENDPOINT`, then the former will be used for internal communication
    between Django and MinIO, and the latter for generating URLs for users. This behaviour optimises the network communication.
    See **Networking** below for a thorough explanation
  * The uploaded object's content-type is guessed during save. If `mimetypes.guess_type` fails to determine the correct content-type, then it falls back to `application/octet-stream`.

## Networking and Docker
If your Django application is running on a shared host with your MinIO instance, you should consider using the `MINIO_EXTERNAL_ENDPOINT` and `MINIO_EXTERNAL_ENDPOINT_USE_HTTPS` parameters.
This way most traffic will happen internally between Django and MinIO. The external endpoint parameters are required for external pre-signed URL generation.

If your Django application and MinIO instance are running on different hosts, you can omit the `MINIO_EXTERNAL_ENDPOINT` and `MINIO_EXTERNAL_ENDPOINT_USE_HTTPS` parameters, 
and **django-minio-backend** will default to the value of `MINIO_ENDPOINT`.

Setting up and configuring custom networks in Docker is not in the scope of this document. <br>
To learn more about Docker networking, see [Networking overview](https://docs.docker.com/network/) and [Networking in Compose](https://docs.docker.com/compose/networking/).

See [README.Docker.md](README.Docker.md) for a real-life Docker Compose demonstration.

## Compatibility
  * Django 2.2 or later
  * Python 3.8.0 or later
  * MinIO SDK 7.0.2 or later

## Contribution
Please find the details in [CONTRIBUTE.md](CONTRIBUTE.md)

## Copyright
  * theriverman/django-minio-backend licensed under the MIT License
  * minio/minio-py is licensed under the Apache License 2.0

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/theriverman/django-minio-backend",
    "name": "django-minio-backend",
    "maintainer": null,
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": null,
    "keywords": null,
    "author": "Kristof Daja (theriverman)",
    "author_email": "kristof@daja.hu",
    "download_url": "https://files.pythonhosted.org/packages/89/cb/e5648967e2626adcf68edc6c6507a14616115086a2bccc0401aab9013864/django-minio-backend-3.6.0.tar.gz",
    "platform": null,
    "description": "[![django-app-tests](https://github.com/theriverman/django-minio-backend/actions/workflows/django-tests.yml/badge.svg)](https://github.com/theriverman/django-minio-backend/actions/workflows/django-tests.yml)\n[![publish-py-dist-to-pypi](https://github.com/theriverman/django-minio-backend/actions/workflows/publish-to-pypi.yml/badge.svg)](https://github.com/theriverman/django-minio-backend/actions/workflows/publish-to-pypi.yml)\n[![PYPI](https://img.shields.io/pypi/v/django-minio-backend.svg)](https://pypi.python.org/pypi/django-minio-backend)\n\n# django-minio-backend\nThe **django-minio-backend** provides a wrapper around the \n[MinIO Python SDK](https://docs.min.io/docs/python-client-quickstart-guide.html).\nSee [minio/minio-py](https://github.com/minio/minio-py) for the source.\n\n## Integration\n1. Get and install the package:\n```bash\npip install django-minio-backend\n```\n\n2. Add `django_minio_backend` to `INSTALLED_APPS`:\n```python\nINSTALLED_APPS = [\n    # '...'\n    'django_minio_backend',  # https://github.com/theriverman/django-minio-backend\n]\n```\n\nIf you would like to enable on-start consistency check, install via `DjangoMinioBackendConfig`:\n```python\nINSTALLED_APPS = [\n    # '...'\n    'django_minio_backend.apps.DjangoMinioBackendConfig',  # https://github.com/theriverman/django-minio-backend\n]\n``` \nThen add the following parameter to your settings file:\n```python\nMINIO_CONSISTENCY_CHECK_ON_START = True\n```\n\n**Note:** The on-start consistency check equals to manually calling `python manage.py initialize_buckets`. <br>\nIt is recommended to turn *off* this feature during development by setting `MINIO_CONSISTENCY_CHECK_ON_START` to `False`, \nbecause this operation can noticeably slow down Django's boot time when many buckets are configured.\n\n3. Add the following parameters to your `settings.py`:\n```python\nfrom datetime import timedelta\nfrom typing import List, Tuple\n\nMINIO_ENDPOINT = 'minio.your-company.co.uk'\nMINIO_EXTERNAL_ENDPOINT = \"external-minio.your-company.co.uk\"  # Default is same as MINIO_ENDPOINT\nMINIO_EXTERNAL_ENDPOINT_USE_HTTPS = True  # Default is same as MINIO_USE_HTTPS\nMINIO_REGION = 'us-east-1'  # Default is set to None\nMINIO_ACCESS_KEY = 'yourMinioAccessKey'\nMINIO_SECRET_KEY = 'yourVeryS3cr3tP4ssw0rd'\nMINIO_USE_HTTPS = True\nMINIO_URL_EXPIRY_HOURS = timedelta(days=1)  # Default is 7 days (longest) if not defined\nMINIO_CONSISTENCY_CHECK_ON_START = True\nMINIO_PRIVATE_BUCKETS = [\n    'django-backend-dev-private',\n]\nMINIO_PUBLIC_BUCKETS = [\n    'django-backend-dev-public',\n]\nMINIO_POLICY_HOOKS: List[Tuple[str, dict]] = []\n# MINIO_MEDIA_FILES_BUCKET = 'my-media-files-bucket'  # replacement for MEDIA_ROOT\n# MINIO_STATIC_FILES_BUCKET = 'my-static-files-bucket'  # replacement for STATIC_ROOT\nMINIO_BUCKET_CHECK_ON_SAVE = True  # Default: True // Creates bucket if missing, then save\n\n# Custom HTTP Client (OPTIONAL)\nimport os\nimport certifi\nimport urllib3\ntimeout = timedelta(minutes=5).seconds\nca_certs = os.environ.get('SSL_CERT_FILE') or certifi.where()\nMINIO_HTTP_CLIENT: urllib3.poolmanager.PoolManager = urllib3.PoolManager(\n    timeout=urllib3.util.Timeout(connect=timeout, read=timeout),\n    maxsize=10,\n    cert_reqs='CERT_REQUIRED',\n    ca_certs=ca_certs,\n    retries=urllib3.Retry(\n        total=5,\n        backoff_factor=0.2,\n        status_forcelist=[500, 502, 503, 504]\n    )\n)\n```\n\n4. Implement your own Attachment handler and integrate **django-minio-backend**:\n```python\nfrom django.db import models\nfrom django_minio_backend import MinioBackend, iso_date_prefix\n\nclass PrivateAttachment(models.Model):   \n    file = models.FileField(verbose_name=\"Object Upload\",\n                            storage=MinioBackend(bucket_name='django-backend-dev-private'),\n                            upload_to=iso_date_prefix)\n```\n\n5. Initialize the buckets & set their public policy (OPTIONAL):<br>\nThis `django-admin` command creates both the private and public buckets in case one of them does not exists,\nand sets the *public* bucket's privacy policy from `private`(default) to `public`.<br>\n```bash\npython manage.py initialize_buckets\n```\n\nCode reference: [initialize_buckets.py](django_minio_backend/management/commands/initialize_buckets.py).\n\n### Static Files Support\n**django-minio-backend** allows serving static files from MinIO.\nTo learn more about Django static files, see [Managing static files](https://docs.djangoproject.com/en/3.2/howto/static-files/), and [STATICFILES_STORAGE](https://docs.djangoproject.com/en/3.2/ref/settings/#staticfiles-storage).\n\nTo enable static files support, update your `settings.py`:\n```python\nSTATICFILES_STORAGE = 'django_minio_backend.models.MinioBackendStatic'\nMINIO_STATIC_FILES_BUCKET = 'my-static-files-bucket'  # replacement for STATIC_ROOT\n# Add the value of MINIO_STATIC_FILES_BUCKET to one of the pre-configured bucket lists. eg.:\n# MINIO_PRIVATE_BUCKETS.append(MINIO_STATIC_FILES_BUCKET)\n# MINIO_PUBLIC_BUCKETS.append(MINIO_STATIC_FILES_BUCKET)\n```\n\nThe value of `STATIC_URL` is ignored, but it must be defined otherwise Django will throw an error.\n\n**IMPORTANT**<br>\nThe value set in `MINIO_STATIC_FILES_BUCKET` must be added either to `MINIO_PRIVATE_BUCKETS` or `MINIO_PUBLIC_BUCKETS`,\notherwise **django-minio-backend** will raise an exception. This setting determines the privacy of generated file URLs which can be unsigned public or signed private.  \n\n**Note:** If `MINIO_STATIC_FILES_BUCKET` is not set, the default value (`auto-generated-bucket-static-files`) will be used. Policy setting for default buckets is **private**.\n\n### Default File Storage Support\n**django-minio-backend** can be configured as a default file storage.\nTo learn more, see [DEFAULT_FILE_STORAGE](https://docs.djangoproject.com/en/3.2/ref/settings/#default-file-storage).\n\nTo configure **django-minio-backend** as the default file storage, update your `settings.py`:\n```python\nDEFAULT_FILE_STORAGE = 'django_minio_backend.models.MinioBackend'\nMINIO_MEDIA_FILES_BUCKET = 'my-media-files-bucket'  # replacement for MEDIA_ROOT\n# Add the value of MINIO_STATIC_FILES_BUCKET to one of the pre-configured bucket lists. eg.:\n# MINIO_PRIVATE_BUCKETS.append(MINIO_STATIC_FILES_BUCKET)\n# MINIO_PUBLIC_BUCKETS.append(MINIO_STATIC_FILES_BUCKET)\n```\n\nThe value of `MEDIA_URL` is ignored, but it must be defined otherwise Django will throw an error.\n\n**IMPORTANT**<br>\nThe value set in `MINIO_MEDIA_FILES_BUCKET` must be added either to `MINIO_PRIVATE_BUCKETS` or `MINIO_PUBLIC_BUCKETS`,\notherwise **django-minio-backend** will raise an exception. This setting determines the privacy of generated file URLs which can be unsigned public or signed private.\n\n**Note:** If `MINIO_MEDIA_FILES_BUCKET` is not set, the default value (`auto-generated-bucket-media-files`) will be used. Policy setting for default buckets is **private**.\n\n### Health Check\nTo check the connection link between Django and MinIO, use the provided `MinioBackend.is_minio_available()` method.<br>\nIt returns a `MinioServerStatus` instance which can be quickly evaluated as boolean.<br>\n\n**Example:**\n```python\nfrom django_minio_backend import MinioBackend\n\nminio_available = MinioBackend().is_minio_available()  # An empty string is fine this time\nif minio_available:\n    print(\"OK\")\nelse:\n    print(\"NOK\")\n    print(minio_available.details)\n```\n\n### Policy Hooks\nYou can configure **django-minio-backend** to automatically execute a set of pre-defined policy hooks. <br>\nPolicy hooks can be defined in `settings.py` by adding `MINIO_POLICY_HOOKS` which must be a list of tuples. <br>\nPolicy hooks are automatically picked up by the `initialize_buckets` management command.\n\nFor an exemplary policy, see the implementation of `def set_bucket_to_public(self)` \nin [django_minio_backend/models.py](django_minio_backend/models.py) or the contents \nof [examples/policy_hook.example.py](examples/policy_hook.example.py).\n\n### Consistency Check On Start\nWhen enabled, the `initialize_buckets` management command gets called automatically when Django starts. <br>\nThis command connects to the configured minIO server and checks if all buckets defined in `settings.py`. <br>\nIn case a bucket is missing or its configuration differs, it gets created and corrected.\n\n### Reference Implementation\nFor a reference implementation, see [Examples](examples).\n\n## Behaviour\nThe following list summarises the key characteristics of **django-minio-backend**:\n  * Bucket existence is **not** checked on a save by default.\n    To enable this guard, set `MINIO_BUCKET_CHECK_ON_SAVE = True` in your `settings.py`.\n  * Bucket existences are **not** checked on Django start by default.\n    To enable this guard, set `MINIO_CONSISTENCY_CHECK_ON_START = True` in your `settings.py`.\n  * Many configuration errors are validated through `AppConfig` but not every error can be captured there.\n  * Files with the same name in the same bucket are **not** replaced on save by default. Django will store the newer file with an altered file name\n    To allow replacing existing files, pass the `replace_existing=True` kwarg to `MinioBackend`.\n    For example: `image = models.ImageField(storage=MinioBackend(bucket_name='images-public', replace_existing=True))`\n  * Depending on your configuration, **django-minio-backend** may communicate over two kind of interfaces: internal and external.\n    If your `settings.py` defines a different value for `MINIO_ENDPOINT` and `MINIO_EXTERNAL_ENDPOINT`, then the former will be used for internal communication\n    between Django and MinIO, and the latter for generating URLs for users. This behaviour optimises the network communication.\n    See **Networking** below for a thorough explanation\n  * The uploaded object's content-type is guessed during save. If `mimetypes.guess_type` fails to determine the correct content-type, then it falls back to `application/octet-stream`.\n\n## Networking and Docker\nIf your Django application is running on a shared host with your MinIO instance, you should consider using the `MINIO_EXTERNAL_ENDPOINT` and `MINIO_EXTERNAL_ENDPOINT_USE_HTTPS` parameters.\nThis way most traffic will happen internally between Django and MinIO. The external endpoint parameters are required for external pre-signed URL generation.\n\nIf your Django application and MinIO instance are running on different hosts, you can omit the `MINIO_EXTERNAL_ENDPOINT` and `MINIO_EXTERNAL_ENDPOINT_USE_HTTPS` parameters, \nand **django-minio-backend** will default to the value of `MINIO_ENDPOINT`.\n\nSetting up and configuring custom networks in Docker is not in the scope of this document. <br>\nTo learn more about Docker networking, see [Networking overview](https://docs.docker.com/network/) and [Networking in Compose](https://docs.docker.com/compose/networking/).\n\nSee [README.Docker.md](README.Docker.md) for a real-life Docker Compose demonstration.\n\n## Compatibility\n  * Django 2.2 or later\n  * Python 3.8.0 or later\n  * MinIO SDK 7.0.2 or later\n\n## Contribution\nPlease find the details in [CONTRIBUTE.md](CONTRIBUTE.md)\n\n## Copyright\n  * theriverman/django-minio-backend licensed under the MIT License\n  * minio/minio-py is licensed under the Apache License 2.0\n",
    "bugtrack_url": null,
    "license": "MIT License | Copyright (c) 2024 Kristof Daja",
    "summary": "The django-minio-backend provides a wrapper around the MinIO Python Library.",
    "version": "3.6.0",
    "project_urls": {
        "Homepage": "https://github.com/theriverman/django-minio-backend"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "5fee6e0e44bba5bff07a89c0e23965de790d21c36a5cb9ad2d7f7ce812e5530a",
                "md5": "60a00cf36b6cf75813a7a64283d0c141",
                "sha256": "2a507713acdc9c9d7fa793dbf6858c43ec1d68905fbf17371c721dd58970795b"
            },
            "downloads": -1,
            "filename": "django_minio_backend-3.6.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "60a00cf36b6cf75813a7a64283d0c141",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 26116,
            "upload_time": "2024-03-24T11:34:52",
            "upload_time_iso_8601": "2024-03-24T11:34:52.151341Z",
            "url": "https://files.pythonhosted.org/packages/5f/ee/6e0e44bba5bff07a89c0e23965de790d21c36a5cb9ad2d7f7ce812e5530a/django_minio_backend-3.6.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "89cbe5648967e2626adcf68edc6c6507a14616115086a2bccc0401aab9013864",
                "md5": "a48c553aeb123653302823419fdb803a",
                "sha256": "d25b0a7bb837873178e71a45e4e31049f5c724a6a55c6cf892e34ebeb530bb5a"
            },
            "downloads": -1,
            "filename": "django-minio-backend-3.6.0.tar.gz",
            "has_sig": false,
            "md5_digest": "a48c553aeb123653302823419fdb803a",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 24674,
            "upload_time": "2024-03-24T11:34:53",
            "upload_time_iso_8601": "2024-03-24T11:34:53.929569Z",
            "url": "https://files.pythonhosted.org/packages/89/cb/e5648967e2626adcf68edc6c6507a14616115086a2bccc0401aab9013864/django-minio-backend-3.6.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-03-24 11:34:53",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "theriverman",
    "github_project": "django-minio-backend",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [
        {
            "name": "Django",
            "specs": [
                [
                    ">=",
                    "3.2"
                ]
            ]
        },
        {
            "name": "minio",
            "specs": [
                [
                    ">=",
                    "7.0.2"
                ]
            ]
        },
        {
            "name": "Pillow",
            "specs": []
        },
        {
            "name": "setuptools",
            "specs": []
        }
    ],
    "lcname": "django-minio-backend"
}
        
Elapsed time: 0.18977s