Trabalhando com JSON em Python — 2025 | Python Brasil

Guia completo sobre JSON em Python. Aprenda a ler, escrever, validar e manipular dados JSON com exemplos praticos para APIs e arquivos.

5 min de leitura Equipe Python Brasil

JSON (JavaScript Object Notation) e o formato de dados mais usado na web. Praticamente toda API retorna JSON, arquivos de configuracao usam JSON e ate bancos NoSQL armazenam documentos nesse formato. Python oferece suporte nativo excelente para trabalhar com JSON atraves do modulo json. Neste guia, a gente vai explorar tudo que voce precisa saber.

O Modulo json do Python

O modulo json ja vem incluso no Python e oferece quatro funcoes principais:

import json

# json.dumps() - Python -> string JSON
# json.loads() - string JSON -> Python
# json.dump()  - Python -> arquivo JSON
# json.load()  - arquivo JSON -> Python

A correspondencia entre tipos Python e JSON:

PythonJSON
dictobject
list, tuplearray
strstring
int, floatnumber
True/Falsetrue/false
Nonenull

Convertendo Python para JSON

import json

# Dicionario Python
usuario = {
    "nome": "Ana Silva",
    "idade": 28,
    "email": "ana@email.com",
    "linguagens": ["python", "javascript"],
    "ativo": True,
    "endereco": None
}

# Converter para string JSON
json_string = json.dumps(usuario)
print(json_string)
# {"nome": "Ana Silva", "idade": 28, ...}

# Com formatacao bonita
json_formatado = json.dumps(usuario, indent=2, ensure_ascii=False)
print(json_formatado)
# {
#   "nome": "Ana Silva",
#   "idade": 28,
#   "email": "ana@email.com",
#   "linguagens": [
#     "python",
#     "javascript"
#   ],
#   "ativo": true,
#   "endereco": null
# }

O parametro ensure_ascii=False e importante para preservar acentos e caracteres especiais do portugues.

Convertendo JSON para Python

import json

json_texto = '''
{
    "nome": "Bruno Costa",
    "idade": 32,
    "habilidades": ["python", "docker", "aws"],
    "remoto": true
}
'''

# Converter JSON para dicionario Python
dados = json.loads(json_texto)

print(type(dados))       # <class 'dict'>
print(dados["nome"])     # Bruno Costa
print(dados["idade"])    # 32
print(dados["remoto"])   # True (booleano Python)

# Acessar dados aninhados
for hab in dados["habilidades"]:
    print(f"  - {hab}")

Lendo e Escrevendo Arquivos JSON

import json
from pathlib import Path

# Dados para salvar
config = {
    "app_name": "Minha Aplicacao",
    "versao": "2.0.0",
    "database": {
        "host": "localhost",
        "porta": 5432,
        "nome": "minha_app"
    },
    "debug": False,
    "idiomas": ["pt-br", "en", "es"]
}

# Salvar em arquivo
with open("config.json", "w", encoding="utf-8") as f:
    json.dump(config, f, indent=2, ensure_ascii=False)

print("Arquivo salvo!")

# Ler de arquivo
with open("config.json", "r", encoding="utf-8") as f:
    config_lida = json.load(f)

print(f"App: {config_lida['app_name']}")
print(f"DB Host: {config_lida['database']['host']}")

# Usando pathlib (forma mais moderna)
caminho = Path("config.json")
dados = json.loads(caminho.read_text(encoding="utf-8"))

Trabalhando com APIs que Retornam JSON

O uso mais comum de JSON em Python e consumir APIs:

import requests

# Buscar dados de uma API
response = requests.get("https://api.github.com/users/python")

if response.status_code == 200:
    usuario = response.json()  # Ja converte para dict automaticamente
    print(f"Nome: {usuario['name']}")
    print(f"Repositorios: {usuario['public_repos']}")
    print(f"Seguidores: {usuario['followers']}")
else:
    print(f"Erro: {response.status_code}")

# Enviar JSON em uma requisicao POST
novo_dado = {
    "titulo": "Meu Post",
    "conteudo": "Conteudo do post",
    "publicado": True
}

response = requests.post(
    "https://api.exemplo.com/posts",
    json=novo_dado,  # requests serializa automaticamente
    headers={"Authorization": "Bearer meu-token"}
)

Serializacao de Objetos Customizados

Por padrao, json.dumps nao sabe serializar objetos Python como datetime ou classes customizadas. Voce precisa criar um encoder:

import json
from datetime import datetime, date
from decimal import Decimal


class EncoderCustomizado(json.JSONEncoder):
    """Encoder que suporta datetime, date e Decimal."""

    def default(self, obj):
        if isinstance(obj, datetime):
            return obj.isoformat()
        if isinstance(obj, date):
            return obj.strftime("%Y-%m-%d")
        if isinstance(obj, Decimal):
            return float(obj)
        if isinstance(obj, set):
            return list(obj)
        return super().default(obj)


# Uso
dados = {
    "usuario": "Ana",
    "criado_em": datetime.now(),
    "nascimento": date(1995, 3, 15),
    "saldo": Decimal("1234.56"),
    "tags": {"python", "backend"}
}

