Importa archivos desde Supabase en Python de forma eficiente
Supabase almacena los objetos en almacenamiento de objetos y sus metadatos en PostgreSQL, lo que lo hace ideal para gestionar archivos grandes, recursos y subidas de usuarios. En este DevTip mostramos cómo importar archivos desde Supabase con Python, con ejemplos prácticos y mejores prácticas para manejar tanto archivos individuales como directorios.
Introducción al almacenamiento de Supabase
Supabase Storage ofrece una forma sencilla pero potente de almacenar y servir archivos grandes. Al organizar los archivos en buckets, de forma muy similar a AWS S3, resulta fácil gestionar los recursos de la aplicación, las subidas de usuarios y otro contenido basado en archivos. Este enfoque garantiza un almacenamiento eficiente y una recuperación rápida cuando se necesita.
Panorama del ecosistema de Python para importar archivos
Python cuenta con un ecosistema rico para el manejo de archivos y las interacciones con API. El SDK oficial de Python de código abierto para Supabase simplifica el proceso de conectarse a tus proyectos de Supabase y gestionar los buckets de almacenamiento. Esta guía aprovecha ese SDK para agilizar las importaciones de archivos en tus aplicaciones de Python.
Guía paso a paso para configurar la integración de Supabase y Python
1. Instala las bibliotecas de Python necesarias
Antes de empezar, asegúrate de estar usando Python 3.9 o superior. Instala el cliente oficial de Python para Supabase con pip:
pip install supabase==2.13.0
2. Configura las credenciales de acceso y los permisos en Supabase
Accede a la configuración de tu proyecto de Supabase para localizar tu URL de API y tu clave de API
en la sección «API». Usa la clave JWT anon heredada del proyecto y autentica a un usuario cuyas
políticas de almacenamiento permitan las operaciones que se describen a continuación. El SDK 2.13.0
fijado valida las claves del proyecto como JWT, por lo que no acepta el formato de clave más
reciente sb_publishable_…. Inicializa el cliente antes de usar cualquier ejemplo de bucket:
import os
import tempfile
from pathlib import Path
from storage3.exceptions import StorageApiError
from supabase import create_client, Client
supabase: Client = create_client(
os.environ['SUPABASE_URL'], os.environ['SUPABASE_PROJECT_KEY']
)
supabase.auth.sign_in_with_password({
'email': os.environ['SUPABASE_USER_EMAIL'],
'password': os.environ['SUPABASE_USER_PASSWORD'],
})
Crea un bucket privado en el panel de control, o usa el siguiente ejemplo opcional de aprovisionamiento solo con una identidad que tenga permiso para crear buckets. Los usuarios de descarga habituales no necesitan ese permiso:
supabase.storage.create_bucket('my-bucket',
options={
"public": False,
"allowed_mime_types": ["image/png", "image/jpeg"],
"file_size_limit": 1024000, # Limit file size to ~1 MB
}
)
Estas opciones restringen los tipos MIME declarados y los tamaños de subida; no analizan el contenido. Las políticas de acceso al almacenamiento determinan qué usuarios autenticados pueden listar y descargar objetos.
3. Establece una conexión con tu bucket de Supabase
Reutiliza el cliente supabase autenticado que inicializaste arriba para las siguientes descargas.
Cómo importar archivos desde Supabase con Python
Importar un solo archivo
La siguiente función muestra cómo descargar un solo archivo de un bucket específico. Recupera el archivo de Supabase y lo escribe en un destino local:
def download_file(bucket_name: str, file_path: str, destination: str) -> bool:
try:
response = supabase.storage.from_(bucket_name).download(file_path)
target = Path(destination)
target.parent.mkdir(parents=True, exist_ok=True)
# Replace the destination only after a complete download and local write.
with tempfile.TemporaryDirectory(dir=target.parent) as staging:
temporary = Path(staging) / 'download'
temporary.write_bytes(response)
os.replace(temporary, target)
print(f"File downloaded successfully to {destination}")
return True
except StorageApiError as e:
print(f"Storage error: {e}")
except Exception as e:
print(f"Error downloading file: {str(e)}")
return False
# Example usage
download_file('my-bucket', 'folder/image.jpg', 'local/image.jpg')
Esta llamada síncrona del SDK mantiene en memoria los bytes descargados. Úsala para archivos que quepan en la memoria disponible; la ejecución asíncrona por sí sola no la convierte en una descarga por streaming. Si la descarga o la escritura falla, el destino existente queda sin cambios.
Importar varios archivos desde un directorio
La siguiente función recorre paginando los archivos directos de una sola carpeta remota y omite las subcarpetas. Guarda esos archivos directamente en un directorio de destino local de confianza. No replica el árbol de directorios remoto y las claves remotas nunca se interpretan como rutas de directorios locales:
def import_directory(bucket_name: str, prefix: str = "", destination: str = "downloads") -> None:
try:
root = Path(destination).resolve()
prefix = prefix.rstrip('/')
offset = 0
page_size = 100
while True:
files = supabase.storage.from_(bucket_name).list(path=prefix, options={
'limit': page_size, 'offset': offset,
'sortBy': {'column': 'name', 'order': 'asc'},
})
for file in files:
if file.get('id') is None:
continue # Folder placeholders have no object ID.
name = file['name']
if not name or name in {'.', '..'} or any(char in name for char in '/\\:\0'):
raise ValueError('Unsafe object name in listing')
file_path = f'{prefix}/{name}' if prefix else name
if not download_file(bucket_name, file_path, str(root / name)):
raise RuntimeError('Import stopped after a failed download')
if len(files) < page_size:
break
offset += page_size
except StorageApiError as e:
print(f"Storage error: {e}")
except Exception as e:
print(f"Error importing directory: {str(e)}")
# Example usage
import_directory('my-bucket', 'images/')
Limitaciones y consideraciones de almacenamiento
- Los límites de tamaño de archivo y las cuotas de almacenamiento dependen del plan y de la configuración del proyecto. Consulta la documentación de Supabase sobre límites de archivos.
- Mantén las descargas dentro del presupuesto de memoria de este ejemplo. Usa una concurrencia acotada y gestiona las respuestas de limitación de velocidad cuando construyas un importador más grande.
- La paginación por offset supone que la carpeta remota permanece estable durante el listado. Los cambios concurrentes pueden provocar que se omitan o se repitan entradas.
Autenticación y seguridad
Antes de realizar operaciones de almacenamiento, autentica siempre a tus usuarios. Por ejemplo, inicia sesión con el email y la contraseña de un usuario para garantizar que las operaciones posteriores se realicen en un contexto seguro:
# Authenticate the user prior to executing storage operations
user = supabase.auth.sign_in_with_password({
"email": os.environ['SUPABASE_USER_EMAIL'],
"password": os.environ['SUPABASE_USER_PASSWORD']
})
# Proceed with storage operations using the authenticated context
response = supabase.storage.from_("private-bucket").download("file.txt")
Recuerda evitar codificar credenciales sensibles directamente en el código; en su lugar, usa variables de entorno o archivos de configuración seguros.
Mejores prácticas para importar archivos desde Supabase
- Usa una autenticación adecuada: asegúrate de que el usuario esté autenticado antes de iniciar operaciones de almacenamiento.
- Maneja las excepciones de forma específica: usa
StorageApiErrorpara detectar y gestionar con precisión los errores de almacenamiento de archivos. - Configura las políticas del bucket: establece controles de acceso estrictos y tipos MIME permitidos para proteger tus archivos.
- Valida los tipos y tamaños de archivo: apóyate en la configuración del bucket para aplicar restricciones del lado del servidor.
- Protege tus credenciales: guarda las claves de API y los secretos en variables de entorno en lugar de incrustarlos en el código.
Recursos adicionales para optimizar los flujos de trabajo con Supabase y Python
- Documentación de Supabase Storage
- Documentación del SDK de Python de Supabase
- Guía de control de acceso al almacenamiento
Conclusión
Importar archivos desde Supabase en Python es sencillo si cuentas con la configuración y las medidas de seguridad adecuadas. El SDK oficial de Python para Supabase ofrece una interfaz robusta para gestionar tanto descargas de archivos individuales como importaciones masivas, manteniendo protocolos de acceso seguros.
Para un procesamiento de archivos avanzado o una mayor automatización, considera explorar el SDK de Python de Transloadit para obtener soluciones potentes de gestión de archivos.
