Gerar UUID v4 em Python — uuid.uuid4()

·Backend Developer·Revisado porDmitri Volkov·Publicado

Use o Gerador UUID v4 gratuito diretamente no seu navegador — sem instalação.

Experimentar Gerador UUID v4 online →

Sempre que preciso de um identificador resistente a colisões para uma linha de banco de dados, rastreamento de API ou token de sessão, a resposta é gerar UUID v4 em Python — uma linha, zero dependências: uuid.uuid4(). O módulo built-in uuid do Python utiliza os.urandom() para aleatoriedade criptograficamente segura. Para obter um UUID rapidamente sem escrever código, o gerador de UUID v4 online funciona instantaneamente. Este guia aborda os atributos do objeto UUID, geração em massa, serialização JSON, armazenamento em banco de dados, validação, uuid-utils (~10× mais rápido, com backend em Rust) e os quatro erros mais comuns — tudo com Python 3.8+.

Pontos-chave
  • uuid.uuid4() faz parte da stdlib do Python — import uuid é tudo que você precisa, sem pip install.
  • O valor retornado é um objeto uuid.UUID, não uma string — use str(), .hex ou .bytes para escolher a representação adequada à sua camada de armazenamento.
  • O UUID v4 utiliza 122 bits aleatórios de os.urandom() — criptograficamente seguro, sem exposição de endereço MAC ou timestamp.
  • Para serviços de alto throughput, pip install uuid-utils é um substituto direto com ~10x mais velocidade, alimentado por Rust.
  • Nunca passe uuid.uuid4 (sem parênteses) como argumento padrão diretamente em um dataclass ou modelo Pydantic — isso fará com que todas as instâncias compartilhem o mesmo UUID.

O que é UUID v4?

Um UUID (Identificador Universalmente Único) é um rótulo de 128 bits formatado como 32 dígitos hexadecimais divididos em cinco grupos por hífens: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx. A versão 4 é a variante mais amplamente utilizada: 122 desses 128 bits são gerados aleatoriamente, e os 6 bits restantes codificam a versão (4) e a variante (RFC 4122). Não há timestamp nem identificador de host — o identificador é completamente opaco e seguro em termos de privacidade. A probabilidade de dois UUIDs v4 gerados independentemente colidirem é tão pequena que, para fins práticos, isso nunca acontece, mesmo em sistemas distribuídos gerando milhões de IDs por segundo.

Before · Python
After · Python
event_id = "evt-" + str(random.randint(100000, 999999))  # fragile, not unique
event_id = str(uuid.uuid4())  # 3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e

uuid.uuid4() — A Forma Padrão de Gerar UUID v4 em Python

O módulo uuid faz parte da biblioteca padrão do Python. Chamar uuid.uuid4() retorna um objeto uuid.UUID com um conjunto completo de atributos para diferentes representações. Converter para string com str() produz o formato canônico com hífens que APIs, bancos de dados e cabeçalhos HTTP esperam.

Python 3.8+ — exemplo mínimo
import uuid

# Gerar um UUID v4
request_id = uuid.uuid4()

print(request_id)           # 3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e
print(type(request_id))     # <class 'uuid.UUID'>
print(request_id.version)   # 4

# Converter para string para JSON / cabeçalhos HTTP
print(str(request_id))      # "3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e"
print(request_id.hex)       # "3b1f8a9d2c4e4f6a8b0d5e7c9f1a3d2e" (sem traços)
print(request_id.bytes)     # b';...' (16 bytes brutos)

Um padrão comum no mundo real é anexar um UUID a cada requisição de API de saída para correlacionar logs entre serviços. Veja um wrapper mínimo de sessão requests que injeta um UUID novo em cada chamada:

Python 3.8+ — trace ID por requisição
import uuid
import requests

def call_api(endpoint: str, payload: dict) -> dict:
    trace_id = str(uuid.uuid4())
    headers = {
        "X-Request-ID": trace_id,
        "Content-Type": "application/json",
    }
    response = requests.post(endpoint, json=payload, headers=headers, timeout=10)
    response.raise_for_status()
    return {"trace_id": trace_id, "data": response.json()}

# result["trace_id"] permite localizar a requisição exata em todos os logs de serviço
result = call_api("https://api.example.com/v1/orders", {"product_id": "prod_7x2k", "qty": 3})
print(result["trace_id"])  # ex: "3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e"