json_string = json.dumps(dados, cls=EncoderCustomizado, indent=2)
print(json_string)
# {
#   "usuario": "Ana",
#   "criado_em": "2025-07-28T14:30:00.000000",
#   "nascimento": "1995-03-15",
#   "saldo": 1234.56,
#   "tags": ["python", "backend"]
# }

Alternativa com funcao default:

def serializar(obj):
    """Funcao de serializacao customizada."""
    if isinstance(obj, (datetime, date)):
        return obj.isoformat()
    if isinstance(obj, Decimal):
        return float(obj)
    raise TypeError(f"Tipo nao serializavel: {type(obj)}")

json_string = json.dumps(dados, default=serializar, indent=2)

Validacao de JSON com Pydantic

Para validar estruturas JSON complexas, Pydantic e a melhor opcao:

from pydantic import BaseModel, EmailStr, Field
from typing import Optional
from datetime import datetime


class Endereco(BaseModel):
    rua: str
    cidade: str
    estado: str = Field(max_length=2)
    cep: str


class Usuario(BaseModel):
    nome: str = Field(min_length=2, max_length=100)
    email: str
    idade: int = Field(ge=0, le=150)
    endereco: Optional[Endereco] = None
    criado_em: datetime = Field(default_factory=datetime.now)


# Validar JSON recebido
json_entrada = '''
{
    "nome": "Carlos",
    "email": "carlos@email.com",
    "idade": 30,
    "endereco": {
        "rua": "Rua das Flores, 123",
        "cidade": "Sao Paulo",
        "estado": "SP",
        "cep": "01234-567"
    }
}
'''

usuario = Usuario.model_validate_json(json_entrada)
print(f"Nome: {usuario.nome}")
print(f"Cidade: {usuario.endereco.cidade}")

# Converter de volta para JSON
json_saida = usuario.model_dump_json(indent=2)
print(json_saida)

Manipulando JSON Grandes com ijson

Para arquivos JSON muito grandes que nao cabem na memoria, use streaming:

# pip install ijson
import ijson

def processar_json_grande(caminho_arquivo):
    """Processa arquivo JSON grande sem carregar tudo na memoria."""
    with open(caminho_arquivo, "rb") as f:
        # Iterar sobre items de um array
        for registro in ijson.items(f, "item"):
            # Processa um registro por vez
            print(f"Processando: {registro.get('id')}")
            # Faca algo com o registro

# Funciona com arquivos de gigabytes
# processar_json_grande("dados_enormes.json")

JSONLines: Um Registro por Linha

Para processamento de dados em lote, o formato JSONLines e muito pratico:

import json

# Escrever JSONLines
registros = [
    {"id": 1, "nome": "Ana", "score": 95},
    {"id": 2, "nome": "Bruno", "score": 87},
    {"id": 3, "nome": "Carla", "score": 92},
]

with open("dados.jsonl", "w", encoding="utf-8") as f:
    for registro in registros:
        f.write(json.dumps(registro, ensure_ascii=False) + "\n")

# Ler JSONLines
with open("dados.jsonl", "r", encoding="utf-8") as f:
    for linha in f:
        registro = json.loads(linha)
        print(f"{registro['nome']}: {registro['score']}")

Performance: json vs orjson

Para aplicacoes que precisam de alta performance, o orjson e muito mais rapido:

# pip install orjson
import orjson

dados = {"nome": "Ana", "valores": list(range(1000))}

# Serializar (retorna bytes, nao string)
json_bytes = orjson.dumps(dados)

# Com formatacao
json_formatado = orjson.dumps(dados, option=orjson.OPT_INDENT_2)

# Desserializar
dados_lidos = orjson.loads(json_bytes)

# orjson suporta datetime nativamente
from datetime import datetime
dados_com_data = {"criado": datetime.now()}
print(orjson.dumps(dados_com_data).decode())
# {"criado":"2025-07-28T14:30:00"}

Boas Praticas

Ao trabalhar com JSON em Python, siga estas recomendacoes:

  • Sempre use ensure_ascii=False para preservar caracteres acentuados
  • Especifique encoding="utf-8" ao abrir arquivos JSON
  • Valide JSON de fontes externas com Pydantic ou jsonschema
  • Use indent=2 para arquivos de configuracao legiveis
  • Para performance critica, considere orjson como alternativa
  • Trate excecoes json.JSONDecodeError ao fazer parsing de dados externos
  • Use JSONLines para processamento de dados em lote

Conclusao

JSON e fundamental para qualquer desenvolvedor Python, especialmente ao trabalhar com APIs, configuracoes e troca de dados. Com o modulo json da biblioteca padrao, encoders customizados, Pydantic para validacao e orjson para performance, voce tem todas as ferramentas necessarias para trabalhar com JSON de forma profissional. Dominar essas tecnicas vai facilitar muito seu trabalho com integracao de sistemas e processamento de dados.

E

Equipe Python Brasil

Contribuidor do Python Brasil — Aprenda Python em Português