Python-এ UUID v4 জেনারেট করুন — uuid.uuid4() পূর্ণ গাইড
বিনামূল্যে অনলাইন UUID v4 জেনারেটর সরাসরি আপনার ব্রাউজারে ব্যবহার করুন — ইনস্টলের প্রয়োজন নেই।
UUID v4 জেনারেটর অনলাইনে ব্যবহার করুন →যখনই আমার ডেটাবেস রো, API ট্রেস বা সেশন টোকেনের জন্য কোলিশন-প্রতিরোধী আইডেন্টিফায়ার দরকার হয়, উত্তর একটাই — Python-এ UUID v4 তৈরি করুন — এক লাইন, শূন্য ডিপেন্ডেন্সি: uuid.uuid4()। Python-এর বিল্ট-ইন uuid মডিউল ক্রিপ্টোগ্রাফিক্যালি নিরাপদ র্যান্ডমনেসের জন্য os.urandom() ব্যবহার করে। কোড না লিখে দ্রুত UUID দরকার হলে, অনলাইন UUID v4 জেনারেটর তাৎক্ষণিকভাবে কাজ করে। এই গাইডে UUID অবজেক্টের অ্যাট্রিবিউট, বাল্ক জেনারেশন, JSON সিরিয়ালাইজেশন, ডেটাবেস স্টোরেজ, ভ্যালিডেশন, uuid-utils (~১০× দ্রুত Rust-ব্যাকড ড্রপ-ইন), এবং চারটি সাধারণ ভুল — সব Python 3.8+-এ।
- →
uuid.uuid4()Python-এর stdlib-এ বিল্ট-ইন —import uuid-ই যথেষ্ট, কোনো pip install লাগবে না। - →রিটার্ন মান একটি
uuid.UUIDঅবজেক্ট, স্ট্রিং নয় — আপনার স্টোরেজ লেয়ারের উপযুক্ত উপস্থাপনা বেছে নিতেstr(),.hex, বা.bytesব্যবহার করুন। - →UUID v4
os.urandom()থেকে ১২২টি র্যান্ডম বিট ব্যবহার করে — ক্রিপ্টোগ্রাফিক্যালি নিরাপদ, MAC ঠিকানা বা টাইমস্ট্যাম্প উন্মুক্ত হয় না। - →হাই-থ্রুপুট সার্ভিসের জন্য,
pip install uuid-utilsএকটি ড্রপ-ইন বিকল্প যা Rust-চালিত এবং ~১০গুণ দ্রুত। - →কখনো
uuid.uuid4(বন্ধনী ছাড়া) সরাসরি ডেটাক্লাস বা Pydantic মডেলে ডিফল্ট আর্গুমেন্ট হিসেবে পাস করবেন না — এটি সব ইনস্ট্যান্সে একটি UUID শেয়ার করবে।
UUID v4 কী?
UUID (Universally Unique Identifier) হলো একটি ১২৮-বিট লেবেল যা হাইফেন দিয়ে পাঁচটি গ্রুপে বিভক্ত ৩২টি হেক্সাডেসিমাল ডিজিট হিসেবে ফরম্যাট করা: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx। ভার্সন 4 সবচেয়ে বহুল ব্যবহৃত ভ্যারিয়েন্ট: ১২৮ বিটের মধ্যে ১২২টি র্যান্ডমভাবে তৈরি হয়, এবং বাকি ৬টি বিট ভার্সন (4) ও ভ্যারিয়েন্ট (RFC 4122) এনকোড করে। এতে কোনো টাইমস্ট্যাম্প বা হোস্ট আইডেন্টিফায়ার নেই — আইডেন্টিফায়ারটি সম্পূর্ণ অস্বচ্ছ ও গোপনীয়তা-নিরাপদ। দুটি স্বাধীনভাবে তৈরি v4 UUID কোলাইড হওয়ার সম্ভাবনা এত কম যে ব্যবহারিক উদ্দেশ্যে এটি কখনো ঘটে না, এমনকি প্রতি সেকেন্ডে লক্ষ লক্ষ ID তৈরি করা বিতরণকৃত সিস্টেমেও।
event_id = "evt-" + str(random.randint(100000, 999999)) # ভঙ্গুর, অনন্য নয়
event_id = str(uuid.uuid4()) # 3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e
uuid.uuid4() — Python-এ UUID v4 তৈরির স্ট্যান্ডার্ড পদ্ধতি
uuid মডিউলটি Python-এর স্ট্যান্ডার্ড লাইব্রেরির অংশ। uuid.uuid4() কল করলে বিভিন্ন উপস্থাপনার জন্য সম্পূর্ণ অ্যাট্রিবিউট সেট সহ একটি uuid.UUID অবজেক্ট রিটার্ন করে। str() দিয়ে স্ট্রিংয়ে রূপান্তর করলে API, ডেটাবেস এবং HTTP হেডার যে ক্যানোনিকাল হাইফেনযুক্ত ফরম্যাট প্রত্যাশা করে তা তৈরি হয়।
import uuid # 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 # JSON / HTTP হেডারের জন্য স্ট্রিংয়ে রূপান্তর করুন print(str(request_id)) # "3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e" print(request_id.hex) # "3b1f8a9d2c4e4f6a8b0d5e7c9f1a3d2e" (ড্যাশ ছাড়া) print(request_id.bytes) # b';...' (16 র্যাও বাইট)
একটি সাধারণ বাস্তব প্যাটার্ন হলো প্রতিটি আউটবাউন্ড API রিকোয়েস্টে একটি UUID সংযুক্ত করা যাতে সার্ভিসের মধ্যে লগ কোরিলেট করা যায়। এখানে একটি সর্বনিম্ন requests সেশন র্যাপার যা প্রতিটি কলে একটি নতুন UUID ইনজেক্ট করে:
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"] দিয়ে সব সার্ভিস লগে এই নির্দিষ্ট রিকোয়েস্টটি grep করা যায়
result = call_api("https://api.example.com/v1/orders", {"product_id": "prod_7x2k", "qty": 3})
print(result["trace_id"]) # যেমন: "3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e"বাল্কে UUID তৈরি করার সময় — যেমন ডেটাবেস রোর ব্যাচ প্রি-পপুলেট করা — লিস্ট কম্প্রিহেনশন সহজাত ও পাঠযোগ্য:
import uuid
# ১০০০টি টেলিমেট্রি ইভেন্টের জন্য ID প্রি-জেনারেট করুন
event_ids = [str(uuid.uuid4()) for _ in range(1000)]
print(f"তৈরি হয়েছে {len(event_ids)}টি অনন্য ID")
print(event_ids[0]) # যেমন: "a1c2e3f4-..."
print(event_ids[-1]) # প্রতিবার ভিন্ন মানকোড না লিখে দ্রুত UUID দরকার হলে অনলাইন UUID v4 জেনারেটর ব্যবহার করুন — এক ক্লিকে একটি নতুন মান কপি করুন, বা একসাথে শত শত তৈরি করুন — টেস্ট ডেটাবেস সিড করা বা ফিক্সচার ফাইল পপুলেট করার জন্য উপযোগী।
uuid.uuid4() অভ্যন্তরীণভাবে os.urandom(16) কল করে, তারপর বাইট 8-এর বিট 6–7 10 (ভ্যারিয়েন্ট) এবং বাইট 6-এর বিট 12–15 0100 (ভার্সন 4) সেট করে। বাকি ১২২টি বিট র্যান্ডম। এই কারণেই ভার্সন বিশ্বাস করতে হলে uuid.UUID() দিয়ে পার্স করতে হবে।UUID অবজেক্টের অ্যাট্রিবিউট ও উপস্থাপনা
uuid.UUID অবজেক্ট একই ১২৮-বিট মানের একাধিক উপস্থাপনা প্রকাশ করে। আপনার স্টোরেজ লেয়ারের জন্য সঠিকটি বেছে নিলে নীরব ডেটা দুর্নীতি ও অপচয় বাইট রোধ হয়।
import uuid
u = uuid.uuid4()
print(str(u)) # "3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e" (36 অক্ষর)
print(u.hex) # "3b1f8a9d2c4e4f6a8b0d5e7c9f1a3d2e" (32 অক্ষর, ড্যাশ ছাড়া)
print(u.bytes) # b';...' (16 বাইট, বিগ-এন্ডিয়ান)
print(u.bytes_le) # b'...' (16 বাইট, লিটল-এন্ডিয়ান)
print(u.int) # 78823... (128-বিট পূর্ণসংখ্যা)
print(u.version) # 4
print(u.variant) # 'specified in RFC 4122'
# রাউন্ড-ট্রিপ: স্ট্রিং থেকে পুনর্নির্মাণ
reconstructed = uuid.UUID("3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e")
print(reconstructed == u) # True (যদি u ঐ মান হয়)psycopg2 বা asyncpg দিয়ে PostgreSQL-এ, UUID অবজেক্ট সরাসরি পাস করুন — ড্রাইভার নেটিভ uuid কলাম টাইপে ম্যাপিং পরিচালনা করে। SQLite-এ, str(u) (TEXT) বা u.bytes (BLOB, স্ট্রিংয়ের ৩৬-এর বিপরীতে ১৬ বাইট) ব্যবহার করুন। স্কেলে স্টোরেজ দক্ষতার জন্য, .bytes ক্যানোনিকাল স্ট্রিংয়ের তুলনায় ৫৫% ছোট।
Python-এ UUID v4 স্ট্রিং যাচাই ও পার্স করা
যখনই ব্যবহারকারীর ইনপুট, URL পাথ প্যারামিটার বা আপস্ট্রিম API থেকে UUID আসে, ডেটাবেস কী হিসেবে ব্যবহার করার আগে এটি যাচাই করা উচিত। সহজাত পদ্ধতি হলো uuid.UUID() দিয়ে নির্মাণ চেষ্টা করা এবং ValueError ধরা। আগত মানটি নির্দিষ্টভাবে ভার্সন 4 কিনা তাও .version চেক করে প্রয়োগ করা যায়।
import uuid
def parse_uuid4(raw: str) -> uuid.UUID:
"""
UUID v4 স্ট্রিং পার্স ও যাচাই করুন।
অবৈধ ফরম্যাট বা ভুল ভার্সনের জন্য ValueError উত্থাপন করে।
"""
try:
u = uuid.UUID(raw)
except ValueError as exc:
raise ValueError(f"অবৈধ UUID ফরম্যাট: {raw!r}") from exc
if u.version != 4:
raise ValueError(f"UUID v4 প্রত্যাশিত, পাওয়া গেছে v{u.version}: {raw!r}")
return u
# FastAPI / Flask রাউট হ্যান্ডলারে ব্যবহার
def get_order(order_id: str):
try:
uid = parse_uuid4(order_id)
except ValueError as exc:
return {"error": str(exc)}, 400
# এখন uid DB কোয়েরিতে নিরাপদে ব্যবহার করা যাবে
return {"order_id": str(uid), "status": "processing"}uuid.UUID() হাইফেন সহ বা ছাড়া স্ট্রিং গ্রহণ করে, এবং urn:uuid: প্রিফিক্সও গ্রহণ করে। তাই "3b1f8a9d2c4e4f6a8b0d5e7c9f1a3d2e" (ড্যাশ ছাড়া) এবং "3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e" উভয়ই একই অবজেক্টে পার্স হয়।JSON পেলোড ও API রেসপন্সে UUID v4
JSON স্ট্যান্ডার্ডে কোনো UUID টাইপ নেই — JSON-এ UUID সর্বদা একটি স্ট্রিং। এর মানে হলো json.dumps()-এ পাস করার আগে uuid.UUID অবজেক্টকে স্ট্রিংয়ে রূপান্তর করতে হবে। সবচেয়ে পরিষ্কার পদ্ধতি হলো একটি কাস্টম JSONEncoder সাবক্লাস তৈরি করা যাতে পুরো কোডবেসে str() কল ছড়িয়ে না পড়ে।
import json
import uuid
from datetime import datetime
class ApiEncoder(json.JSONEncoder):
"""JSON রেসপন্সে UUID ও datetime অবজেক্ট সিরিয়ালাইজ করুন।"""
def default(self, obj):
if isinstance(obj, uuid.UUID):
return str(obj)
if isinstance(obj, datetime):
return obj.isoformat()
return super().default(obj)
# নেস্টেড UUID সহ বাস্তব API রেসপন্স
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-...",
# ...
# }
# }এককালীন সিরিয়ালাইজেশন কলের জন্য, সাবক্লাসিংয়ের চেয়ে default= হুক সহজ:
import json, uuid
event_id = uuid.uuid4()
payload = {"event_id": event_id, "action": "checkout"}
# একটি callable পাস করুন; শুধু যেসব টাইপ json হ্যান্ডেল করতে পারে না তাদের জন্য কল হয়
json_str = json.dumps(payload, default=str)
print(json_str) # {"event_id": "3b1f8a9d-...", "action": "checkout"}বাহ্যিক API থেকে রেসপন্স পাওয়ার সময়, UUID স্ট্রিংগুলো আবার অবজেক্টে পার্স করুন যাতে কোড সম্পূর্ণ অ্যাট্রিবিউট সেট ও টাইপ সেফটি পায়:
import json
import uuid
import requests
def fetch_shipment(shipment_id: str) -> dict:
"""একটি শিপমেন্ট ফেচ করুন এবং টাইপড UUID ফিল্ড সহ রিটার্ন করুন।"""
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()
# UUID ফিল্ডগুলো 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"ত্রুটিপূর্ণ শিপমেন্ট রেসপন্স: {exc}") from exc
return dataডিস্কে JSON ফাইলে UUID ফিল্ড আপডেট করতে — যেমন কনফিগ বা সিড ফাইলে কোরিলেশন ID রোটেট করতে — পড়ুন, পরিবর্তন করুন এবং অ্যাটমিক্যালি ফিরে লিখুন:
import json, uuid
def rotate_correlation_id(path: str) -> str:
"""JSON ফাইলে 'correlation_id' প্রতিস্থাপন বা যোগ করুন। নতুন UUID রিটার্ন করে।"""
try:
with open(path) as f:
data = json.load(f)
except FileNotFoundError:
data = {}
except json.JSONDecodeError as exc:
raise ValueError(f"{path!r}-এ অবৈধ JSON: {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_idAPI রেসপন্স থেকে UUID ইন্সপেক্ট করার জন্য প্রতিবার স্ক্রিপ্ট চালাতে না চাইলে, সরাসরি UUID ডিকোডার-এ পেস্ট করুন — এটি কোনো কোড ছাড়াই ভার্সন, ভ্যারিয়েন্ট এবং সব ফিল্ড দেখায়।
Python দিয়ে কমান্ড লাইনে UUID v4 তৈরি করা
Python-এর uuid মডিউলে python -m json.tool-এর মতো কোনো স্বতন্ত্র CLI সাবকমান্ড নেই, তবে একটি ওয়ান-লাইনার একই কাজ করে। শেল স্ক্রিপ্ট, CI পাইপলাইন এবং REPL না খুলে ডিসপোজেবল আইডেন্টিফায়ার দরকার হলে এগুলো কার্যকর।
# একটি UUID v4 python3 -c "import uuid; print(uuid.uuid4())" # 3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e # ড্যাশ-ছাড়া (হেক্স) ফরম্যাট — ফাইলনেম ও env ভ্যারের জন্য উপযোগী python3 -c "import uuid; print(uuid.uuid4().hex)" # 3b1f8a9d2c4e4f6a8b0d5e7c9f1a3d2e # ব্যাচ সিড স্ক্রিপ্টের জন্য ৫টি UUID তৈরি করুন python3 -c "import uuid; [print(uuid.uuid4()) for _ in range(5)]" # শেল ভ্যারিয়েবলে ব্যবহার করুন DEPLOY_ID=$(python3 -c "import uuid; print(uuid.uuid4())") echo "এই ID দিয়ে ডিপ্লয় করা হচ্ছে: $DEPLOY_ID"
uuidgen (একটি C ইউটিলিটি) UUID v4 মান তৈরি করে এবং বিশুদ্ধ শেল স্ক্রিপ্টের জন্য দ্রুততর। Python ওয়ান-লাইনার ব্যবহার করুন যখন আপনি ইতিমধ্যে Python-কেন্দ্রিক পরিবেশে আছেন এবং অ্যাপ্লিকেশন কোডে UUID তৈরির সামঞ্জস্য চান।uuid-utils দিয়ে উচ্চ-কার্যক্ষমতার UUID v4
স্ট্যান্ডার্ড লাইব্রেরির uuid.uuid4() বেশিরভাগ অ্যাপ্লিকেশনের জন্য যথেষ্ট দ্রুত — প্রতি কলে কয়েক মাইক্রোসেকেন্ডে এটি প্রতি সেকেন্ডে হাজার হাজার ID আরামদায়কভাবে পরিচালনা করে। যদি আপনি হাই-থ্রুপুট সার্ভিসের হট পাথে UUID তৈরি করেন (বাল্ক ইনসার্ট, স্কেলে প্রতি-ইভেন্ট টেলিমেট্রি, বা ভারী লোডে রিকোয়েস্ট ID জেনারেশন), uuid-utils হলো Rust-ব্যাকড একটি ড্রপ-ইন বিকল্প যা stdlib-এর প্রায় ১০গুণ গতিতে বেঞ্চমার্ক করে।
pip install uuid-utils
# uuid_utils হলো stdlib uuid মডিউলের ড্রপ-ইন বিকল্প import uuid_utils as uuid # stdlib-এর মতোই API request_id = uuid.uuid4() print(request_id) # 3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e print(str(request_id)) # ক্যানোনিকাল স্ট্রিং print(request_id.hex) # ড্যাশ-ছাড়া হেক্স print(request_id.version) # 4 # v7 (টাইম-অর্ডার্ড, DB প্রাইমারি কীর জন্য চমৎকার) সমর্থন করে time_ordered_id = uuid.uuid7() print(time_ordered_id) # বর্তমান-টাইমস্ট্যাম্প প্রিফিক্স দিয়ে শুরু
isinstance(u, uuid.UUID) চেক দরকার হয়, compat মোড ব্যবহার করুন: import uuid_utils.compat as uuid। Compat মোড ডিফল্টের চেয়ে সামান্য ধীর কিন্তু stdlib-এর চেয়ে এখনো দ্রুত।ডেটাক্লাস ও Pydantic মডেলে UUID v4
Python ডেটাক্লাস ও Pydantic মডেল উভয়ই নেটিভলি UUID ফিল্ড সমর্থন করে। UUID অটো-জেনারেটেড ডিফল্ট হিসেবে ব্যবহার করার সময় মূল প্যাটার্ন হলো ফাংশন রেফারেন্স পাস করা, কল ফলাফল নয় — অন্যথায় সব ইনস্ট্যান্স একই 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) # প্রতি ইনস্ট্যান্সে অনন্য
print(job2.job_id) # 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 স্বয়ংক্রিয়ভাবে uuid.UUID স্ট্রিং হিসেবে সিরিয়ালাইজ করেPython-এ UUID v4 তৈরিতে সাধারণ ভুল
আমি কোড রিভিউ ও প্রোডাকশন ইনসিডেন্টে এই চারটি প্যাটার্ন বারবার দেখেছি — এগুলো মিস করা সহজ কারণ এগুলো তৎক্ষণাৎ কোনো এরর উত্থাপন করে না।
সমস্যা: uuid.uuid4 (ফাংশন অবজেক্ট) default_factory-তে না মুড়িয়ে ডেটাক্লাস বা মডেলে ডিফল্ট মান হিসেবে পাস করা — Python ক্লাস ডেফিনিশন সময়ে একবার ডিফল্ট মূল্যায়ন করে, তাই সব ইনস্ট্যান্স একই UUID শেয়ার করে।
সমাধান: ডেটাক্লাসে default_factory=uuid.uuid4 বা Pydantic-এ Field(default_factory=uuid.uuid4) ব্যবহার করুন যাতে প্রতি ইনস্ট্যান্সে নতুন UUID তৈরি হয়।
@dataclass
class Session:
# ভুল: একবার মূল্যায়িত, সব ইনস্ট্যান্স এই UUID শেয়ার করে
session_id: uuid.UUID = uuid.uuid4()@dataclass
class Session:
# সঠিক: প্রতি ইনস্ট্যান্সে factory কল হয়
session_id: uuid.UUID = field(default_factory=uuid.uuid4)সমস্যা: uuid.UUID অবজেক্ট সাধারণ স্ট্রিংয়ের সমান নয়, তাই session_id == '3b1f8a9d-...' সর্বদা False রিটার্ন করে মান মিলেও — নীরবে লুকআপ ভেঙে দেয়।
সমাধান: সবসময় UUID-কে UUID-এর সাথে তুলনা করুন: তুলনার আগে স্ট্রিংটি uuid.UUID()-এ মুড়ুন, অথবা উভয় দিক str()-এ রূপান্তর করুন।
# মান মিলেও False রিটার্ন করে
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: # উভয়ই uuid.UUID
revoke_session(record)
# অথবা বাউন্ডারিতে সব কিছু স্ট্রিংয়ে নরমালাইজ করুন:
if str(record["session_id"]) == str(target):
revoke_session(record)সমস্যা: uuid_obj.hex হাইফেন ছাড়া ৩২-অক্ষরের স্ট্রিং তৈরি করে। ডাউনস্ট্রিম কোড যদি ক্যানোনিকাল ৩৬-অক্ষরের ড্যাশযুক্ত ফরম্যাট প্রত্যাশা করে (বেশিরভাগ API ও ডেটাবেস), এটি প্রত্যাখ্যান করবে বা নীরবে ভুল পার্স করবে।
সমাধান: কম্প্যাক্ট হেক্স ফরম্যাটের স্পষ্ট প্রয়োজন না থাকলে ক্যানোনিকাল ৩৬-অক্ষরের ফরম্যাটের জন্য str(uuid_obj) ব্যবহার করুন।
# "3b1f8a9d2c4e4f6a8b0d5e7c9f1a3d2e" সংরক্ষণ করে — ড্যাশ ছাড়া
payload = {"correlation_id": request_id.hex}# "3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e" সংরক্ষণ করে — স্ট্যান্ডার্ড ফরম্যাট
payload = {"correlation_id": str(request_id)}সমস্যা: random.random() ক্রিপ্টোগ্রাফিক্যালি নিরাপদ নয়, এবং secrets.token_hex(16) একটি ৩২-অক্ষরের হেক্স স্ট্রিং তৈরি করে যা বৈধ UUID নয় — এটিতে uuid.UUID() কল করলে ডাউনস্ট্রিম ভ্যালিডেটর ValueError উত্থাপন করবে।
সমাধান: যখনই রিসিভিং সিস্টেম UUID-ফরম্যাটেড আইডেন্টিফায়ার প্রত্যাশা করে তখন uuid.uuid4() ব্যবহার করুন। শুধু তখনই secrets.token_hex() ব্যবহার করুন যখন আপনার স্পষ্টভাবে UUID-আকৃতি নয় এমন র্যান্ডম টোকেন দরকার।
import random, secrets # UUID নয় — uuid.UUID() ভ্যালিডেশন ব্যর্থ হবে request_id = secrets.token_hex(16) # "a1b2c3d4e5f6..." session_id = str(random.random()) # "0.8273..." — আদৌ কাছাকাছি নয়
import uuid request_id = str(uuid.uuid4()) # "3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e" # বৈধ UUID v4, ক্রিপ্টোগ্রাফিক্যালি নিরাপদ
Python-এ UUID জেনারেশন পদ্ধতি — দ্রুত তুলনা
নিচের সব পদ্ধতি ১২৮-বিট আইডেন্টিফায়ার তৈরি করে কিন্তু এন্ট্রপি উৎস, গোপনীয়তা বৈশিষ্ট্য এবং তৃতীয়-পক্ষ ইনস্টল প্রয়োজন কিনা তাতে পার্থক্য আছে।
ওয়েব অ্যাপ্লিকেশন, বিতরণকৃত সিস্টেম এবং ডেটাবেস প্রাইমারি কীতে সাধারণ-উদ্দেশ্য অনন্য আইডেন্টিফায়ারের জন্য uuid.uuid4() ব্যবহার করুন যেখানে সর্টযোগ্যতা প্রয়োজন নেই। পরিচিত namespace ও name থেকে নির্ধারণযোগ্য ID-এর জন্য uuid.uuid5() (বা v3) ব্যবহার করুন — যেমন ক্যানোনিকাল URL-এর জন্য স্থিতিশীল ID তৈরি। ডেটাবেস ইন্ডেক্সের জন্য টাইম-অর্ডার্ড ID দরকার হলে uuid_utils.uuid7()-এ স্যুইচ করুন (উচ্চ ইনসার্ট রেটে B-tree ইন্ডেক্সে পেজ স্প্লিট এড়ায়)। জেনারেশন থ্রুপুট বটলনেক হলে uuid_utils.uuid4() ব্যবহার করুন।
UUID v4 বনাম UUID v7 — কোনটি ব্যবহার করবেন?
সবচেয়ে সাধারণ ব্যবহারিক প্রশ্ন হলো ডেটাবেস প্রাইমারি কীর জন্য UUID v4 বা নতুন UUID v7 ব্যবহার করা উচিত কিনা। সংক্ষিপ্ত উত্তর: ডিফল্টভাবে UUID v4 ব্যবহার করুন; শুধুমাত্র যখন ইন্ডেক্স ফ্র্যাগমেন্টেশন পরিমাপিত সমস্যা হয় তখন UUID v7-এ স্যুইচ করুন।
UUID v4 মান সম্পূর্ণ র্যান্ডম, যার মানে B-tree ইন্ডেক্সে ইনসার্টগুলো র্যান্ডম অবস্থানে পড়ে। মাঝারি ইনসার্ট রেটে (প্রতি সেকেন্ডে কয়েক শত থেকে কম হাজার) এটি ঠিক আছে — ইন্ডেক্স বাফার পুলে ফিট করে এবং র্যান্ডম রাইট সস্তা। খুব উচ্চ ইনসার্ট রেটে, র্যান্ডম প্লেসমেন্ট ঘন ঘন পেজ স্প্লিট ও ক্যাশ মিস সৃষ্টি করে, রাইট অ্যাম্প্লিফিকেশন বাড়ায় এবং কোয়েরি ধীর করে।
UUID v7 সবচেয়ে-উল্লেখযোগ্য বিটে মিলিসেকেন্ড-নির্ভুলতার Unix টাইমস্ট্যাম্প এম্বেড করে, তাই কাছাকাছি সময়ে ইনসার্ট হওয়া রোগুলো ইন্ডেক্সেও কাছাকাছি থাকে। এটি B-tree ইন্ডেক্সকে (PostgreSQL, MySQL, SQLite) অটো-ইনক্রিমেন্ট পূর্ণসংখ্যার মতো আচরণ দেয়: নতুন রোগুলো সর্বদা ইন্ডেক্সের শেষে যোগ হয়, পেজ স্প্লিট দূর করে। ট্রেডঅফ হলো UUID v7 একটি টাইমস্ট্যাম্প এনকোড করে, যা তৈরির সময় ফাঁস করে — ব্যবহারকারী-মুখী ID-এর জন্য এড়িয়ে চলুন যেখানে তৈরির সময় সংবেদনশীল।
Python-এ, UUID v7 এখনো স্ট্যান্ডার্ড লাইব্রেরিতে নেই (Python 3.12 পর্যন্ত)। pip install uuid-utils দিয়ে তৈরি করুন এবং uuid_utils.uuid7() কল করুন। এটি uuid.UUID-এর মতোই অ্যাট্রিবিউট সেট সহ একটি অবজেক্ট রিটার্ন করে, তাই v4 থেকে মাইগ্রেশন ID ফ্যাক্টরিতে এক লাইনের পরিবর্তন।
কোনো Python সেটআপ ছাড়া এক-ক্লিক বিকল্পের জন্য, আপনার UUID স্ট্রিং UUID v4 জেনারেটর ও ভ্যালিডেটর-এ পেস্ট করুন — এটি ব্রাউজারে তৈরি করে, যাচাই করে এবং সব ফিল্ড ডিকোড করে।
সচরাচর জিজ্ঞাসা
Python-এ UUID v4 কীভাবে তৈরি করব?
Python-এর বিল্ট-ইন uuid মডিউল থেকে uuid.uuid4() কল করুন। এটি একটি UUID অবজেক্ট রিটার্ন করে — টেক্সট উপস্থাপনা দরকার হলে str() দিয়ে রূপান্তর করুন। মডিউলটি স্ট্যান্ডার্ড লাইব্রেরির সাথেই আসে, তাই কোনো pip install প্রয়োজন নেই।
import uuid session_id = uuid.uuid4() print(session_id) # যেমন: 3b1f8a9d-2c4e-4f6a-8b0d-5e7c9f1a3d2e print(str(session_id)) # একই ক্যানোনিকাল স্ট্রিং print(session_id.hex) # 3b1f8a9d2c4e4f6a8b0d5e7c9f1a3d2e (ড্যাশ ছাড়া)
uuid.uuid4() এবং str(uuid.uuid4())-এর মধ্যে পার্থক্য কী?
uuid.uuid4() একটি UUID অবজেক্ট রিটার্ন করে যার .hex, .bytes, .int এবং .version-এর মতো অ্যাট্রিবিউট আছে। str(uuid.uuid4()) সেই অবজেক্টকে তৎক্ষণাৎ ৩৬-অক্ষরের ক্যানোনিকাল স্ট্রিংয়ে রূপান্তর করে, অবজেক্টটি বাদ দিয়ে। একাধিক উপস্থাপনা দরকার হলে অবজেক্ট রাখুন; JSON পেলোড, ডেটাবেস বা HTTP হেডারে পাস করার সময় স্ট্রিংয়ে রূপান্তর করুন।
import uuid u = uuid.uuid4() print(type(u)) # <class 'uuid.UUID'> print(u.version) # 4 print(u.hex) # 32-অক্ষরের হেক্স, ড্যাশ ছাড়া print(u.bytes) # 16-বাইট বাইনারি print(str(u)) # ড্যাশ সহ ক্যানোনিকাল 36-অক্ষরের স্ট্রিং
uuid.uuid4() কি ক্রিপ্টোগ্রাফিক্যালি নিরাপদ?
হ্যাঁ। Python-এর uuid.uuid4() অভ্যন্তরীণভাবে os.urandom() ব্যবহার করে, যা অপারেটিং সিস্টেমের ক্রিপ্টোগ্রাফিক্যালি নিরাপদ র্যান্ডম নম্বর জেনারেটর থেকে পড়ে (Linux/macOS-এ /dev/urandom, Windows-এ CryptGenRandom)। ১২২টি র্যান্ডম বিট যেকোনো বাস্তব কাজের জন্য কোলিশনের সম্ভাবনা নগণ্য করে তোলে। এটিকে random.random()-এর সাথে গুলিয়ে ফেলবেন না, যেটি ক্রিপ্টোগ্রাফিক্যালি নিরাপদ নয়।
import uuid, os # uuid4 অভ্যন্তরীণভাবে os.urandom(16) কল করে raw = os.urandom(16) # uuid4 রিটার্ন করার আগে version ও variant বিট সেট করে u = uuid.UUID(bytes=raw, version=4) print(u) # র্যান্ডম বাইট থেকে বৈধ v4 UUID
Python-এ কীভাবে যাচাই করব যে একটি স্ট্রিং বৈধ UUID v4?
uuid.UUID() দিয়ে পার্স করুন এবং .version অ্যাট্রিবিউট চেক করুন। স্ট্রিংটি বৈধ UUID না হলে uuid.UUID() একটি ValueError উত্থাপন করে — অবৈধ ইনপুট হ্যান্ডেল করতে এটি ধরুন। এটি ফরম্যাট (ড্যাশ, দৈর্ঘ্য) সঠিক কিনা তাও যাচাই করে।
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("এটি-uuid-নয়")) # False
print(is_valid_uuid4("3b1f8a9d-2c4e-1f6a-8b0d-5e7c9f1a3d2e")) # False (v1, v4 নয়)Python থেকে PostgreSQL বা SQLite ডেটাবেসে UUID কীভাবে সংরক্ষণ করব?
PostgreSQL-এ (psycopg2 বা asyncpg দিয়ে), UUID অবজেক্ট সরাসরি পাস করুন — ড্রাইভার এটি নেটিভ UUID টাইপে রূপান্তর করে। SQLite-এ, যার কোনো নেটিভ UUID টাইপ নেই, str(uuid_obj) ব্যবহার করে TEXT হিসেবে বা uuid_obj.bytes ব্যবহার করে BLOB হিসেবে সংরক্ষণ করুন। SQLAlchemy-তে একটি UUID কলাম টাইপ আছে যা বিভিন্ন ডায়ালেক্টে এটি স্বয়ংক্রিয়ভাবে পরিচালনা করে।
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()
# সংরক্ষিত স্ট্রিং থেকে UUID অবজেক্ট পুনর্নির্মাণ করুন
retrieved_id = uuid.UUID(row[0])
print(retrieved_id.version) # 4Python-এ একসাথে একাধিক UUID তৈরি করা কি সম্ভব?
হ্যাঁ — লিস্ট কম্প্রিহেনশন বা জেনারেটর ব্যবহার করুন। uuid.uuid4()-এর প্রতিটি কল স্বাধীন এবং একটি আলাদা মান তৈরি করার নিশ্চয়তা দেয়। বাল্ক জেনারেশনে থ্রুপুট গুরুত্বপূর্ণ হলে, uuid-utils (Rust-ব্যাকড) স্ট্যান্ডার্ড লাইব্রেরির চেয়ে প্রায় ১০গুণ দ্রুত।
import uuid
# একটি ব্যাচ রিকোয়েস্টের জন্য ৫টি অনন্য ট্রেস ID তৈরি করুন
trace_ids = [str(uuid.uuid4()) for _ in range(5)]
for tid in trace_ids:
print(tid)
# প্রতিটি লাইন আলাদা UUID v4সম্পর্কিত টুল
- →UUID v4 জেনারেটর — ব্রাউজারে তাৎক্ষণিকভাবে UUID v4 মান তৈরি করুন — কোনো Python পরিবেশের প্রয়োজন নেই। একটি মান কপি করুন বা একসাথে শত শত তৈরি করুন।
- →UUID v7 জেনারেটর — টাইম-অর্ডার্ড UUID v7 মান তৈরি করুন — তৈরির সময় অনুযায়ী সর্টযোগ্য, ডেটাবেস প্রাইমারি কীর জন্য আদর্শ যেখানে ইন্ডেক্স ফ্র্যাগমেন্টেশন গুরুত্বপূর্ণ।
- →UUID ডিকোডার — যেকোনো UUID পরীক্ষা করুন — ভার্সন, ভ্যারিয়েন্ট, টাইমস্ট্যাম্প (v1/v7), এবং নোড ফিল্ড — নিজে পার্সার না লিখেই।
- →JWT ডিকোডার — JWT টোকেন ডিকোড ও পরীক্ষা করুন, যেগুলো প্রায়ই UUID সাবজেক্ট ক্লেম (sub) বা jti আইডেন্টিফায়ার বহন করে সেশন UUID-এর পাশাপাশি।
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.