Générer un UUID v4 en Python — Guide uuid.uuid4()
Utilisez le Générateur UUID v4 gratuit directement dans votre navigateur — sans installation.
Essayer Générateur UUID v4 en ligne →Chaque fois que j'ai besoin d'un identifiant résistant aux collisions pour une ligne de base de données, une trace d'API ou un token de session, la réponse est générer un UUID v4 en Python — une ligne, zéro dépendance : uuid.uuid4(). Le module uuid intégré à Python utilise os.urandom() pour un caractère aléatoire cryptographiquement sécurisé. Pour obtenir un UUID rapide sans écrire de code, le générateur UUID v4 en ligne fonctionne instantanément. Ce guide couvre les attributs de l'objet UUID, la génération en masse, la sérialisation JSON, le stockage en base de données, la validation, uuid-utils (alternative Rust ~10× plus rapide), et les quatre erreurs les plus courantes — le tout avec Python 3.8+.
- →
uuid.uuid4()est intégré à la stdlib de Python —import uuidsuffit, aucun pip install n'est nécessaire. - →La valeur retournée est un objet
uuid.UUID, pas une chaîne — utilisezstr(),.hexou.bytespour choisir la représentation adaptée à votre couche de stockage. - →UUID v4 utilise 122 bits aléatoires issus de
os.urandom()— cryptographiquement sécurisé, sans exposition d'adresse MAC ni d'horodatage. - →Pour les services à haut débit,
pip install uuid-utilsest un remplacement direct environ 10× plus rapide, propulsé par Rust. - →Ne passez jamais
uuid.uuid4(sans parenthèses) comme argument par défaut directement dans un dataclass ou un modèle Pydantic — cela partagerait un seul UUID entre toutes les instances.
Qu'est-ce qu'un UUID v4 ?
Un UUID (Universally Unique Identifier) est un label de 128 bits formaté en 32 chiffres hexadécimaux répartis en cinq groupes séparés par des tirets : xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx. La version 4 est la variante la plus utilisée : 122 de ces 128 bits sont générés aléatoirement, et les 6 bits restants encodent la version (4) et la variante (RFC 4122). Il n'y a pas d'horodatage ni d'identifiant d'hôte — l'identifiant est entièrement opaque et respectueux de la vie privée. La probabilité que deux UUID v4 générés indépendamment entrent en collision est si faible qu'en pratique cela ne se produit jamais, même dans des systèmes distribués générant des millions d'identifiants par seconde.
event_id = "evt-" + str(random.randint(100000, 999999)) # fragile, not unique
event_id = str(uuid.uuid4()) # 3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e
uuid.uuid4() — La méthode standard pour générer un UUID v4 en Python
Le module uuid fait partie de la bibliothèque standard de Python. Appeler uuid.uuid4() retourne un objet uuid.UUID avec un ensemble complet d'attributs pour différentes représentations. La conversion en chaîne avec str() produit le format canonique avec tirets attendu par les API, les bases de données et les en-têtes HTTP.
import uuid # Générer un 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 # Convertir en chaîne pour JSON / en-têtes HTTP print(str(request_id)) # "3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e" print(request_id.hex) # "3b1f8a9d2c4e4f6a8b0d5e7c9f1a3d2e" (sans tirets) print(request_id.bytes) # b';...' (16 octets bruts)
Un schéma courant en production consiste à attacher un UUID à chaque requête API sortante pour corréler les journaux entre les services. Voici un wrapper minimal de session requests qui injecte un UUID frais à chaque appel :
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"] permet de retrouver la requête exacte dans tous les journaux de service
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"Pour générer des UUID en masse — par exemple, pré-remplir un lot de lignes de base de données — une compréhension de liste est idiomatique et lisible :
import uuid
# Pré-générer des identifiants pour 1000 événements de télémétrie
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]) # valeur différente à chaque exécutionBesoin d'un UUID rapide sans exécuter de code ? Utilisez le générateur UUID v4 en ligne pour copier une valeur fraîche en un clic, ou générez-en des centaines à la fois — pratique pour alimenter des bases de données de test ou remplir des fichiers de fixtures.
uuid.uuid4() appelle os.urandom(16)en interne, puis positionne les bits 6–7 de l'octet 8 à 10 (variante) et les bits 12–15 de l'octet 6 à 0100(version 4). Les 122 bits restants sont aléatoires. C'est pourquoi on ne peut pas se fier à la version sans analyser avec uuid.UUID().Attributs et représentations de l'objet UUID
L'objet uuid.UUID expose plusieurs représentations de la même valeur 128 bits. Choisir la bonne pour votre couche de stockage évite la corruption silencieuse des données et le gaspillage d'octets.
import uuid
u = uuid.uuid4()
print(str(u)) # "3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e" (36 chars)
print(u.hex) # "3b1f8a9d2c4e4f6a8b0d5e7c9f1a3d2e" (32 chars, no dashes)
print(u.bytes) # b';...' (16 bytes, big-endian)
print(u.bytes_le) # b'...' (16 bytes, little-endian)
print(u.int) # 78823... (entier 128 bits)
print(u.version) # 4
print(u.variant) # 'specified in RFC 4122'
# Aller-retour : reconstituer depuis la chaîne
reconstructed = uuid.UUID("3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e")
print(reconstructed == u) # True (si u avait cette valeur)Pour PostgreSQL avec psycopg2 ou asyncpg, passez l'objet UUID directement — le pilote gère la conversion vers le type natif uuid de la colonne. Pour SQLite, utilisez str(u) (TEXT) ou u.bytes (BLOB, 16 octets contre 36 pour la chaîne). Pour l'efficacité du stockage à grande échelle, .bytes est 55 % plus petit que la chaîne canonique.
Valider et analyser des chaînes UUID v4 en Python
Chaque fois qu'un UUID arrive d'une saisie utilisateur, d'un paramètre de chemin URL ou d'une API en amont, vous devez le valider avant de l'utiliser comme clé de base de données. L'approche idiomatique consiste à tenter la construction avec uuid.UUID() et à intercepter ValueError. Vous pouvez également imposer que la valeur entrante soit spécifiquement la version 4 en vérifiant .version.
import uuid
def parse_uuid4(raw: str) -> uuid.UUID:
"""
Parse and validate a UUID v4 string.
Raises ValueError for invalid format or wrong version.
"""
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
# Utilisation dans un gestionnaire de route FastAPI / Flask
def get_order(order_id: str):
try:
uid = parse_uuid4(order_id)
except ValueError as exc:
return {"error": str(exc)}, 400
# uid peut être utilisé en toute sécurité dans une requête DB
return {"order_id": str(uid), "status": "processing"}uuid.UUID() accepte les chaînes avec ou sans tirets, et accepte également le préfixe urn:uuid:. Ainsi "3b1f8a9d2c4e4f6a8b0d5e7c9f1a3d2e" (sans tirets) et "3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e" sont analysés vers le même objet.UUID v4 dans les payloads JSON et les réponses d'API
Le standard JSON ne dispose pas de type UUID — un UUID en JSON est toujours une chaîne. Cela signifie que vous devez convertir l'objet uuid.UUID en chaîne avant de le passer à json.dumps(). L'approche la plus propre est une sous-classe JSONEncoder personnalisée pour éviter de disperser les appels str() dans tout votre code.
import json
import uuid
from datetime import datetime
class ApiEncoder(json.JSONEncoder):
"""Sérialise les objets UUID et datetime dans les réponses JSON."""
def default(self, obj):
if isinstance(obj, uuid.UUID):
return str(obj)
if isinstance(obj, datetime):
return obj.isoformat()
return super().default(obj)
# Réponse API réaliste avec des UUID imbriqués
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-...",
# ...
# }
# }Pour un appel de sérialisation ponctuel, le hook default= est plus simple que la création d'une sous-classe :
import json, uuid
event_id = uuid.uuid4()
payload = {"event_id": event_id, "action": "checkout"}
# Passer un callable ; appelé uniquement pour les types que json ne sait pas gérer
json_str = json.dumps(payload, default=str)
print(json_str) # {"event_id": "3b1f8a9d-...", "action": "checkout"}Lors de la réception d'une réponse d'une API externe, analysez les chaînes UUID en objets pour que votre code dispose de l'ensemble complet des attributs et de la sécurité de typage :
import json
import uuid
import requests
def fetch_shipment(shipment_id: str) -> dict:
"""Récupère une expédition et retourne les champs UUID typés."""
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()
# Analyser les champs UUID en objets 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 dataPour mettre à jour des champs UUID dans un fichier JSON sur disque — par exemple, faire tourner un identifiant de corrélation dans un fichier de configuration ou de données initiales — lisez, modifiez et réécrivez de manière atomique :
import json, uuid
def rotate_correlation_id(path: str) -> str:
"""Remplace ou ajoute 'correlation_id' dans un fichier JSON. Retourne le nouveau 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_idSi vous ne voulez pas exécuter un script à chaque fois que vous devez inspecter un UUID depuis une réponse d'API, collez-le directement dans le Décodeur UUID — il vous affiche la version, la variante et tous les champs sans écrire une seule ligne de code.
Générer un UUID v4 en ligne de commande avec Python
Le module uuid de Python n'expose pas de sous-commande CLI autonome comme python -m json.tool, mais une expression à une ligne couvre le même besoin. Ces commandes sont utiles dans des scripts shell, des pipelines CI et chaque fois que vous avez besoin d'un identifiant jetable sans ouvrir un REPL.
# UUID v4 unique python3 -c "import uuid; print(uuid.uuid4())" # 3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e # Format hexadécimal sans tirets — utile pour les noms de fichiers et les variables d'environnement python3 -c "import uuid; print(uuid.uuid4().hex)" # 3b1f8a9d2c4e4f6a8b0d5e7c9f1a3d2e # Générer 5 UUID pour un script d'initialisation en lot python3 -c "import uuid; [print(uuid.uuid4()) for _ in range(5)]" # Utiliser dans une variable shell DEPLOY_ID=$(python3 -c "import uuid; print(uuid.uuid4())") echo "Deploying with ID: $DEPLOY_ID"
uuidgen (un utilitaire C) produit des UUID v4 et est plus rapide pour les scripts shell purs. Utilisez l'expression Python à une ligne lorsque vous êtes déjà dans un environnement centré sur Python et souhaitez rester cohérent avec la façon dont les UUID sont générés dans le code de votre application.UUID v4 haute performance avec uuid-utils
Le uuid.uuid4() de la bibliothèque standard est suffisamment rapide pour la plupart des applications — à quelques microsecondes par appel, il gère confortablement des milliers d'identifiants par seconde. Si vous générez des UUID sur le chemin critique d'un service à haut débit (insertions en masse, télémétrie par événement à grande échelle, ou génération d'identifiants de requêtes sous forte charge), uuid-utils est un remplacement direct propulsé par Rust qui atteint environ 10× la vitesse de la stdlib selon les benchmarks.
pip install uuid-utils
# uuid_utils est un remplacement direct du module uuid de la stdlib import uuid_utils as uuid # Même API que la stdlib request_id = uuid.uuid4() print(request_id) # 3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e print(str(request_id)) # chaîne canonique print(request_id.hex) # hex sans tirets print(request_id.version) # 4 # Supporte également v7 (ordonné dans le temps, idéal pour les clés primaires DB) time_ordered_id = uuid.uuid7() print(time_ordered_id) # commence par un préfixe d'horodatage courant
isinstance(u, uuid.UUID) de la bibliothèque standard, utilisez le mode de compatibilité : import uuid_utils.compat as uuid. Le mode compat est légèrement plus lent que le mode par défaut, mais reste plus rapide que la stdlib.UUID v4 dans les Dataclasses et les modèles Pydantic
Les dataclasses Python et les modèles Pydantic prennent tous deux en charge nativement les champs UUID. Le schéma clé lors de l'utilisation d'un UUID comme valeur par défaut auto-générée est de passer la référence de fonction, pas le résultat d'un appel — sinon chaque instance partagerait le même UUID.
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) # unique par instance
print(job2.job_id) # différent de job1.job_id
print(job1.job_id == job2.job_id) # Falsefrom 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 sérialise uuid.UUID en chaîne automatiquementErreurs courantes lors de la génération d'UUID v4 en Python
J'ai vu ces quatre schémas apparaître lors de revues de code et d'incidents en production — ils sont faciles à manquer car ils ne lèvent pas d'erreur immédiatement.
Problème : Passer uuid.uuid4 (l'objet fonction) comme valeur par défaut dans un dataclass ou un modèle sans l'encapsuler dans default_factory — Python évalue la valeur par défaut une seule fois lors de la définition de la classe, donc toutes les instances partagent le même UUID.
Solution : Utilisez default_factory=uuid.uuid4 dans les dataclasses ou Field(default_factory=uuid.uuid4) dans Pydantic pour qu'un nouveau UUID soit généré par instance.
@dataclass
class Session:
# INCORRECT : évalué une fois, toutes les instances partagent ce UUID
session_id: uuid.UUID = uuid.uuid4()@dataclass
class Session:
# CORRECT : la factory est appelée par instance
session_id: uuid.UUID = field(default_factory=uuid.uuid4)Problème : Les objets uuid.UUID ne sont pas égaux aux chaînes simples, donc session_id == '3b1f8a9d-...' retourne toujours False même lorsque la valeur correspond — rompant silencieusement les recherches.
Solution : Comparez toujours UUID à UUID : encapsulez la chaîne avec uuid.UUID() avant de comparer, ou convertissez les deux côtés en str().
# Retourne False même lorsque les valeurs correspondent
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: # les deux sont uuid.UUID
revoke_session(record)
# Ou normaliser tout en chaînes à la frontière :
if str(record["session_id"]) == str(target):
revoke_session(record)Problème : uuid_obj.hex produit une chaîne de 32 caractères sans tirets. Si le code en aval attend le format canonique de 36 caractères avec tirets (c'est le cas de la plupart des API et bases de données), il rejettera ou mal-analysera silencieusement la valeur.
Solution : Utilisez str(uuid_obj) pour le format canonique de 36 caractères, sauf si vous avez une exigence explicite pour la forme hexadécimale compacte.
# Stocke "3b1f8a9d2c4e4f6a8b0d5e7c9f1a3d2e" — sans tirets
payload = {"correlation_id": request_id.hex}# Stocke "3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e" — format standard
payload = {"correlation_id": str(request_id)}Problème : random.random() n'est pas cryptographiquement sécurisé, et secrets.token_hex(16) produit une chaîne hexadécimale de 32 caractères qui n'est pas un UUID valide — les validateurs en aval qui appellent uuid.UUID() dessus lèveront ValueError.
Solution : Utilisez uuid.uuid4() chaque fois que le système destinataire attend un identifiant au format UUID. N'utilisez secrets.token_hex() que lorsque vous avez besoin explicitement d'un token aléatoire sans forme UUID.
import random, secrets # Pas un UUID — échouera à la validation uuid.UUID() request_id = secrets.token_hex(16) # "a1b2c3d4e5f6..." session_id = str(random.random()) # "0.8273..." — pas du tout un UUID
import uuid request_id = str(uuid.uuid4()) # "3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e" # UUID v4 valide, cryptographiquement sécurisé
Méthodes de génération d'UUID en Python — Comparaison rapide
Toutes les méthodes ci-dessous produisent des identifiants de 128 bits, mais diffèrent par leur source d'entropie, leurs caractéristiques de confidentialité et la nécessité ou non d'une installation tierce.
Utilisez uuid.uuid4() pour les identifiants uniques à usage général dans les applications web, les systèmes distribués et les clés primaires de bases de données lorsque la triabilité n'est pas requise. Utilisez uuid.uuid5() (ou v3) pour des identifiants déterministes dérivés d'un espace de nommage et d'un nom connus — par exemple, générer un identifiant stable pour une URL canonique. Passez à uuid_utils.uuid7() lorsque vous avez besoin d'identifiants ordonnés dans le temps pour les index de base de données (évite les fractionnements de pages dans les index B-tree à fort taux d'insertion). Utilisez uuid_utils.uuid4() lorsque le débit brut de génération est le goulot d'étranglement.
UUID v4 vs UUID v7 — Lequel utiliser ?
La question pratique la plus courante est de savoir s'il faut utiliser UUID v4 ou le plus récent UUID v7 pour les clés primaires de bases de données. Voici la réponse concise : utilisez UUID v4 par défaut ; ne passez à UUID v7 que lorsque la fragmentation des index est un problème mesuré.
Les valeurs UUID v4 sont entièrement aléatoires, ce qui signifie que les insertions atterrissent à des positions aléatoires dans un index B-tree. À des taux d'insertion modérés (de quelques centaines à quelques milliers par seconde), c'est acceptable — l'index tient dans le pool de tampons et les écritures aléatoires sont bon marché. À des taux d'insertion très élevés, le placement aléatoire provoque de fréquents fractionnements de pages et des défauts de cache, augmentant l'amplification des écritures et ralentissant les requêtes.
UUID v7 intègre un horodatage Unix en précision milliseconde dans les bits les plus significatifs, de sorte que les lignes insérées proches dans le temps atterrissent également proches dans l'index. Cela donne aux index B-tree (PostgreSQL, MySQL, SQLite) un comportement proche d'un entier auto-incrémenté : les nouvelles lignes s'ajoutent toujours à la fin de l'index, éliminant les fractionnements de pages. La contrepartie est qu'UUID v7 encode un horodatage, ce qui divulgue l'heure de création — évitez-le pour les identifiants exposés aux utilisateurs quand l'heure de création est sensible.
En Python, UUID v7 n'est pas encore dans la bibliothèque standard (à partir de Python 3.12). Générez-le avec pip install uuid-utils et appelez uuid_utils.uuid7(). Il retourne un objet avec le même ensemble d'attributs que uuid.UUID, donc la migration depuis v4 est un changement d'une ligne dans la factory d'identifiants.
Pour une alternative en un clic sans configuration Python, collez votre chaîne UUID dans le générateur et validateur UUID v4 — il génère, valide et décode tous les champs dans le navigateur.
Questions fréquemment posées
Comment générer un UUID v4 en Python ?
Appelez uuid.uuid4() depuis le module uuid intégré à Python. La fonction retourne un objet UUID — convertissez-le en chaîne avec str() lorsque vous avez besoin d'une représentation textuelle. Le module est livré avec la bibliothèque standard, aucun pip install n'est nécessaire.
import uuid session_id = uuid.uuid4() print(session_id) # ex. 3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e print(str(session_id)) # même chaîne canonique print(session_id.hex) # 3b1f8a9d2c4e4f6a8b0d5e7c9f1a3d2e (sans tirets)
Quelle est la différence entre uuid.uuid4() et str(uuid.uuid4()) ?
uuid.uuid4() retourne un objet UUID qui possède des attributs comme .hex, .bytes, .int et .version. str(uuid.uuid4()) convertit immédiatement cet objet en une chaîne canonique de 36 caractères, en abandonnant l'objet. Conservez l'objet si vous avez besoin de plusieurs représentations ; convertissez en chaîne à la frontière où vous transmettez la valeur à un payload JSON, une base de données ou un en-tête HTTP.
import uuid u = uuid.uuid4() print(type(u)) # <class 'uuid.UUID'> print(u.version) # 4 print(u.hex) # hex 32 caractères, sans tirets print(u.bytes) # binaire 16 octets print(str(u)) # chaîne canonique de 36 caractères avec tirets
uuid.uuid4() est-il cryptographiquement sécurisé ?
Oui. Le uuid.uuid4() de Python utilise os.urandom() en interne, qui lit depuis le générateur de nombres aléatoires cryptographiquement sécurisé du système d'exploitation (/dev/urandom sous Linux/macOS, CryptGenRandom sous Windows). Les 122 bits aléatoires rendent la probabilité de collision négligeable pour toute charge de travail réaliste. Ne le confondez pas avec random.random(), qui n'est pas cryptographiquement sécurisé.
import uuid, os # uuid4 appelle os.urandom(16) en interne raw = os.urandom(16) # uuid4 définit les bits de version et de variante avant de retourner u = uuid.UUID(bytes=raw, version=4) print(u) # UUID v4 valide à partir d'octets aléatoires bruts
Comment valider qu'une chaîne est un UUID v4 valide en Python ?
Analysez avec uuid.UUID() et vérifiez l'attribut .version. Si la chaîne n'est pas un UUID valide, uuid.UUID() lève une ValueError — interceptez-la pour gérer les entrées invalides. Cela valide également que le format (tirets, longueur) est correct.
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, pas v4)Comment stocker des UUID dans une base de données PostgreSQL ou SQLite depuis Python ?
Avec PostgreSQL (via psycopg2 ou asyncpg), passez l'objet UUID directement — le pilote l'adapte au type UUID natif. Avec SQLite, qui n'a pas de type UUID natif, stockez en TEXT avec str(uuid_obj) ou en BLOB avec uuid_obj.bytes. SQLAlchemy dispose d'un type de colonne UUID qui gère cela automatiquement pour tous les dialectes.
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()
# Reconstituer l'objet UUID depuis la chaîne stockée
retrieved_id = uuid.UUID(row[0])
print(retrieved_id.version) # 4Peut-on générer plusieurs UUID à la fois en Python ?
Oui — utilisez une compréhension de liste ou un générateur. Chaque appel à uuid.uuid4() est indépendant et garantit de produire une valeur distincte. Pour la génération en masse où le débit compte, uuid-utils (version Rust) est environ 10 fois plus rapide que la bibliothèque standard.
import uuid
# Générer 5 identifiants de trace uniques pour une requête en lot
trace_ids = [str(uuid.uuid4()) for _ in range(5)]
for tid in trace_ids:
print(tid)
# Chaque ligne est un UUID v4 distinctOutils associés
- →UUID v4 Generator — Générez des UUID v4 instantanément dans le navigateur — aucun environnement Python requis. Copiez une valeur unique ou générez-en des centaines à la fois.
- →UUID v7 Generator — Générez des UUID v7 ordonnés dans le temps — triables par date de création, idéaux pour les clés primaires de bases de données où la fragmentation des index est un enjeu.
- →UUID Decoder — Inspectez n'importe quel UUID — version, variante, horodatage (v1/v7) et champs node — sans écrire un analyseur de zéro.
- →JWT Decoder — Décodez et inspectez les tokens JWT, qui contiennent souvent des identifiants UUID dans les claims subject (sub) ou jti, ainsi que des UUID de session.
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.
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.