Authentication ও Caching basics: API-কে সুরক্ষিত ও দ্রুত করা

নিরাপদ ও দ্রুত API (Series 09, Episode 04)

🟡 INTERMEDIATE Series 09 — Notebook থেকে Production AI Episode 04 / 09

📑 এই পর্বে যা যা আছে

🎬 ১. গল্প: "আমার API-এর বিল ৫০ হাজার টাকা কেন?"

Rahim তার flagship-এর /analyze endpoint (যেটা ভেতরে একটা LLM API call করে) publicly ছেড়ে দিয়েছিল — কোনো লক ছাড়াই। এক সপ্তাহ পর Boss একটা invoice নিয়ে হাজির:

💼 Boss: "আমাদের OpenAI বিল হঠাৎ ৫০ হাজার টাকা! আর কেউ একজন একই request সেকেন্ডে ১০০ বার পাঠাচ্ছে। এটা কি normal?"

Maya দেখে বলল: "তোমার API-এ কোনো authentication নেই — যে কেউ ব্যবহার করছে। কোনো caching নেই — একই JD ১০০ বার এলে ১০০ বারই LLM call হচ্ছে (টাকা পুড়ছে)। আর কোনো rate limit নেই — একজন সবটা দখল করছে। এই তিনটা ঠিক করলেই বিল আর অপব্যবহার দুটোই কমবে।"

২. সমস্যা: open API = অপব্যবহার + ধীর + খরচ

একটা লক-ছাড়া AI API তিনটা ঝুঁকি বহন করে: (১) কে ব্যবহার করছে জানি না (security), (২) একই কাজ বারবার করছি (latency + cost), (৩) একজন সব resource খেয়ে ফেলছে (availability)। আজ তিনটারই বেসিক সমাধান শিখব।

🛡️ ৩. তিনটা রক্ষাকবচ: Auth, Caching, Rate limiting

রক্ষাকবচকী ঠেকায়সহজ analogy
Authenticationঅচেনা লোকের ব্যবহারদরজায় তালা + চাবি (API key)
Cachingএকই কাজ বারবারউত্তর মুখস্থ রাখা — আবার জিজ্ঞেস করলে ভাবতে হয় না
Rate limitingএকজনের অতিরিক্ত চাপ"প্রতি মিনিটে ৬০ বার" — লাইনে দাঁড়ানোর নিয়ম

🔑 ৪. Authentication: API key দিয়ে দরজা বন্ধ

সবচেয়ে সহজ ও junior-এর জন্য যথেষ্ট উপায়: প্রতিটা request-এ একটা secret API key header চাওয়া। ঠিক key না থাকলে 401 Unauthorized

# app/auth.py from fastapi import Header, HTTPException, Depends from app.config import settings def verify_api_key(x_api_key: str = Header(...)): # client প্রতিটা request-এ header পাঠাবে: X-API-Key: <key> if x_api_key != settings.api_key: raise HTTPException(status_code=401, detail="Invalid API key") return True # app/main.py — endpoint-এ dependency হিসেবে যোগ করা from fastapi import Depends from app.auth import verify_api_key @app.post("/analyze", dependencies=[Depends(verify_api_key)]) def analyze(jd: JobDescription): ...

এখন key ছাড়া কেউ /analyze ছুঁতে পারবে না। Key আসে settings থেকে (মনে আছে? secret env-এ, কোডে নয়)।

🧠 ৫. তিন স্তরে: authentication বনাম authorization

Level 1 — intuition: Authentication = "তুমি কে?" (পরিচয় যাচাই)। Authorization = "তোমার কী কী করার অনুমতি আছে?" (permission)। বাড়ির চাবি থাকা মানে তুমি ঢুকতে পারো (auth); কিন্তু বাড়ির মালিকের locker খোলার অনুমতি আছে কিনা — সেটা authorization।
Level 2 — technical: junior-level ML API-তে সাধারণত API key দিয়ে authentication-ই যথেষ্ট। বড় system-এ এর সাথে যোগ হয় JWT token, OAuth, আর per-user role (authorization)।
Level 3 — engineer perspective: engineer আলাদা client-কে আলাদা key দেয় (mobile app, internal dashboard), যাতে কেউ অপব্যবহার করলে শুধু তার key বন্ধ করা যায় — পুরো service নয়। এটাকে বলে key rotation ও per-client tracking।

৬. Caching: একই প্রশ্নে বারবার model চালাব না

কেন caching? একটা LLM call ধরো ২ সেকেন্ড লাগে ও ৫ টাকা খরচ করে। যদি ১০০ user একই JD পাঠায়, cache ছাড়া = ২০০ সেকেন্ড + ৫০০ টাকা। Cache থাকলে = প্রথমবার একবার, বাকি ৯৯ বার instant + free।