Ao gerar UUIDs em massa — por exemplo, pré-populando um lote de linhas de banco de dados — uma list comprehension é a forma idiomática e legível:

Python 3.8+ — geração em massa
import uuid

# Pré-gerar IDs para 1000 eventos de telemetria
event_ids = [str(uuid.uuid4()) for _ in range(1000)]
print(f"Generated {len(event_ids)} unique IDs")
print(event_ids[0])   # ex: "a1c2e3f4-..."
print(event_ids[-1])  # valor diferente a cada execução

Precisa de um UUID rápido sem executar código? Use o gerador de UUID v4 online para copiar um valor novo com um clique, ou gere centenas de uma vez — útil para popular bancos de dados de teste ou arquivos de fixtures.

Nota:uuid.uuid4() chama os.urandom(16) internamente, depois define os bits 6–7 do byte 8 como 10 (variante) e os bits 12–15 do byte 6 como 0100 (versão 4). Os 122 bits restantes são aleatórios. Por isso você não pode confiar na versão sem analisar com uuid.UUID().

Atributos e Representações do Objeto UUID

O objeto uuid.UUID expõe múltiplas representações do mesmo valor de 128 bits. Escolher a correta para sua camada de armazenamento previne corrupção silenciosa de dados e bytes desperdiçados.

Atributo / Método
Tipo
Descrição
uuid.UUID(hex=...)
UUID
Analisa um UUID existente a partir de uma string hexadecimal, com ou sem traços.
.hex
str
String hexadecimal em minúsculas com 32 caracteres sem hífens — formato compacto para armazenamento.
.int
int
Representação do UUID como inteiro de 128 bits — útil para aritmética e ordenação.
.bytes
bytes
Representação binária big-endian de 16 bytes — tamanho de armazenamento mais eficiente.
.bytes_le
bytes
Binário little-endian de 16 bytes — corresponde à ordem de bytes dos GUIDs da Microsoft.
.fields
tuple
Tupla de seis campos UUID: (time_low, time_mid, time_hi_version, clock_seq_hi_variant, clock_seq_low, node).
.version
int | None
Número de versão do UUID (1–5, ou None para UUIDs não padronizados).
.variant
str
String de variante do UUID — "specified in RFC 4122" para UUIDs padrão.
str(uuid_obj)
str
String canônica de 36 caracteres com quatro hífens: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
Python 3.8+ — todas as representações
import uuid

u = uuid.uuid4()

print(str(u))         # "3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e"  (36 chars)
print(u.hex)          # "3b1f8a9d2c4e4f6a8b0d5e7c9f1a3d2e"      (32 chars, sem traços)
print(u.bytes)        # b';Š...'                       (16 bytes, big-endian)
print(u.bytes_le)     # b'Š...'                       (16 bytes, little-endian)
print(u.int)          # 78823... (inteiro de 128 bits)
print(u.version)      # 4
print(u.variant)      # 'specified in RFC 4122'

# Round-trip: reconstruir a partir de string
reconstructed = uuid.UUID("3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e")
print(reconstructed == u)  # True (se u tinha esse valor)

Para PostgreSQL com psycopg2 ou asyncpg, passe o objeto UUID diretamente — o driver cuida do mapeamento para o tipo de coluna nativo uuid. Para SQLite, use str(u) (TEXT) ou u.bytes (BLOB, 16 bytes contra 36 da string). Para eficiência de armazenamento em escala, .bytes é 55% menor que a string canônica.

Validar e Analisar Strings UUID v4 em Python

Sempre que um UUID chegar de entrada do usuário, de um parâmetro de URL ou de uma API upstream, você deve validá-lo antes de usá-lo como chave de banco de dados. A abordagem idiomática é tentar a construção com uuid.UUID() e capturar ValueError. Você também pode garantir que o valor recebido seja especificamente a versão 4 verificando .version.

Python 3.8+ — função auxiliar de validação
import uuid

def parse_uuid4(raw: str) -> uuid.UUID:
    """
    Analisa e valida uma string UUID v4.
    Lança ValueError para formato inválido ou versão incorreta.
    """
    try:
        u = uuid.UUID(raw)
    except ValueError as exc:
        raise ValueError(f"Invalid UUID format: {raw!r}") from exc

    if u.version != 4:
        raise ValueError(f"Expected UUID v4, got v{u.version}: {raw!r}")

    return u

