FastAPI এর Dependency Injection

Web Development - ফাস্টএপিআই (FastAPI)
239

Dependency Injection (DI) হলো একটি ডিজাইন প্যাটার্ন যা অ্যাপ্লিকেশনে নির্দিষ্ট ডিপেনডেন্সি (যেমন, ডাটাবেস সংযোগ, লগিং, থার্ড-পার্টি API কল) সহজে এবং পরিষ্কারভাবে ইনজেক্ট করার জন্য ব্যবহৃত হয়। FastAPI তে Dependency Injection খুবই সহজ এবং শক্তিশালী, যা কোডকে মডুলার, পুনঃব্যবহারযোগ্য এবং পরীক্ষণযোগ্য করে তোলে।

FastAPI তে Dependency Injection ব্যবস্থাপনা মূলত Depends ক্লাস ব্যবহার করে করা হয়, যা dependencies কে নির্দিষ্ট এন্ডপয়েন্টে ইনজেক্ট করে।


Step 1: Dependency Injection এর মৌলিক ধারণা

Dependency Injection একটি প্যাটার্ন যেখানে একটি ক্লাস বা ফাংশন নির্দিষ্ট একটি ডিপেনডেন্সি গ্রহণ করে, যা তা নিজে তৈরি না করে, বরং বাইরের কোন উৎস থেকে পাওয়া যায়। FastAPI তে এটি Depends ডেকোরেটরের মাধ্যমে করা হয়।

উদাহরণ:

from fastapi import FastAPI, Depends

app = FastAPI()

# একটি Dependency ফাংশন
def get_query_param(q: str = None):
    return q

# Dependency ইনজেকশন ব্যবহার করে API এন্ডপয়েন্ট
@app.get("/items/")
def read_item(query: str = Depends(get_query_param)):
    return {"query": query}

এখানে:

  • get_query_param হলো একটি ডিপেনডেন্সি ফাংশন, যা q কোয়েরি প্যারামিটার গ্রহণ করে এবং তা Depends ডেকোরেটরের মাধ্যমে এন্ডপয়েন্টে ইনজেক্ট করা হয়।
  • Depends(get_query_param) ডেকোরেটর ব্যবহার করে query প্যারামিটার ইনজেক্ট করা হচ্ছে।

রিকোয়েস্ট উদাহরণ:

GET /items/?q=example

রেসপন্স:

{
  "query": "example"
}

Step 2: Dependency Injection with Class-Based Dependencies

FastAPI তে class-based dependencies ও ব্যবহার করা যেতে পারে, যেখানে একটি ক্লাসকে ডিপেনডেন্সি হিসেবে ব্যবহার করা হয়।

উদাহরণ: ক্লাস ব্যবহার করে Dependency Injection

from fastapi import FastAPI, Depends

class QueryParams:
    def __init__(self, q: str = None):
        self.q = q

app = FastAPI()

@app.get("/items/")
def read_item(params: QueryParams = Depends(QueryParams)):
    return {"query": params.q}

এখানে:

  • QueryParams হলো একটি ক্লাস, যা q কোয়েরি প্যারামিটার গ্রহণ করে।
  • Depends(QueryParams) ব্যবহার করে ক্লাস ইনস্ট্যান্স এন্ডপয়েন্টে ইনজেক্ট করা হয়।

রিকোয়েস্ট উদাহরণ:

GET /items/?q=search-term

রেসপন্স:

{
  "query": "search-term"
}

Step 3: Dependency Injection with Dependency Sharing

FastAPI তে dependency sharing সম্ভব, অর্থাৎ এক ডিপেনডেন্সি ফাংশনকে একাধিক এন্ডপয়েন্টে পুনঃব্যবহার করা যায়। আপনি একটি ডিপেনডেন্সি তৈরি করে সেটি বিভিন্ন এন্ডপয়েন্টে ইনজেক্ট করতে পারেন।

উদাহরণ: একাধিক এন্ডপয়েন্টে এক ডিপেনডেন্সি ব্যবহার

from fastapi import FastAPI, Depends

app = FastAPI()

# সাধারণ dependency
def common_parameters(q: str = None, limit: int = 10):
    return {"q": q, "limit": limit}

# প্রথম এন্ডপয়েন্ট
@app.get("/items/")
def read_items(commons: dict = Depends(common_parameters)):
    return {"query": commons["q"], "limit": commons["limit"]}

# দ্বিতীয় এন্ডপয়েন্ট
@app.get("/users/")
def read_users(commons: dict = Depends(common_parameters)):
    return {"query": commons["q"], "limit": commons["limit"]}

এখানে common_parameters ডিপেনডেন্সি ফাংশনটি দুইটি এন্ডপয়েন্টে ব্যবহার করা হয়েছে।

রিকোয়েস্ট উদাহরণ:

GET /items/?q=test&limit=5
GET /users/?q=user_test&limit=3

রেসপন্স:

{
  "query": "test",
  "limit": 5
}
{
  "query": "user_test",
  "limit": 3
}

Step 4: Dependency Injection for Authentication and Authorization

Authentication এবং Authorization ব্যবস্থাপনা করার জন্যও FastAPI তে Dependency Injection ব্যবহার করা যায়। এক্ষেত্রে, আপনি একটি ডিপেনডেন্সি ফাংশন তৈরি করতে পারেন যা ইউজারের অথেনটিকেশন টোকেন যাচাই করবে।

উদাহরণ: Authentication Dependency

from fastapi import FastAPI, Depends, HTTPException, status

app = FastAPI()

def get_current_user(token: str = Depends()):
    if token != "valid_token":
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token")
    return {"user": "admin"}

@app.get("/protected/")
def protected_route(user: dict = Depends(get_current_user)):
    return {"message": f"Hello, {user['user']}"}

এখানে:

  • get_current_user হলো একটি ডিপেনডেন্সি ফাংশন যা ইউজারের টোকেন যাচাই করে।
  • Depends(get_current_user) ব্যবহার করে ইউজারের তথ্য এন্ডপয়েন্টে ইনজেক্ট করা হয়।

রিকোয়েস্ট উদাহরণ (অথেনটিকেশন টোকেনের সাথে):

GET /protected/?token=valid_token

রেসপন্স:

{
  "message": "Hello, admin"
}

রিকোয়েস্ট উদাহরণ (অথেনটিকেশন টোকেন ছাড়া):

GET /protected/?token=invalid_token

রেসপন্স:

{
  "detail": "Invalid token"
}

Step 5: Using Depends for Request and Response Manipulation

FastAPI তে আপনি Request এবং Response অবজেক্ট পরিচালনার জন্যও ডিপেনডেন্সি ব্যবহার করতে পারেন। উদাহরণস্বরূপ, আপনি একটি ডিপেনডেন্সি তৈরি করে রিকোয়েস্ট হেডার বা রেসপন্স মডিফাই করতে পারেন।

উদাহরণ: Request Header Manipulation

from fastapi import FastAPI, Depends, Request

app = FastAPI()

def get_user_agent(request: Request):
    user_agent = request.headers.get('User-Agent')
    return user_agent

@app.get("/user-agent/")
def get_user_agent_info(user_agent: str = Depends(get_user_agent)):
    return {"User-Agent": user_agent}

এখানে, get_user_agent ডিপেনডেন্সি ফাংশন রিকোয়েস্ট হেডার থেকে User-Agent মান গ্রহণ করছে।

রিকোয়েস্ট উদাহরণ:

GET /user-agent/ (যেখানে হেডারে User-Agent তথ্য থাকবে)

রেসপন্স:

{
  "User-Agent": "Mozilla/5.0"
}

FastAPI তে Dependency Injection ব্যবস্থাপনা অত্যন্ত শক্তিশালী এবং মডুলার কোড লেখার জন্য একটি কার্যকর পদ্ধতি। Depends ডেকোরেটরের মাধ্যমে ডিপেনডেন্সি ইনজেকশন ব্যবহার করে, আপনি কোডের পুনঃব্যবহারযোগ্যতা, নিরাপত্তা এবং কার্যক্ষমতা বৃদ্ধি করতে পারেন। এটি আপনার অ্যাপ্লিকেশনকে আরও পরিষ্কার, মেইনটেইনেবল এবং পরীক্ষণযোগ্য করে তোলে।

Content added By

Dependency Injection কী এবং কিভাবে কাজ করে?

172

Dependency Injection (DI) হল একটি ডিজাইন প্যাটার্ন যা কোডে ডিপেনডেন্সি (যেমন, সার্ভিস, লাইব্রেরি, ডাটাবেস সেশনের মত বাহ্যিক উপাদান) ইনজেক্ট করতে ব্যবহৃত হয়, যাতে কোডের বিভিন্ন অংশের মধ্যে দৃঢ় সংযুক্তি (tight coupling) না থাকে। এটি কোডকে আরো মডুলার, টেস্টেবল, এবং পুনঃব্যবহারযোগ্য করে তোলে।

FastAPI তে Dependency Injection খুব সহজ এবং শক্তিশালী ভাবে ব্যবহৃত হয়। FastAPI স্বয়ংক্রিয়ভাবে ডিপেনডেন্সি ইনজেকশন করে, যা আপনার API-এর কোডকে পরিষ্কার, সংক্ষিপ্ত, এবং সহজবোধ্য করে তোলে।


Dependency Injection কী?

Dependency Injection (DI) হল এমন একটি পদ্ধতি যেখানে কোন ক্লাস বা ফাংশনের ডিপেনডেন্সি (যেমন: ডাটাবেস কানেকশন, লগিং, বা ইউটিলিটি ফাংশন) বাইরে থেকে সরবরাহ করা হয়, যেটি ক্লাস বা ফাংশন নিজে তৈরি বা পরিচালনা করে না। এর ফলে, কোডের পুনঃব্যবহারযোগ্যতা বৃদ্ধি পায় এবং টেস্টিং সহজ হয়।

Dependency Injection FastAPI-তে কিভাবে কাজ করে?

FastAPI তে, আপনি Dependency তৈরি করেন এবং তারপর সেই ডিপেনডেন্সি আপনার API রাউটস বা এন্ডপয়েন্টে ব্যবহার করতে পারেন। FastAPI Dependency Injection এর জন্য একটি খুব শক্তিশালী এবং স্বয়ংক্রিয় সিস্টেম প্রদান করে।

উদাহরণ:

from fastapi import FastAPI, Depends

app = FastAPI()

# Dependency তৈরি
def get_query_param(q: str = "default"):
    return {"query": q}

@app.get("/items/")
def read_item(query: dict = Depends(get_query_param)):
    return query

এখানে:

  • get_query_param হল একটি ডিপেনডেন্সি ফাংশন।
  • Depends(get_query_param) ব্যবহার করে FastAPI স্বয়ংক্রিয়ভাবে এই ফাংশনটি ইনজেক্ট করে।

রিকোয়েস্ট উদাহরণ:

GET /items/?q=example

রেসপন্স:

{
  "query": "example"
}

FastAPI তে Dependency Injection কিভাবে কাজ করে?

  1. Dependency ফাংশন তৈরি করা:
    প্রথমে আপনি একটি ফাংশন বা ক্লাস তৈরি করেন যা আপনার ডিপেনডেন্সি সরবরাহ করবে। এটি সাধারণত Depends দ্বারা নির্দেশিত হয়। এই ফাংশন বা ক্লাসটি রিকোয়েস্টের আগে FastAPI এর মাধ্যমে ইনজেক্ট করা হয়।
  2. Depends ব্যবহার:
    Depends ব্যবহার করে আপনি ফাংশন বা ক্লাসে ডিপেনডেন্সি ইনজেক্ট করতে পারেন। FastAPI তারপর আপনার ডিপেনডেন্সি স্বয়ংক্রিয়ভাবে ইনস্ট্যান্সিয়েট এবং ইনজেক্ট করবে, তাই আপনাকে এটির জন্য নিজে কোড লিখতে হবে না।

Dependency Injection এর সুবিধা

  1. কোডের পুনঃব্যবহারযোগ্যতা:
    একাধিক এন্ডপয়েন্টে একই ডিপেনডেন্সি ব্যবহার করা যায়, যেমন ডাটাবেস কানেকশন বা লগিং ফাংশন।
  2. টেস্টিং সহজ করা:
    ডিপেনডেন্সি আলাদা করা থাকায় আপনি সহজেই ইউনিট টেস্ট করতে পারবেন।
  3. কোডের পরিষ্কারতা এবং সংক্ষিপ্ততা:
    ডিপেনডেন্সি আলাদাভাবে রক্ষা করা থাকলে কোড আরও পরিষ্কার, মডুলার এবং সহজবোধ্য হয়।

FastAPI তে Dependency Injection এর আরও উদাহরণ

১. ডাটাবেস কানেকশন ডিপেনডেন্সি:

from fastapi import FastAPI, Depends

app = FastAPI()

# Dummy Database dependency
def get_db():
    db = "Database connection"  # এখানে ডাটাবেস কানেকশন তৈরি করতে হবে
    try:
        yield db
    finally:
        pass  # এখানে ডাটাবেস কানেকশন বন্ধ করার কোড হবে

@app.get("/items/")
def get_items(db: str = Depends(get_db)):
    return {"db_connection": db}

এখানে, get_db ফাংশনটি একটি ডিপেনডেন্সি তৈরি করেছে, যা ডাটাবেস কানেকশন সরবরাহ করে। FastAPI Depends(get_db) ব্যবহার করে ডিপেনডেন্সিটি ইনজেক্ট করছে।

রিকোয়েস্ট উদাহরণ:

GET /items/

রেসপন্স:

{
  "db_connection": "Database connection"
}

২. কাস্টম ডিপেনডেন্সি: লগিং

from fastapi import FastAPI, Depends

app = FastAPI()

# Dependency function for logging
def get_logger():
    class Logger:
        def log(self, message: str):
            print(f"LOG: {message}")
    
    return Logger()

@app.get("/log/")
def log_message(logger: Logger = Depends(get_logger)):
    logger.log("This is a log message.")
    return {"message": "Logged successfully"}

এখানে, get_logger একটি কাস্টম ডিপেনডেন্সি যা একটি Logger ক্লাসের ইনস্ট্যান্স সরবরাহ করে। এই ইনস্ট্যান্সটি log_message ফাংশনে ইনজেক্ট করা হয়।

রিকোয়েস্ট উদাহরণ:

GET /log/

রেসপন্স:

{
  "message": "Logged successfully"
}

এটি কনসোলে "LOG: This is a log message." প্রিন্ট করবে।


Dependency Injection এর ডিপেনডেন্সি (চেইনিং ডিপেনডেন্সি)

FastAPI তে একটি ডিপেনডেন্সির মধ্যে অন্য একটি ডিপেনডেন্সি ইনজেক্ট করা যায়। এটি চেইনিং ডিপেনডেন্সি নামে পরিচিত।

from fastapi import FastAPI, Depends

app = FastAPI()

# First level dependency
def get_query_param(q: str = "default"):
    return {"query": q}

# Second level dependency
def get_full_query(query: dict = Depends(get_query_param)):
    return {**query, "status": "success"}

@app.get("/items/")
def read_item(query: dict = Depends(get_full_query)):
    return query

এখানে, get_full_query ফাংশনটি get_query_param ডিপেনডেন্সিকে ইনজেক্ট করছে।

রিকোয়েস্ট উদাহরণ:

GET /items/?q=test

রেসপন্স:

{
  "query": "test",
  "status": "success"
}

FastAPI তে Dependency Injection একটি শক্তিশালী বৈশিষ্ট্য যা কোডের মডুলারিটি, পুনঃব্যবহারযোগ্যতা এবং টেস্টযোগ্যতা নিশ্চিত করে। এটি আপনাকে API ডেভেলপমেন্টে ডিপেনডেন্সিগুলো সহজভাবে হ্যান্ডল করার সুযোগ দেয় এবং কোডের গুণগত মান উন্নত করে। FastAPI তে Depends ব্যবহার করে আপনি খুব সহজেই ফাংশন বা ক্লাসে ডিপেনডেন্সি ইনজেক্ট করতে পারেন এবং সেই ডিপেনডেন্সির কার্যকারিতা নিশ্চিত করতে পারেন।

Content added By

Dependencies তৈরি এবং ব্যবহার

197

FastAPI তে Dependencies ব্যবস্থাপনা একটি শক্তিশালী বৈশিষ্ট্য, যা কোডের পুনঃব্যবহারযোগ্যতা, পরিষ্কার কোড এবং কার্যকরী ডেটা সঞ্চালন নিশ্চিত করে। Dependency Injection এর মাধ্যমে FastAPI আপনাকে কোডের বিভিন্ন অংশে নির্ভরশীলতা সহজে পরিচালনা করার সুযোগ দেয়।

Dependency হল এমন একটি ফাংশন বা ক্লাস যা অন্যান্য ফাংশন বা রাউটের মধ্যে পুনঃব্যবহারযোগ্য লগিক বা ডাটা সরবরাহ করে। FastAPI তে এটি খুবই সহজে কাজ করে।


Dependency কী?

Dependency এমন একটি ফাংশন বা ক্লাস যা একটি নির্দিষ্ট রিকোয়েস্ট প্রসেসে ব্যবহৃত হতে পারে, এবং সেটি বিভিন্ন এন্ডপয়েন্টে ইনজেক্ট করা যেতে পারে। সাধারণত Database Connections, Authentication, Validation ইত্যাদি ব্যবহৃত হয়।


Step 1: Dependency তৈরি করা

FastAPI তে Dependency তৈরি করতে সাধারণত একটি ফাংশন ব্যবহার করা হয়, যা একটি নির্দিষ্ট কাজ করে এবং পরে তা অন্য ফাংশন বা রাউটে ইনজেক্ট করা হয়।

উদাহরণ: একটি সাধারণ Dependency ফাংশন

from fastapi import FastAPI, Depends

app = FastAPI()

# Dependency ফাংশন
def get_query_param(q: str = None):
    return q

@app.get("/items/")
def read_item(q: str = Depends(get_query_param)):
    return {"q": q}

এখানে, get_query_param হল একটি Dependency ফাংশন, যা q কোয়েরি প্যারামিটার গ্রহণ করে এবং তা অন্য রাউটে Depends ডেকোরেটরের মাধ্যমে ইনজেক্ট করা হয়।

রিকোয়েস্ট উদাহরণ:

GET /items/?q=fastapi

রেসপন্স:

{
  "q": "fastapi"
}

এখানে, q Dependency ফাংশন থেকে প্রাপ্ত মান ব্যবহার করা হয়েছে।


Step 2: Dependency Injection

FastAPI তে Dependency Injection ব্যবহার করে আপনি dependencies ইনজেক্ট করতে পারেন, যা একটি ফাংশন বা রাউটের মধ্যে স্বয়ংক্রিয়ভাবে সরবরাহ করা হয়।

উদাহরণ: Dependency Injection

from fastapi import FastAPI, Depends

app = FastAPI()

# Dependency ফাংশন
def get_token():
    return "sample_token_123"

@app.get("/items/")
def read_item(token: str = Depends(get_token)):
    return {"token": token}

এখানে, get_token একটি Dependency ফাংশন যা token প্রদান করে এবং এটি read_item রাউটে ইনজেক্ট করা হচ্ছে।

রিকোয়েস্ট উদাহরণ:

GET /items/

রেসপন্স:

{
  "token": "sample_token_123"
}

এখানে, get_token ফাংশন থেকে সরবরাহিত টোকেন ব্যবহার করা হয়েছে।


Step 3: Dependency তে ফাংশন প্যারামিটার

FastAPI তে আপনি Dependency ফাংশনে প্যারামিটার পাস করতে পারেন, যা রাউটের আর্গুমেন্ট থেকে আসতে পারে।

উদাহরণ: প্যারামিটার সহ Dependency

from fastapi import FastAPI, Depends

app = FastAPI()

# Dependency ফাংশন
def get_item_id(item_id: int):
    return item_id

@app.get("/items/{item_id}")
def read_item(item_id: int = Depends(get_item_id)):
    return {"item_id": item_id}

এখানে, get_item_id ফাংশন item_id প্যারামিটার গ্রহণ করে এবং এটি রাউট ফাংশনে ইনজেক্ট করা হচ্ছে।

রিকোয়েস্ট উদাহরণ:

GET /items/123

রেসপন্স:

{
  "item_id": 123
}

Step 4: Dependencies with Classes (Dependency Injection in Classes)

ফাস্টএপিআইতে আপনি ক্লাসের মাধ্যমেও ডিপেনডেন্সি ইনজেক্ট করতে পারেন। এটি বেশ কার্যকরী যখন আপনাকে কিছু শেয়ারযোগ্য অবজেক্ট বা রিসোর্স পরিচালনা করতে হয়।

উদাহরণ: Dependency ইনজেকশন ক্লাসের মাধ্যমে

from fastapi import FastAPI, Depends

app = FastAPI()

# Dependency class
class Database:
    def __init__(self):
        self.connection = "Database Connection Established"
    
    def get_data(self):
        return {"data": "Sample Data from Database"}

# Dependency function
def get_database() -> Database:
    db = Database()
    return db

@app.get("/items/")
def read_item(db: Database = Depends(get_database)):
    return db.get_data()

এখানে, Database একটি ক্লাস হিসেবে ডিপেনডেন্সি ফাংশনে ব্যবহৃত হচ্ছে। get_database ফাংশন ডাটাবেস সংযোগ এবং ডাটা প্রদান করছে।

রিকোয়েস্ট উদাহরণ:

GET /items/

রেসপন্স:

{
  "data": "Sample Data from Database"
}

এখানে, Database ক্লাসের মাধ্যমে ডাটা সংগ্রহ করা হয়েছে।


Step 5: Dependency with Authentication (Authentication Dependencies)

ডিপেনডেন্সি ইনজেকশন সাধারণত Authentication এবং Authorization ব্যবস্থাপনায় ব্যবহৃত হয়। যেমন, টোকেন যাচাই, ইউজার লগইন স্ট্যাটাস চেক ইত্যাদি।

উদাহরণ: Authentication Dependency

from fastapi import FastAPI, Depends, HTTPException, status

app = FastAPI()

# Dependency function to simulate token validation
def get_token(token: str):
    if token != "valid_token":
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid Token",
        )
    return token

@app.get("/secure-data/")
def get_secure_data(token: str = Depends(get_token)):
    return {"message": "This is a secure data!"}

এখানে, get_token একটি Dependency ফাংশন যা টোকেন যাচাই করে এবং get_secure_data রাউটে ইনজেক্ট করা হয়।

রিকোয়েস্ট উদাহরণ:

GET /secure-data/?token=valid_token

রেসপন্স:

{
  "message": "This is a secure data!"
}

Step 6: Dependency Chaining

FastAPI তে আপনি একাধিক ডিপেনডেন্সি চেইনও করতে পারেন। একাধিক ডিপেনডেন্সি একে অপরের উপর নির্ভরশীল হতে পারে।

উদাহরণ: Dependency Chaining

from fastapi import FastAPI, Depends

app = FastAPI()

def dependency_one():
    return "Hello"

def dependency_two(dep_one: str = Depends(dependency_one)):
    return dep_one + ", World!"

@app.get("/")
def read_item(dep: str = Depends(dependency_two)):
    return {"message": dep}

এখানে, dependency_two ফাংশন dependency_one এর উপর নির্ভরশীল এবং read_item রাউটে উভয়ই ইনজেক্ট করা হচ্ছে।

রিকোয়েস্ট উদাহরণ:

GET /

রেসপন্স:

{
  "message": "Hello, World!"
}

FastAPI তে Dependency Injection একটি শক্তিশালী বৈশিষ্ট্য যা কোডের পুনঃব্যবহারযোগ্যতা এবং পরিস্কার কোড তৈরি করতে সহায়ক। Dependency ব্যবহার করে আপনি বিভিন্ন রাউটে কমন ফাংশনালিটি, ডাটা এবং ভ্যালিডেশন সহজে শেয়ার করতে পারেন। এটি বড় এবং স্কেলেবল অ্যাপ্লিকেশন তৈরিতে সহায়ক।

Content added By

Global Dependency এবং Scoped Dependency কনফিগার করা

193

FastAPI তে Dependency Injection একটি গুরুত্বপূর্ণ বৈশিষ্ট্য, যা কোডকে আরও মডুলার, টেস্টযোগ্য এবং পুনঃব্যবহারযোগ্য করে তোলে। Global Dependency এবং Scoped Dependency FastAPI অ্যাপ্লিকেশনের মধ্যে বিভিন্ন ধরনের নির্ভরশীলতা পরিচালনা করতে ব্যবহৃত হয়।


Dependency Injection কী?

Dependency Injection (DI) হল একটি ডিজাইন প্যাটার্ন যেখানে একটি অবজেক্টের নির্ভরশীলতা অন্য এক অবজেক্ট সরবরাহ করে (ইনজেক্ট করে)। FastAPI-তে, আপনি ফাংশন এবং ক্লাসগুলির জন্য নির্ভরশীলতা নির্ধারণ করতে পারেন এবং এটি FastAPI-এর মাধ্যমে স্বয়ংক্রিয়ভাবে পরিচালিত হয়।

Dependency Injection ব্যবহারের সুবিধা:

  • কোড পুনঃব্যবহারযোগ্যতা বাড়ানো।
  • কোডের বিচ্ছিন্নতা (Separation of Concerns) নিশ্চিত করা।
  • অ্যাপ্লিকেশনটিকে আরও সহজে টেস্ট করা সম্ভব করা।

Global Dependency

Global Dependency হলো একটি নির্ভরশীলতা যা পুরো FastAPI অ্যাপ্লিকেশন জুড়ে উপলব্ধ থাকে। এটি অ্যাপ্লিকেশন-এর প্রতিটি এন্ডপয়েন্টে ব্যবহৃত হতে পারে। সাধারণত, Depends কনস্ট্রাক্টরের মাধ্যমে এটি ইনজেক্ট করা হয়।

Global Dependency উদাহরণ:

from fastapi import FastAPI, Depends

app = FastAPI()

# Global Dependency Function
def get_query_param(q: str = "default"):
    return q

@app.get("/items/")
def read_item(query: str = Depends(get_query_param)):
    return {"query": query}

এখানে, get_query_param হল একটি Global Dependency যেটি /items/ এন্ডপয়েন্টে Depends(get_query_param) এর মাধ্যমে ইনজেক্ট করা হয়েছে।

রিকোয়েস্ট উদাহরণ:

GET /items/?q=test

রেসপন্স:

{
  "query": "test"
}

এটি যখন কোন প্যারামিটার পাঠানো হয় না, তখন q="default" হবে।


Scoped Dependency

Scoped Dependency একটি নির্ভরশীলতা যা একটি নির্দিষ্ট সময়কাল বা কনটেক্সট পর্যন্ত সীমাবদ্ধ থাকে, যেমন একটি নির্দিষ্ট HTTP রিকোয়েস্ট। FastAPI-তে Scoped Dependency মূলত HTTP রিকোয়েস্ট লাইফসাইকেলের সাথে সম্পর্কিত থাকে, অর্থাৎ প্রতি রিকোয়েস্টে নতুন ইন্সট্যান্স তৈরি করা হয় এবং রিকোয়েস্টটি শেষ হলে সেই নির্ভরশীলতা ধ্বংস হয়ে যায়।

Scoped Dependency উদাহরণ:

from fastapi import FastAPI, Depends

app = FastAPI()

# Scoped Dependency Function
def get_db():
    db = "Database Connection"  # এখানে সিমুলেটেড ডাটাবেস কনেকশন
    try:
        yield db
    finally:
        db = None  # এখানে ডাটাবেস কানেকশন ক্লোজ হবে

@app.get("/users/")
def read_users(db: str = Depends(get_db)):
    return {"db": db}

এখানে, get_db হল একটি Scoped Dependency, যা একটি নির্দিষ্ট HTTP রিকোয়েস্টের সময়ে ইনজেক্ট করা হয় এবং রিকোয়েস্ট শেষ হলে yield ব্যবহৃত হয়ে ডাটাবেস কানেকশনটি ক্লোজ হয়।

রিকোয়েস্ট উদাহরণ:

GET /users/

রেসপন্স:

{
  "db": "Database Connection"
}

Scoped Dependency সাধারণত ডাটাবেস সংযোগ, কেশ, এবং অন্যান্য রিকোয়েস্ট-ভিত্তিক ডাটা হ্যান্ডল করার জন্য ব্যবহৃত হয়।


Global এবং Scoped Dependency-র মধ্যে পার্থক্য

বৈশিষ্ট্যGlobal DependencyScoped Dependency
ব্যবহারঅ্যাপ্লিকেশন জুড়ে ব্যবহৃতপ্রতিটি HTTP রিকোয়েস্টের জন্য
এনজেক্ট হওয়াএকবার, পুরো অ্যাপের জন্যপ্রতিটি রিকোয়েস্টের জন্য
নির্ভরশীলতা লাইফটাইমঅ্যাপের সাথে থাকছেরিকোয়েস্ট শেষ হলে ধ্বংস হয়
উদাহরণAPI কনফিগারেশন, অ্যাপ্লিকেশন সেটিংসডাটাবেস কানেকশন, লগিং

Dependency Injection ব্যবহার করে Authorization এবং Authentication

Dependency Injection ব্যবহার করে আপনি authorization এবং authentication পরিচালনা করতে পারেন, যেমন JWT টোকেন বা OAuth2 ভিত্তিক অথেনটিকেশন। নিচে একটি উদাহরণ দেওয়া হলো যেখানে OAuth2-এর মাধ্যমে ডিপেনডেন্সি তৈরি করা হয়েছে।

