Easy Python upload manager for images, files and media. Python fork of robsonvleite/uploader (PHP).
Project description
Uploader (Python)
Port em Python do pacote PHP coffeecode/uploader
de Robson V. Leite. Mantem o comportamento original (validacao por mime/extensao,
diretorios YYYY/MM, slug, redimensionamento de imagens) com uma API
framework-agnostica baseada em UploadedFile — aceita path em disco ou
stream em memoria, com adapters prontos para Flask e FastAPI.
Python port of the PHP package coffeecode/uploader by Robson V. Leite. Same behavior (mime/extension validation, year/month directories, slugged filenames, image resizing) with a framework-agnostic
UploadedFileAPI: accepts a filesystem path or an in-memory stream, with built-in adapters for Flask and FastAPI.
Destaques
- Upload simples de imagens, arquivos e midias
UploadedFile: abstracao unica para path em disco ou stream- Adapters:
from_flask,from_fastapi,from_stream,from_path,from_dict(compat com PHP$_FILES) - Gestao de diretorios com esquema de datas (
YYYY/MM) - Validacao por mime-type e extensao
- Redimensionamento e qualidade de imagem (substitui
ext-gdpor Pillow)
Instalacao
pip install coffeecode-uploader
Requer Python >= 3.9 e Pillow >= 10.
Uso
Flask
from flask import Flask, request
from coffeecode_uploader import Image, UploadedFile, UploaderException
@app.post("/avatar")
def avatar():
try:
upload = UploadedFile.from_flask(request.files["image"])
path = Image("uploads", "images").upload(upload, request.form["name"])
return {"path": path}
except UploaderException as e:
return {"error": str(e)}, 400
FastAPI
from fastapi import FastAPI, File, UploadFile, HTTPException
from coffeecode_uploader import Image, UploadedFile, UploaderException
app = FastAPI()
@app.post("/avatar")
async def avatar(name: str, image: UploadFile = File(...)):
try:
upload = UploadedFile.from_fastapi(image)
path = Image("uploads", "images").upload(upload, name)
return {"path": path}
except UploaderException as e:
raise HTTPException(400, str(e))
Stream em memoria
from io import BytesIO
from coffeecode_uploader import File, UploadedFile
upload = UploadedFile.from_stream(
BytesIO(pdf_bytes),
filename="report.pdf",
content_type="application/pdf",
)
path = File("uploads", "files").upload(upload, "Relatorio Mensal")
Path ja em disco
from coffeecode_uploader import File, UploadedFile
upload = UploadedFile.from_path("/tmp/report.pdf", content_type="application/pdf")
path = File("uploads", "files").upload(upload, "Relatorio")
Compat com $_FILES (PHP-style)
from coffeecode_uploader import File, UploadedFile
upload = UploadedFile.from_dict({
"name": "report.pdf",
"type": "application/pdf",
"tmp_name": "/tmp/upload.pdf",
})
path = File("uploads", "files").upload(upload, "Relatorio")
API
Construtores
Image(upload_dir, file_type_dir, month_year_path=True)
File(upload_dir, file_type_dir, month_year_path=True)
Media(upload_dir, file_type_dir, month_year_path=True)
Send(upload_dir, file_type_dir, allow_types, extensions, month_year_path=True)
upload(file: UploadedFile, name: str, ...)
Retorna a string com o caminho final relativo. Lanca UploaderException
quando o tipo MIME ou a extensao nao estao na lista permitida.
Image.upload(image, name, width=2000, quality=None)—qualityaceita{"jpg": 0..95, "png": 0..9}. Padrao:{"jpg": 75, "png": 5}. GIFs sao copiados sem reprocessamento (igual ao PHP).File.upload(file, name)Media.upload(media, name)Send.upload(file, name)
UploadedFile
| Metodo | Quando usar |
|---|---|
UploadedFile.from_flask(file_storage) |
request.files["x"] em Flask/Quart |
UploadedFile.from_fastapi(upload_file) |
UploadFile em FastAPI/Starlette |
UploadedFile.from_stream(stream, ...) |
BytesIO, S3 body, qualquer file-like binario |
UploadedFile.from_path(path, content_type) |
Arquivo ja em disco |
UploadedFile.from_dict({...}) |
Compat com $_FILES PHP |
.open() |
Context manager → file-like binario |
.save_to(dst) |
Copia para dst (preserva o source) |
.extension |
Extensao em lowercase a partir de filename |
Helpers
Cls.is_allowed()(aliasCls.isAllowed()) — lista de mime-types permitidos.Cls.is_extension()(aliasCls.isExtension()) — lista de extensoes permitidas.Uploader.multiple([...])— converte lista heterogenea (dict, FileStorage, UploadFile, UploadedFile) emlist[UploadedFile].
Migrar de v1.x
A v1 aceitava um dict no formato PHP $_FILES. Em v2 use UploadedFile:
# v1
file_dict = {"name": "x.pdf", "type": "application/pdf", "tmp_name": "/tmp/x"}
File("uploads", "files").upload(file_dict, "Doc")
# v2
upload = UploadedFile.from_dict(file_dict)
File("uploads", "files").upload(upload, "Doc")
Equivalencia com a versao PHP
| PHP | Python |
|---|---|
CoffeeCode\Uploader\Image |
coffeecode_uploader.Image |
CoffeeCode\Uploader\File |
coffeecode_uploader.File |
CoffeeCode\Uploader\Media |
coffeecode_uploader.Media |
CoffeeCode\Uploader\Send |
coffeecode_uploader.Send |
Exception |
UploaderException |
$_FILES['x'] |
UploadedFile.from_dict({...}) |
move_uploaded_file() |
UploadedFile.save_to() |
ext-gd |
Pillow |
monthYearPath |
month_year_path |
Creditos
- API e comportamento original: Robson V. Leite — coffeecode/uploader (MIT)
- Port Python: Kaue Leal
Licenca
MIT.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file coffeecode_uploader-2.0.0.tar.gz.
File metadata
- Download URL: coffeecode_uploader-2.0.0.tar.gz
- Upload date:
- Size: 14.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0c32e3dbcb4c2943c66193f13b536f5134630b2e8bc2dc239ceeca714fcb7907
|
|
| MD5 |
75cd6aaee3b0c74dbe31a4604a7e41bc
|
|
| BLAKE2b-256 |
222d9be631553852d3722e85e9f7a14732b2c955b67be53404488688c0a8c370
|
Provenance
The following attestation bundles were made for coffeecode_uploader-2.0.0.tar.gz:
Publisher:
release.yml on kauelima21/coffeecode-uploader
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
coffeecode_uploader-2.0.0.tar.gz -
Subject digest:
0c32e3dbcb4c2943c66193f13b536f5134630b2e8bc2dc239ceeca714fcb7907 - Sigstore transparency entry: 1414618976
- Sigstore integration time:
-
Permalink:
kauelima21/coffeecode-uploader@78808819e309bf3cf658444460e0999d947a0a5c -
Branch / Tag:
refs/tags/v2.0.0 - Owner: https://github.com/kauelima21
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@78808819e309bf3cf658444460e0999d947a0a5c -
Trigger Event:
push
-
Statement type:
File details
Details for the file coffeecode_uploader-2.0.0-py3-none-any.whl.
File metadata
- Download URL: coffeecode_uploader-2.0.0-py3-none-any.whl
- Upload date:
- Size: 10.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
85388ebbf14ef3a6fb562f8ea4920662c55e144f45493cfdfe714e63b30663c5
|
|
| MD5 |
19a66a65e3194ef33aa952e0b557f72f
|
|
| BLAKE2b-256 |
82ffcb8e79cb369f6912385b78fb8499de559eba62e48581037cdfe99182e98c
|
Provenance
The following attestation bundles were made for coffeecode_uploader-2.0.0-py3-none-any.whl:
Publisher:
release.yml on kauelima21/coffeecode-uploader
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
coffeecode_uploader-2.0.0-py3-none-any.whl -
Subject digest:
85388ebbf14ef3a6fb562f8ea4920662c55e144f45493cfdfe714e63b30663c5 - Sigstore transparency entry: 1414619092
- Sigstore integration time:
-
Permalink:
kauelima21/coffeecode-uploader@78808819e309bf3cf658444460e0999d947a0a5c -
Branch / Tag:
refs/tags/v2.0.0 - Owner: https://github.com/kauelima21
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@78808819e309bf3cf658444460e0999d947a0a5c -
Trigger Event:
push
-
Statement type: