JSON com bytes em Base64¶
🌐 Tradução por IA e humanos
Esta tradução foi feita por IA orientada por humanos. 🤝
Ela pode conter erros de interpretação do significado original ou soar pouco natural, etc. 🤖
Você pode melhorar esta tradução ajudando-nos a orientar melhor o LLM de IA.
Se sua aplicação precisa receber e enviar dados JSON, mas você precisa incluir dados binários nele, você pode codificá-los em base64.
Base64 vs Arquivos¶
Primeiro, considere se você pode usar Arquivos na request para fazer upload de dados binários e Response personalizada - FileResponse para enviar dados binários, em vez de codificá-los em JSON.
JSON só pode conter strings codificadas em UTF-8, portanto não pode conter bytes puros.
Base64 pode codificar dados binários em strings, mas, para isso, precisa usar mais caracteres do que os dados binários originais; assim, normalmente é menos eficiente do que arquivos comuns.
Use base64 apenas se realmente precisar incluir dados binários em JSON e não puder usar arquivos para isso.
Pydantic bytes¶
Você pode declarar um modelo Pydantic com campos bytes e então usar val_json_bytes na configuração do modelo para indicar que deve usar base64 para validar os dados JSON de entrada; como parte dessa validação, ele decodificará a string base64 em bytes.
from fastapi import FastAPI
from pydantic import BaseModel
class DataInput(BaseModel):
description: str
data: bytes
model_config = {"val_json_bytes": "base64"}
# Code here omitted 👈
app = FastAPI()
@app.post("/data")
def post_data(body: DataInput):
content = body.data.decode("utf-8")
return {"description": body.description, "content": content}
# Code below omitted 👇
👀 Full file preview
from fastapi import FastAPI
from pydantic import BaseModel
class DataInput(BaseModel):
description: str
data: bytes
model_config = {"val_json_bytes": "base64"}
class DataOutput(BaseModel):
description: str
data: bytes
model_config = {"ser_json_bytes": "base64"}
class DataInputOutput(BaseModel):
description: str
data: bytes
model_config = {
"val_json_bytes": "base64",
"ser_json_bytes": "base64",
}
app = FastAPI()
@app.post("/data")
def post_data(body: DataInput):
content = body.data.decode("utf-8")
return {"description": body.description, "content": content}
@app.get("/data")
def get_data() -> DataOutput:
data = "hello".encode("utf-8")
return DataOutput(description="A plumbus", data=data)
@app.post("/data-in-out")
def post_data_in_out(body: DataInputOutput) -> DataInputOutput:
return body
Se você verificar a /docs, verá que o campo data espera bytes codificados em base64:
Você poderia enviar uma request assim:
{
"description": "Some data",
"data": "aGVsbG8="
}
Dica
aGVsbG8= é a codificação base64 de hello.
Em seguida, o Pydantic decodificará a string base64 e fornecerá os bytes originais no campo data do modelo.
Você receberá uma response assim:
{
"description": "Some data",
"content": "hello"
}
Pydantic bytes para dados de saída¶
Você também pode usar campos bytes com ser_json_bytes na configuração do modelo para dados de saída, e o Pydantic irá serializar os bytes como base64 ao gerar a response JSON.
from fastapi import FastAPI
from pydantic import BaseModel
# Code here omitted 👈
class DataOutput(BaseModel):
description: str
data: bytes
model_config = {"ser_json_bytes": "base64"}
# Code here omitted 👈
app = FastAPI()
# Code here omitted 👈
@app.get("/data")
def get_data() -> DataOutput:
data = "hello".encode("utf-8")
return DataOutput(description="A plumbus", data=data)
# Code below omitted 👇
👀 Full file preview
from fastapi import FastAPI
from pydantic import BaseModel
class DataInput(BaseModel):
description: str
data: bytes
model_config = {"val_json_bytes": "base64"}
class DataOutput(BaseModel):
description: str
data: bytes
model_config = {"ser_json_bytes": "base64"}
class DataInputOutput(BaseModel):
description: str
data: bytes
model_config = {
"val_json_bytes": "base64",
"ser_json_bytes": "base64",
}
app = FastAPI()
@app.post("/data")
def post_data(body: DataInput):
content = body.data.decode("utf-8")
return {"description": body.description, "content": content}
@app.get("/data")
def get_data() -> DataOutput:
data = "hello".encode("utf-8")
return DataOutput(description="A plumbus", data=data)
@app.post("/data-in-out")
def post_data_in_out(body: DataInputOutput) -> DataInputOutput:
return body
Pydantic bytes para dados de entrada e saída¶
E, claro, você pode usar o mesmo modelo configurado para usar base64 para lidar tanto com a entrada (validar) com val_json_bytes quanto com a saída (serializar) com ser_json_bytes ao receber e enviar dados JSON.
from fastapi import FastAPI
from pydantic import BaseModel
# Code here omitted 👈
class DataInputOutput(BaseModel):
description: str
data: bytes
model_config = {
"val_json_bytes": "base64",
"ser_json_bytes": "base64",
}
# Code here omitted 👈
app = FastAPI()
# Code here omitted 👈
@app.post("/data-in-out")
def post_data_in_out(body: DataInputOutput) -> DataInputOutput:
return body
👀 Full file preview
from fastapi import FastAPI
from pydantic import BaseModel
class DataInput(BaseModel):
description: str
data: bytes
model_config = {"val_json_bytes": "base64"}
class DataOutput(BaseModel):
description: str
data: bytes
model_config = {"ser_json_bytes": "base64"}
class DataInputOutput(BaseModel):
description: str
data: bytes
model_config = {
"val_json_bytes": "base64",
"ser_json_bytes": "base64",
}
app = FastAPI()
@app.post("/data")
def post_data(body: DataInput):
content = body.data.decode("utf-8")
return {"description": body.description, "content": content}
@app.get("/data")
def get_data() -> DataOutput:
data = "hello".encode("utf-8")
return DataOutput(description="A plumbus", data=data)
@app.post("/data-in-out")
def post_data_in_out(body: DataInputOutput) -> DataInputOutput:
return body