OAuth2 Scoped Dependency উদাহরণ:

from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer

app = FastAPI()

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

def get_current_user(token: str = Depends(oauth2_scheme)):
    if token != "valid-token":
        raise HTTPException(status_code=401, detail="Invalid token")
    return {"username": "test_user"}

@app.get("/users/me")
def read_users_me(current_user: dict = Depends(get_current_user)):
    return {"current_user": current_user}

এখানে, get_current_user একটি Scoped Dependency, যা OAuth2 টোকেন যাচাই করতে ব্যবহৃত হয়েছে। এটি কেবল সেই রিকোয়েস্টের জন্য কার্যকর যা একটি সঠিক টোকেন প্রদান করে।


FastAPI তে Global Dependency এবং Scoped Dependency ব্যবহারের মাধ্যমে আপনি অ্যাপ্লিকেশনের নির্ভরশীলতা আরও কার্যকরভাবে এবং মডুলারভাবে পরিচালনা করতে পারেন। Global Dependency আপনাকে অ্যাপ্লিকেশন জুড়ে ব্যবহৃত ফাংশন বা সেটিংস এর জন্য সুবিধা দেয়, যখন Scoped Dependency HTTP রিকোয়েস্টের সাথে সম্পর্কিত নির্ভরশীলতা হ্যান্ডল করতে সাহায্য করে, যেমন ডাটাবেস সংযোগ বা লগিং। Dependency Injection-এর মাধ্যমে কোডের বিচ্ছিন্নতা এবং পুনঃব্যবহারযোগ্যতা বৃদ্ধি পায়, এবং অ্যাপ্লিকেশন টেস্টিং আরও সহজ হয়।

Content added By

Dependency Injection এর মাধ্যমে Authentication এবং Authorization

228

FastAPI তে Dependency Injection ব্যবস্থাপনা অত্যন্ত শক্তিশালী এবং সহজ। এটি Authentication এবং Authorization পরিচালনা করতে ব্যবহৃত হতে পারে, যেখানে আপনি ব্যবহারকারীদের শনাক্ত করতে এবং তাদের অ্যাক্সেস অনুমতি নিয়ন্ত্রণ করতে পারেন।

Dependency Injection (DI) কী?

Dependency Injection (DI) হল একটি ডিজাইন প্যাটার্ন যা অন্য কোনো ক্লাসের বা কম্পোনেন্টের ডিপেনডেন্সি সরবরাহ করে (ইনজেক্ট করে)। FastAPI তে, আপনি এটির মাধ্যমে ফাংশন বা ক্লাসের মধ্যে প্রয়োজনীয় উপাদান সরবরাহ করতে পারেন। Authentication এবং Authorization-এ DI ব্যবহারের মাধ্যমে আপনি নিরাপত্তা যুক্ত করতে পারেন এবং কোডকে আরও মডুলার ও পুনরায় ব্যবহারের উপযোগী করতে পারেন।


Step 1: Dependency Injection এর মাধ্যমে Authentication

Authentication এর উদ্দেশ্য হল ব্যবহারকারীর পরিচয় যাচাই করা (যেমন: username/password দিয়ে লগইন)। FastAPI তে Dependency Injection ব্যবহার করে আপনি এই প্রক্রিয়াকে সহজভাবে ম্যানেজ করতে পারেন।

উদাহরণ: Token-based Authentication

এখানে একটি JWT Token-based Authentication ব্যবস্থার উদাহরণ দেয়া হলো:

from fastapi import FastAPI, Depends, HTTPException
from pydantic import BaseModel
from jose import JWTError, jwt
from datetime import datetime, timedelta
from typing import List

# Secret key for encoding and decoding JWT tokens
SECRET_KEY = "a5e4b5c6d6e6f2e4b9"
ALGORITHM = "HS256"

# FastAPI instance
app = FastAPI()

# User model
class User(BaseModel):
    username: str

# JWT Token schema
class Token(BaseModel):
    access_token: str
    token_type: str

# Dependency to simulate getting a user from a database
def get_user_from_db(username: str):
    if username == "testuser":
        return User(username="testuser")
    return None

# Dependency for authentication (token verification)
def get_current_user(token: str = Depends()):
    credentials_exception = HTTPException(
        status_code=401,
        detail="Could not validate credentials",
        headers={"WWW-Authenticate": "Bearer"},
    )
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        username: str = payload.get("sub")
        if username is None:
            raise credentials_exception
        user = get_user_from_db(username)
        if user is None:
            raise credentials_exception
    except JWTError:
        raise credentials_exception
    return user

# Route to generate token (authentication)
@app.post("/token", response_model=Token)
def login_for_access_token(form_data: User):
    user = get_user_from_db(form_data.username)
    if user is None:
        raise HTTPException(
            status_code=404,
            detail="User not found",
        )

    expiration = timedelta(minutes=30)
    access_token_expires = datetime.utcnow() + expiration
    access_token = jwt.encode(
        {"sub": user.username, "exp": access_token_expires},
        SECRET_KEY,
        algorithm=ALGORITHM,
    )

    return {"access_token": access_token, "token_type": "bearer"}