# Uso em um handler de rota FastAPI / Flask
def get_order(order_id: str):
    try:
        uid = parse_uuid4(order_id)
    except ValueError as exc:
        return {"error": str(exc)}, 400

    # seguro para usar uid em uma consulta ao banco de dados agora
    return {"order_id": str(uid), "status": "processing"}
Nota:uuid.UUID() aceita strings com ou sem hífens, e também aceita o prefixo urn:uuid:. Portanto, "3b1f8a9d2c4e4f6a8b0d5e7c9f1a3d2e" (sem traços) e "3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e" são analisados para o mesmo objeto.

UUID v4 em Payloads JSON e Respostas de API

O padrão JSON não possui tipo UUID — um UUID em JSON é sempre uma string. Isso significa que você deve converter o objeto uuid.UUID para string antes de passá-lo para json.dumps(). A abordagem mais limpa é uma subclasse personalizada de JSONEncoder para não precisar espalhar chamadas str() por todo o código.

Python 3.8+ — JSONEncoder personalizado para UUID
import json
import uuid
from datetime import datetime

class ApiEncoder(json.JSONEncoder):
    """Serializa objetos UUID e datetime em respostas JSON."""
    def default(self, obj):
        if isinstance(obj, uuid.UUID):
            return str(obj)
        if isinstance(obj, datetime):
            return obj.isoformat()
        return super().default(obj)

# Resposta de API realista com UUIDs aninhados
api_response = {
    "request_id": uuid.uuid4(),
    "created_at": datetime(2026, 3, 14, 9, 41, 0),
    "order": {
        "id": uuid.uuid4(),
        "customer_id": uuid.uuid4(),
        "items": [
            {"product_id": uuid.uuid4(), "sku": "NVX-9000", "qty": 2},
        ],
    },
}

print(json.dumps(api_response, indent=2, cls=ApiEncoder))
# {
#   "request_id": "3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e",
#   "created_at": "2026-03-14T09:41:00",
#   "order": {
#     "id": "a1c2e3f4-...",
#     ...
#   }
# }

Para uma serialização avulsa, o hook default= é mais simples do que criar uma subclasse:

Python 3.8+ — hook default= (uso avulso)
import json, uuid

event_id = uuid.uuid4()
payload = {"event_id": event_id, "action": "checkout"}

# Passa um callable; chamado apenas para tipos que json não suporta
json_str = json.dumps(payload, default=str)
print(json_str)  # {"event_id": "3b1f8a9d-...", "action": "checkout"}

Ao receber uma resposta de uma API externa, analise as strings UUID de volta para objetos para que o código obtenha o conjunto completo de atributos e segurança de tipos:

Python 3.8+ — analisando UUID de uma resposta de API
import json
import uuid
import requests

def fetch_shipment(shipment_id: str) -> dict:
    """Busca uma remessa e retorna com campos UUID tipados."""
    response = requests.get(
        f"https://api.logistics.example.com/v2/shipments/{shipment_id}",
        headers={"Accept": "application/json"},
        timeout=10,
    )
    response.raise_for_status()
    data = response.json()

    # Analisar os campos UUID de volta para objetos uuid.UUID
    try:
        data["id"] = uuid.UUID(data["id"])
        data["carrier_id"] = uuid.UUID(data["carrier_id"])
    except (KeyError, ValueError) as exc:
        raise RuntimeError(f"Malformed shipment response: {exc}") from exc

    return data

Para atualizar campos UUID em um arquivo JSON no disco — por exemplo, rotacionar um ID de correlação em um arquivo de configuração ou seed — leia, modifique e grave de volta atomicamente:

Python 3.8+ — ler, atualizar e gravar um arquivo JSON
import json, uuid

def rotate_correlation_id(path: str) -> str:
    """Substitui ou adiciona 'correlation_id' em um arquivo JSON. Retorna o novo UUID."""
    try:
        with open(path) as f:
            data = json.load(f)
    except FileNotFoundError:
        data = {}
    except json.JSONDecodeError as exc:
        raise ValueError(f"Invalid JSON in {path!r}: {exc}") from exc

    new_id = str(uuid.uuid4())
    data["correlation_id"] = new_id

    with open(path, "w") as f:
        json.dump(data, f, indent=2)

    return new_id

Se não quiser executar um script toda vez que precisar inspecionar um UUID de uma resposta de API, cole-o diretamente no UUID Decoder — ele mostra a versão, variante e todos os campos sem nenhum código.

Gerar UUID v4 pela Linha de Comando com Python

O módulo uuid do Python não expõe um subcomando de CLI independente como python -m json.tool, mas um one-liner cobre o mesmo caso de uso. Esses comandos são úteis em scripts shell, pipelines de CI e sempre que você precisar de um identificador descartável sem abrir um REPL.

bash
# UUID v4 único
python3 -c "import uuid; print(uuid.uuid4())"
# 3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e

# Formato sem traços (hex) — útil para nomes de arquivo e variáveis de ambiente
python3 -c "import uuid; print(uuid.uuid4().hex)"
# 3b1f8a9d2c4e4f6a8b0d5e7c9f1a3d2e

# Gerar 5 UUIDs para um script de seed em lote
python3 -c "import uuid; [print(uuid.uuid4()) for _ in range(5)]"

# Usar em uma variável shell
DEPLOY_ID=$(python3 -c "import uuid; print(uuid.uuid4())")
echo "Deploying with ID: $DEPLOY_ID"
Nota:No macOS e na maioria das distribuições Linux, uuidgen (um utilitário C) produz valores UUID v4 e é mais rápido para scripts shell puros. Use o one-liner Python quando já estiver em um ambiente centrado em Python e quiser consistência com a forma como os UUIDs são gerados no código da sua aplicação.

UUID v4 de Alto Desempenho com uuid-utils

O uuid.uuid4() da biblioteca padrão é rápido o suficiente para a maioria das aplicações — a alguns microssegundos por chamada, ele lida confortavelmente com milhares de IDs por segundo. Se você estiver gerando UUIDs no caminho crítico de um serviço de alto throughput (inserções em massa, telemetria por evento em escala ou geração de request ID sob carga intensa), uuid-utils é um substituto direto com backend em Rust que apresenta cerca de 10x a velocidade da stdlib nos benchmarks.

bash — install
pip install uuid-utils
Python 3.8+ — uuid-utils como substituto direto
# uuid_utils é um substituto direto para o módulo uuid da stdlib
import uuid_utils as uuid

# Mesma API que a stdlib
request_id = uuid.uuid4()
print(request_id)           # 3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e
print(str(request_id))      # string canônica
print(request_id.hex)       # hex sem traços
print(request_id.version)   # 4

# Também suporta v7 (ordenado por tempo, ótimo para chaves primárias de BD)
time_ordered_id = uuid.uuid7()
print(time_ordered_id)      # começa com prefixo do timestamp atual
Aviso:O modo padrão do uuid-utils retorna seu próprio tipo de objeto UUID, que é compatível com a stdlib na maioria dos casos. Se você precisar de verificações estritas com isinstance(u, uuid.UUID) da biblioteca padrão, use o modo compat: import uuid_utils.compat as uuid. O modo compat é ligeiramente mais lento que o padrão, mas ainda mais rápido que a stdlib.

UUID v4 em Dataclasses e Modelos Pydantic

Dataclasses e modelos Pydantic do Python suportam campos UUID nativamente. O padrão essencial ao usar UUID como padrão gerado automaticamente é passar a referência da função, não o resultado de uma chamada — caso contrário, todas as instâncias compartilharão o mesmo UUID.

Python 3.10+ — dataclass com UUID padrão
from dataclasses import dataclass, field
import uuid

@dataclass
class WorkerJob:
    job_id: uuid.UUID = field(default_factory=uuid.uuid4)
    worker_id: str = "worker-01"
    payload: dict = field(default_factory=dict)

job1 = WorkerJob(payload={"task": "resize_image", "src": "uploads/img_4932.png"})
job2 = WorkerJob(payload={"task": "send_email",   "to":  "ops@example.com"})

print(job1.job_id)  # único por instância
print(job2.job_id)  # diferente de job1.job_id
print(job1.job_id == job2.job_id)  # False
Python 3.10+ — modelo Pydantic v2 com UUID
from pydantic import BaseModel, Field
import uuid

class OrderEvent(BaseModel):
    event_id: uuid.UUID = Field(default_factory=uuid.uuid4)
    order_id: uuid.UUID
    status: str
    amount_cents: int

event = OrderEvent(
    order_id=uuid.UUID("a1c2e3f4-5b6d-4e7f-8c9d-0a1b2c3d4e5f"),
    status="payment_confirmed",
    amount_cents=4995,
)