# সহজতম in-memory cache (একই input -> সংরক্ষিত output) from functools import lru_cache @lru_cache(maxsize=1000) def analyze_cached(jd_text: str) -> str: # ব্যয়বহুল কাজ (LLM/model) — একই jd_text-এ একবারই চলবে return run_expensive_analysis(jd_text)

বড়/একাধিক server-এর জন্য in-memory যথেষ্ট নয় (প্রতিটা server-এর আলাদা cache)। তখন Redis ব্যবহার করা হয় — একটা shared cache, যা সব server share করে:

# Redis দিয়ে shared cache (ধারণা) import redis, hashlib, json r = redis.Redis(host="localhost", port=6379) def analyze_with_cache(jd_text: str) -> dict: key = "jd:" + hashlib.sha256(jd_text.encode()).hexdigest() cached = r.get(key) if cached: # cache HIT -> দ্রুত ও free return json.loads(cached) result = run_expensive_analysis(jd_text) # cache MISS r.setex(key, 3600, json.dumps(result)) # 1 ঘণ্টা রাখি return result

🤔 ৭. Caching কখন করবে, কখন করবে না

✅ Cache করা ভালো
• একই input বারবার আসে
• output deterministic/স্থিতিশীল
• কাজটা ব্যয়বহুল (LLM, বড় model)
• সামান্য পুরনো উত্তর গ্রহণযোগ্য
❌ Cache করা বিপজ্জনক
• output সবসময় fresh লাগবে (real-time price)
• প্রতিটা input প্রায় unique
• personalized/sensitive data (অন্যের উত্তর ফাঁস হতে পারে)
• output প্রতিবার আলাদা হওয়া উচিত
সতর্কতা: user-specific data cache করলে cache key-তে user id রাখো, নাহলে একজনের উত্তর আরেকজন পেয়ে যাবে — মারাত্মক bug ও privacy breach।

🚦 ৮. Rate limiting: এক client যেন সব দখল না করে

Rate limiting মানে "একটা client প্রতি মিনিটে কতবার call করতে পারবে" তার সীমা। এতে একজন খারাপ/বাগি client পুরো service ধীর করে দিতে পারে না। FastAPI-তে slowapi দিয়ে সহজে করা যায়:

# pip install slowapi from slowapi import Limiter from slowapi.util import get_remote_address limiter = Limiter(key_func=get_remote_address) @app.post("/analyze") @limiter.limit("60/minute") # প্রতি IP প্রতি মিনিটে ৬০ বার def analyze(request: Request, jd: JobDescription): ...

সীমা ছাড়ালে client পায় 429 Too Many Requests — service বাঁচে।

🧪 ৯. Experiment: cache hit/miss ও ভুল key

🇧🇩 ১০. বাংলাদেশের বাস্তব প্রসঙ্গ (LLM খরচ)

বাংলাদেশে অনেক startup ডলারে LLM API-এর বিল দেয় — টাকায় হিসাব করলে খরচ চোখে পড়ার মতো। একটা customer support bot যদি একই ধরনের প্রশ্নের উত্তর প্রতিবার নতুন করে LLM থেকে আনে, বিল লাফিয়ে বাড়ে। Caching দিয়ে common প্রশ্নের উত্তর জমিয়ে রাখলে খরচ নাটকীয়ভাবে কমে — এটা সরাসরি টাকার হিসাব, তাই এই skill business-এ অত্যন্ত মূল্যবান।

👷 ১১. AI Engineer perspective: latency ও cost

Must Know: API key auth, simple caching ধারণা, rate limit ধারণা। Good to Know: Redis cache, cache invalidation, JWT। Learn Later: OAuth2, API gateway, per-tenant quota।

💼 ১২. Boss Question

💼 Boss: "এই তিন জিনিস (auth, cache, rate limit) যোগ করতে সময় লাগবে। এতে কী পাব?"

উত্তর: সোজা হিসাব — auth ছাড়া যে কেউ আমাদের paid LLM পুড়িয়ে বিল বাড়াতে পারত, এখন পারবে না (টাকা বাঁচল)। Caching-এ common প্রশ্নে LLM call ৭০-৮০% কমতে পারে (আরও টাকা বাঁচল + উত্তর দ্রুত)। Rate limit-এ একজন খারাপ client পুরো service ফেলে দিতে পারবে না (uptime বাঁচল)। মানে — এই সময়টা বিনিয়োগ, খরচ নয়।