# Protected route using the dependency injection to check the current user
@app.get("/users/me")
def read_users_me(current_user: User = Depends(get_current_user)):
    return {"username": current_user.username}

ব্যাখ্যা:

  • get_current_user: এটি একটি dependency যা JWT token যাচাই করে এবং ভ্যালিড হলে ব্যবহারকারীকে ফেরত দেয়।
  • login_for_access_token: ব্যবহারকারীকে JWT token প্রদান করার জন্য এন্ডপয়েন্ট।
  • read_users_me: এটি একটি প্রটেক্টেড রাউট, যেখানে Depends(get_current_user) দিয়ে রিকোয়েস্টের token যাচাই করা হচ্ছে।

রিকোয়েস্ট উদাহরণ:

  • POST /token: ব্যবহারকারীর নাম এবং পাসওয়ার্ড দিয়ে JWT টোকেন প্রাপ্তি।
{
  "username": "testuser"
}
  • GET /users/me: JWT token হেডারে পাঠানো হলে, বর্তমান লগইন করা ব্যবহারকারী তথ্য ফেরত পাওয়া যাবে।

রেসপন্স:

{
  "username": "testuser"
}

Step 2: Dependency Injection এর মাধ্যমে Authorization

Authorization হল ব্যবহারকারীর বিশেষ অনুমতিগুলি যাচাই করা। FastAPI তে, আপনি Permission-based Authorization সেটআপ করতে পারেন Dependency Injection এর মাধ্যমে। এক্ষেত্রে, আমরা ব্যবহারকারীর ভূমিকা (roles) যাচাই করব।

উদাহরণ: Role-based Authorization

from fastapi import FastAPI, Depends, HTTPException, status
from pydantic import BaseModel

# User model and roles
class User(BaseModel):
    username: str
    role: str

# Simulated database for users
users_db = {
    "admin": {"username": "admin", "role": "admin"},
    "guest": {"username": "guest", "role": "guest"}
}

# Dependency for getting the current user
def get_current_user(username: str):
    user = users_db.get(username)
    if user is None:
        raise HTTPException(status_code=404, detail="User not found")
    return user

# Dependency for checking if user has the correct role
def get_admin_user(current_user: User = Depends(get_current_user)):
    if current_user.role != "admin":
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Not authorized to access this resource",
        )
    return current_user

# Protected route: Only accessible to 'admin' users
@app.get("/admin/")
def admin_route(current_user: User = Depends(get_admin_user)):
    return {"message": f"Welcome, {current_user.username}, you are an admin."}

ব্যাখ্যা:

  • get_current_user: এই dependency ব্যবহারকারীর নাম দ্বারা ডাটাবেস থেকে ব্যবহারকারী ফেরত দেয়।
  • get_admin_user: এটি একটি authorization dependency যা নিশ্চিত করে যে শুধুমাত্র admin রোলের ব্যবহারকারীই এই রুটটি অ্যাক্সেস করতে পারবে।

রিকোয়েস্ট উদাহরণ:

  • GET /admin/: শুধুমাত্র admin রোলের ব্যবহারকারী অ্যাক্সেস করতে পারবে। যদি guest ব্যবহারকারী এই রুটে প্রবেশের চেষ্টা করে, তাহলে 403 ত্রুটি হবে।

Step 3: Combination of Authentication and Authorization

FastAPI-তে আপনি সহজেই Authentication এবং Authorization একত্রে ব্যবহার করতে পারেন। উপরের উদাহরণগুলোতে আপনি দেখেছেন কিভাবে টোকেন এবং রোল যাচাই করা হয়, এখন একই সময়ে এই দুটোকে একত্রে ব্যবহার করা হবে।

from fastapi import FastAPI, Depends, HTTPException

# Dependency to check if the user has admin privileges
def get_admin_user(current_user: User = Depends(get_current_user)):
    if current_user.role != "admin":
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Not authorized to access this resource",
        )
    return current_user

# Combining authentication and authorization: Admin access
@app.get("/admin/")
def admin_route(current_user: User = Depends(get_admin_user)):
    return {"message": f"Hello {current_user.username}, you are an admin!"}

এখানে:

  • Depends(get_current_user): এই dependency token যাচাই করে ব্যবহারকারীকে ফেরত দেয়।
  • Depends(get_admin_user): এটি ব্যবহৃত হয় authorization চেক করার জন্য।

FastAPI তে Dependency Injection ব্যবহারের মাধ্যমে Authentication এবং Authorization পরিচালনা করা অনেক সহজ এবং পরিষ্কার। আপনি JWT token ব্যবহার করে authentication পরিচালনা করতে পারেন এবং role-based বা permission-based authorization সহ নিরাপদ রাউট তৈরি করতে পারেন। এই প্রক্রিয়া FastAPI কে আরও শক্তিশালী এবং নিরাপদ API ডেভেলপমেন্টের জন্য উপযোগী করে তোলে।

Content added By
Promotion
NEW SATT AI এখন আপনাকে সাহায্য করতে পারে।

Are you sure to start over?

Loading...