print(event.model_dump_json(indent=2))
# {
#   "event_id": "3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e",
#   "order_id": "a1c2e3f4-5b6d-4e7f-8c9d-0a1b2c3d4e5f",
#   "status": "payment_confirmed",
#   "amount_cents": 4995
# }
# Pydantic v2 serializa uuid.UUID como string automaticamente

Erros Comuns ao Gerar UUID v4 em Python

Já vi todos esses quatro padrões aparecerem em revisões de código e incidentes em produção — são fáceis de ignorar porque não levantam um erro imediatamente.

Chamar uuid4 Sem Parênteses como Valor Padrão

Problema: Passar uuid.uuid4 (o objeto função) como valor padrão em um dataclass ou modelo sem envolvê-lo em default_factory — o Python avalia o padrão uma vez na definição da classe, fazendo com que todas as instâncias compartilhem o mesmo UUID.

Solução: Use default_factory=uuid.uuid4 em dataclasses ou Field(default_factory=uuid.uuid4) no Pydantic para que um novo UUID seja gerado por instância.

Before · Python
After · Python
@dataclass
class Session:
    # ERRADO: avaliado uma vez, todas as instâncias compartilham este UUID
    session_id: uuid.UUID = uuid.uuid4()
@dataclass
class Session:
    # CORRETO: factory chamada por instância
    session_id: uuid.UUID = field(default_factory=uuid.uuid4)
Comparar um Objeto UUID com uma String Simples

Problema: Objetos uuid.UUID não são iguais a strings simples, então session_id == '3b1f8a9d-...' sempre retorna False mesmo quando o valor coincide — quebrando buscas silenciosamente.

Solução: Sempre compare UUID com UUID: envolva a string com uuid.UUID() antes de comparar, ou converta ambos os lados para str().

Before · Python
After · Python
# Retorna False mesmo quando os valores coincidem
if record["session_id"] == "3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e":
    revoke_session(record)
target = uuid.UUID("3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e")
if record["session_id"] == target:   # ambos são uuid.UUID
    revoke_session(record)

# Ou normalize tudo para strings na fronteira:
if str(record["session_id"]) == str(target):
    revoke_session(record)
Armazenar .hex em Vez de str() e Perder os Traços

Problema: uuid_obj.hex produz uma string de 32 caracteres sem hífens. Se o código downstream esperar o formato canônico de 36 caracteres com traços (como a maioria das APIs e bancos de dados esperam), ele rejeitará ou analisará incorretamente o valor.

Solução: Use str(uuid_obj) para o formato canônico de 36 caracteres, a menos que você tenha um requisito explícito para o formato hex compacto.

Before · Python
After · Python
# Armazena "3b1f8a9d2c4e4f6a8b0d5e7c9f1a3d2e" — sem traços
payload = {"correlation_id": request_id.hex}
# Armazena "3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e" — formato padrão
payload = {"correlation_id": str(request_id)}
Usar random.random() ou secrets.token_hex() Quando um UUID é Esperado

Problema: random.random() não é criptograficamente seguro, e secrets.token_hex(16) produz uma string hex de 32 caracteres que não é um UUID válido — validadores downstream que chamam uuid.UUID() nela lançarão ValueError.

Solução: Use uuid.uuid4() sempre que o sistema receptor esperar um identificador no formato UUID. Use secrets.token_hex() apenas quando você precisar explicitamente de um token aleatório que não seja no formato UUID.

Before · Python
After · Python
import random, secrets

# Não é um UUID — falhará na validação com uuid.UUID()
request_id = secrets.token_hex(16)   # "a1b2c3d4e5f6..."
session_id = str(random.random())    # "0.8273..." — nem perto
import uuid

request_id = str(uuid.uuid4())  # "3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e"
# UUID v4 válido, criptograficamente seguro

Métodos de Geração de UUID em Python — Comparação Rápida

Todos os métodos abaixo produzem identificadores de 128 bits, mas diferem na fonte de entropia, características de privacidade e se requerem instalação de terceiros.