🔎 ১৩. Job Requirement Decoder: "API security, caching & optimization"

  1. কী বোঝায়? API-কে নিরাপদ (auth), সাশ্রয়ী ও দ্রুত (caching), স্থিতিশীল (rate limit) করা।
  2. কেন চায়? production API-তে অপব্যবহার, খরচ ও ধীরগতি বাস্তব সমস্যা।
  3. কোন সমস্যা সমাধান করে? unauthorized ব্যবহার, বাড়তি বিল, ধীর response, একজনের দখল।
  4. Junior-এর কী জানা লাগে? API key auth, একটা simple cache, rate limit-এর ধারণা।
  5. এখনই কী master লাগে না? OAuth2/OIDC, distributed rate limit, CDN edge caching — পরে।
  6. GitHub-এ কীভাবে দেখাবে? auth dependency, cache layer, README-তে "কেন cache/rate limit"।
  7. Interview-তে কী জিজ্ঞেস করতে পারে? "API কীভাবে secure করবে?", "কী cache করবে, কী করবে না?", "user data cache করার ঝুঁকি?", "authentication vs authorization?"

⚠️ ১৪. সাধারণ ভুল

ভুল ১: paid LLM endpoint auth ছাড়া public করা। → বিল বোমা।

ভুল ২: user-specific উত্তর user id ছাড়া cache করা। → একজনের উত্তর আরেকজন পায় (privacy breach)।

ভুল ৩: সব কিছু cache করা, এমনকি যা fresh লাগবে। → পুরনো/ভুল data।

ভুল ৪: API key কোডে/URL query-তে পাঠানো। → header-এ পাঠাও, log-এ key লিখো না।

ভুল ৫: cache-এর expiry (TTL) না রাখা। → data পুরনো হয়ে বাসি হয়ে যায়।

🎤 ১৫. Interview Prep

প্রশ্ন ১: "একটা inference API কীভাবে secure করবে?"
উত্তর: API key/token auth (header-এ), secret env-এ, HTTPS, rate limit, প্রয়োজনে per-client key।

প্রশ্ন ২: "কোন response cache করবে, কোনটা করবে না?"
উত্তর: deterministic + ব্যয়বহুল + repeat হয় → cache; real-time/personalized/sensitive → সাবধানে বা না।

প্রশ্ন ৩: "in-memory cache বনাম Redis কখন?"
উত্তর: single instance → in-memory যথেষ্ট; multiple instance/scale → Redis (shared)।

প্রশ্ন ৪: "rate limiting কেন দরকার?"
উত্তর: একজন client-এর অতিরিক্ত load থেকে service রক্ষা; abuse ও খরচ নিয়ন্ত্রণ।

✍️ ১৬. হাতে-কলমে

Mini exercise:
১. তোমার /analyze (বা /predict)-এ X-API-Key auth যোগ করো।
২. lru_cache দিয়ে ব্যয়বহুল অংশ cache করো; log-এ HIT/MISS দেখাও।
৩. একই input দু'বার পাঠিয়ে latency-র পার্থক্য মাপো (time দিয়ে)।
৪. slowapi দিয়ে 10/minute rate limit বসাও; loop-এ পাঠিয়ে 429 দেখো।
৫. ভাবো: তোমার flagship-এ কোন endpoint cache করা নিরাপদ, কোনটা নয়? এক লাইনে লেখো কেন।

🚀 ১৭. Project Connection ও পরের পর্ব

আমাদের flagship "Bangladesh Tech Career Assistant" এখন নিরাপদ (API key), সাশ্রয়ী (JD analysis cached), ও স্থিতিশীল (rate limited)। কোড এখন সত্যিই একটা দায়িত্বশীল production service।

✓ API key authentication, ✓ caching (in-memory + Redis ধারণা), ✓ rate limiting — API এখন প্রস্তুত বাইরের দুনিয়ায় যাওয়ার জন্য।
কিন্তু একটা বড় প্রশ্ন বাকি — "আমার laptop-এ চলছে, কিন্তু server-এ চলবে তো?" পরের episode-এ আমরা Docker শিখব: পুরো service-কে একটা container-এ প্যাক করা, যাতে যেকোনো জায়গায় হুবহু একইভাবে চলে।
© 2025 Sheikh Thanbir Alam. All Rights Reserved. thanbirtamim.github.io
এই লেখা মূল লেখকের সম্পত্তি — লিখিত অনুমতি ছাড়া কপি করে অন্য কোনো ওয়েবসাইট, ব্লগ, বই বা প্ল্যাটফর্মে প্রকাশ/বিতরণ করা কঠোরভাবে নিষিদ্ধ। Content may not be copied or republished without permission.