Как создать предварительно подписанные URL-адреса MinIO, доступные для браузера, из серверной части FastAPI, работающей Python

Программы на Python
Ответить
Anonymous
 Как создать предварительно подписанные URL-адреса MinIO, доступные для браузера, из серверной части FastAPI, работающей

Сообщение Anonymous »

Название: FastAPI + MinIO в Docker Compose: как создать предварительно подписанные URL-адреса, доступные за пределами Docker?

Сводка проблемы
Я использую серверную часть FastAPI и сервер MinIO с помощью Docker Compose. Бэкэнд подключается к MinIO через имя службы Docker (

Код: Выделить всё

minio:9000
).
Когда я генерирую предварительно подписанный URL-адрес для файла с помощью MinIO Python SDK, URL-адрес выглядит следующим образом:

Код: Выделить всё

http://minio:9000/bucket/file...

{
"id": 2,
"filename": "iva_2024.pdf",
"size_mb": 0.65,
"size_kb": 667.02,
"upload_date": "2025-05-09T13:51:43",
"download_url": "http://minio:9000/b2caixa-files/Company_1/IVA_AUTOMATICO_MAIS2.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=b2caixa%2F20250509%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20250509T135222Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=aca2cae38fb705d6160519a397ab51fe36b19684e03b3d44aa65f1a3e00277a5"
}

Этот URL-адрес работает внутри сети Docker (например, при доступе из пользовательского интерфейса MINIO в /docs), но не работает во внешних инструментах, таких как мой браузер или Postman, поскольку minio неразрешим вне сети Docker. Внешне я получаю сообщение об ошибке типа:

Код: Выделить всё

getaddrinfo ENOTFOUND minio
Чего я хочу
Я хочу, чтобы серверная часть генерировала предварительно подписанные URL-адреса, доступные как в браузере, так и во внешних инструментах. В частности, URL-адреса должны:
  • Использовать localhost:9000 или другой общедоступный домен.
  • Разрешить интерфейсу загружать файлы через простую конечную точку (например, щелкнув значок).
Docker Compose Snippet

Код: Выделить всё

services:
backend:
build: .
environment:
- MINIO_ENDPOINT=minio:9000
depends_on:
- minio

minio:
image: minio/minio
ports:
- "9000:9000"
Фрагмент кода

Код: Выделить всё

from minio import Minio
from datetime import timedelta
import os

class MinioClient:
def __init__(self):
self.client = Minio(
endpoint=os.getenv("MINIO_ENDPOINT", "minio:9000"),
access_key=os.getenv("MINIO_ROOT_USER", "..."),
secret_key=os.getenv("MINIO_ROOT_PASSWORD", "..."),
secure=False
)
self.bucket_name = os.getenv("MINIO_BUCKET", "b2caixa-files")

def get_file_url(self, object_name: str) -> str:
url = self.client.presigned_get_object(
bucket_name=self.bucket_name,
object_name=object_name,
expires=timedelta(seconds=3600)
)
# Replace Docker-internal hostname with browser-accessible one
url = url.replace("minio:9000", "localhost:9000")
return url
Что я пробовал
  • Установка MINIO_ENDPOINT=localhost:9000 в серверной среде, но это приводит к сбою подключения серверной части к MinIO (поскольку localhost внутри контейнера относится к самому контейнеру, а не к хост-компьютеру).
  • Использование имени службы Docker (

    Код: Выделить всё

    minio:9000
    ), который работает для связи между серверной частью и MinIO, но приводит к созданию URL-адресов, недоступных за пределами Docker.


Подробнее здесь: https://stackoverflow.com/questions/796 ... api-backen
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»