Método
Fonte
Unicidade
Privacidade
Tipos personalizados
Velocidade
Instalação
uuid.uuid4()
Aleatório (os.urandom)
2¹²² bits aleatórios
N/A
Padrão
Nativa
uuid.uuid1()
Timestamp + MAC
Tempo + host
❌ (MAC exposto)
N/A
Padrão
Nativa
uuid.uuid3(name)
Hash MD5
Determinístico
namespace+name
Padrão
Nativa
uuid.uuid5(name)
Hash SHA-1
Determinístico
namespace+name
Padrão
Nativa
uuid_utils.uuid4()
Rust os.urandom
2¹²² bits aleatórios
N/A
~10× mais rápido
pip install uuid-utils
secrets.token_hex(16)
os.urandom
128 bits aleatórios
N/A
Rápido
Nativa
str(uuid.uuid4())
Aleatório
2¹²² bits aleatórios
N/A
Padrão
Nativa

Use uuid.uuid4() para identificadores únicos de propósito geral em aplicações web, sistemas distribuídos e chaves primárias de banco de dados quando a ordenação não é necessária. Use uuid.uuid5() (ou v3) para IDs determinísticos derivados de um namespace e nome conhecidos — por exemplo, gerando um ID estável para uma URL canônica. Mude para uuid_utils.uuid7() quando precisar de IDs ordenados por tempo para índices de banco de dados (evita page splits em índices B-tree com altas taxas de inserção). Recorra a uuid_utils.uuid4() quando o throughput de geração bruta for o gargalo.

UUID v4 vs UUID v7 — Qual Usar?

A questão prática mais comum é se usar UUID v4 ou o mais recente UUID v7 para chaves primárias de banco de dados. Eis a resposta resumida: use UUID v4 por padrão; mude para UUID v7 apenas quando a fragmentação de índice for um problema medido.

Os valores UUID v4 são totalmente aleatórios, o que significa que as inserções caem em posições aleatórias em um índice B-tree. Em taxas de inserção moderadas (centenas a poucos milhares por segundo), isso é aceitável — o índice cabe no buffer pool e escritas aleatórias são baratas. Em taxas de inserção muito altas, o posicionamento aleatório causa page splits frequentes e cache misses, aumentando a amplificação de escrita e tornando as consultas mais lentas.

O UUID v7 incorpora um timestamp Unix com precisão de milissegundos nos bits mais significativos, de modo que linhas inseridas próximas no tempo também ficam próximas no índice. Isso dá aos índices B-tree (PostgreSQL, MySQL, SQLite) um comportamento mais próximo de um inteiro auto-incrementado: novas linhas sempre são anexadas ao final do índice, eliminando page splits. A desvantagem é que o UUID v7 codifica um timestamp, o que vaza o tempo de criação — evite-o para IDs voltados ao usuário onde o tempo de criação é sensível.

Em Python, o UUID v7 ainda não está na biblioteca padrão (até o Python 3.12). Gere-o com pip install uuid-utils e chame uuid_utils.uuid7(). Ele retorna um objeto com o mesmo conjunto de atributos que uuid.UUID, portanto a migração do v4 é uma mudança de uma linha na factory de IDs.

Para uma alternativa com um clique sem qualquer configuração de Python, cole sua string UUID no gerador e validador de UUID v4 — ele gera, valida e decodifica todos os campos no navegador.

Perguntas Frequentes

Como gerar um UUID v4 em Python?

Chame uuid.uuid4() do módulo built-in uuid do Python. O retorno é um objeto UUID — converta para string com str() quando precisar de uma representação textual. O módulo faz parte da biblioteca padrão, portanto não é necessário instalar nada via pip.

Python
import uuid

session_id = uuid.uuid4()
print(session_id)           # ex: 3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e
print(str(session_id))      # mesma string canônica
print(session_id.hex)       # 3b1f8a9d2c4e4f6a8b0d5e7c9f1a3d2e (sem traços)

Qual a diferença entre uuid.uuid4() e str(uuid.uuid4())?

uuid.uuid4() retorna um objeto UUID que possui atributos como .hex, .bytes, .int e .version. str(uuid.uuid4()) converte esse objeto imediatamente em uma string canônica de 36 caracteres, descartando o objeto. Mantenha o objeto se precisar de múltiplas representações; converta para string na fronteira onde o valor é passado para um payload JSON, banco de dados ou cabeçalho HTTP.

Python
import uuid

u = uuid.uuid4()
print(type(u))          # <class 'uuid.UUID'>
print(u.version)        # 4
print(u.hex)            # hex de 32 chars, sem traços
print(u.bytes)          # 16 bytes binários
print(str(u))           # string canônica de 36 chars com traços

uuid.uuid4() é criptograficamente seguro?

Sim. O uuid.uuid4() do Python utiliza os.urandom() internamente, que lê do gerador de números aleatórios criptograficamente seguro do sistema operacional (/dev/urandom no Linux/macOS, CryptGenRandom no Windows). Os 122 bits aleatórios tornam a probabilidade de colisão desprezível para qualquer carga de trabalho realista. Não o confunda com random.random(), que não é criptograficamente seguro.

Python
import uuid, os

# uuid4 internamente chama os.urandom(16)
raw = os.urandom(16)
# uuid4 define os bits de versão e variante antes de retornar
u = uuid.UUID(bytes=raw, version=4)
print(u)  # UUID v4 válido a partir de bytes aleatórios brutos

Como validar se uma string é um UUID v4 válido em Python?

Analise com uuid.UUID() e verifique o atributo .version. Se a string não for um UUID válido, uuid.UUID() lança um ValueError — capture-o para tratar entradas inválidas. Isso também valida que o formato (traços, comprimento) está correto.

Python
import uuid

def is_valid_uuid4(value: str) -> bool:
    try:
        u = uuid.UUID(value)
        return u.version == 4
    except ValueError:
        return False

print(is_valid_uuid4("3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e"))  # True
print(is_valid_uuid4("not-a-uuid"))                              # False
print(is_valid_uuid4("3b1f8a9d-2c4e-1f6a-8b0d-5e7c9f1a3d2e"))  # False (v1, não v4)

Como armazenar UUIDs em um banco de dados PostgreSQL ou SQLite com Python?

Com PostgreSQL (via psycopg2 ou asyncpg), passe o objeto UUID diretamente — o driver adapta para o tipo UUID nativo. Com o SQLite, que não possui tipo UUID nativo, armazene como TEXT usando str(uuid_obj) ou como BLOB usando uuid_obj.bytes. O SQLAlchemy possui um tipo de coluna UUID que lida com isso automaticamente em diferentes dialetos.

Python
import uuid
import sqlite3

conn = sqlite3.connect(":memory:")
conn.execute("CREATE TABLE events (id TEXT PRIMARY KEY, name TEXT)")

event_id = uuid.uuid4()
conn.execute("INSERT INTO events VALUES (?, ?)", (str(event_id), "user_signup"))
conn.commit()

row = conn.execute("SELECT * FROM events").fetchone()
# Reconstruir objeto UUID a partir da string armazenada
retrieved_id = uuid.UUID(row[0])
print(retrieved_id.version)  # 4

Posso gerar vários UUIDs de uma só vez em Python?

Sim — use uma list comprehension ou um gerador. Cada chamada a uuid.uuid4() é independente e garante um valor distinto. Para geração em massa onde o throughput é importante, uuid-utils (com backend em Rust) é cerca de 10x mais rápido que a biblioteca padrão.

Python
import uuid

# Gerar 5 trace IDs únicos para uma requisição em lote
trace_ids = [str(uuid.uuid4()) for _ in range(5)]
for tid in trace_ids:
    print(tid)
# Cada linha é um UUID v4 distinto

Ferramentas Relacionadas

  • UUID v4 GeneratorGere valores UUID v4 instantaneamente no navegador — sem precisar de um ambiente Python. Copie um único valor ou gere centenas de uma vez.
  • UUID v7 GeneratorGere valores UUID v7 ordenados por tempo — classificáveis pela hora de criação, ideais para chaves primárias em bancos de dados onde a fragmentação de índice é um problema.
  • UUID DecoderInspecione qualquer UUID — versão, variante, timestamp (v1/v7) e campos do nó — sem precisar escrever um parser do zero.
  • JWT DecoderDecodifique e inspecione tokens JWT, que frequentemente carregam identificadores UUID no campo subject (sub) ou jti junto com UUIDs de sessão.
MS
Maria SantosBackend Developer

Maria is a backend developer specialising in Python and API integration. She has broad experience with data pipelines, serialisation formats, and building reliable server-side services. She is an active member of the Python community and enjoys writing practical, example-driven guides that help developers solve real problems without unnecessary theory.

DV
Dmitri VolkovRevisor técnico

Dmitri is a DevOps engineer who relies on Python as his primary scripting and automation language. He builds internal tooling, CI/CD pipelines, and infrastructure automation scripts that run in production across distributed teams. He writes about the Python standard library, subprocess management, file processing, encoding utilities, and the practical shell-adjacent Python that DevOps engineers use every day.