0% found this document useful (0 votes)
4 views

markdowntohtml.com (43).html

This document outlines the creation of a FastAPI API to manage many-to-many relationships between User, Role, and Permission models, including CRUD operations and role/permission assignments. It provides detailed endpoint implementations for creating users, roles, and permissions, as well as assigning roles to users and permissions to roles. Additionally, it includes Pydantic schemas for data validation and response formatting, and instructions for testing the API using tools like curl or Postman.

Uploaded by

mtbaloch666
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views

markdowntohtml.com (43).html

This document outlines the creation of a FastAPI API to manage many-to-many relationships between User, Role, and Permission models, including CRUD operations and role/permission assignments. It provides detailed endpoint implementations for creating users, roles, and permissions, as well as assigning roles to users and permissions to roles. Additionally, it includes Pydantic schemas for data validation and response formatting, and instructions for testing the API using tools like curl or Postman.

Uploaded by

mtbaloch666
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 4

To create an API using FastAPI for the many-to-many relationships in the models you've defined (such as User, Role,

Permission, and the junction tables UserRole and RolePermission), we'll first need to set up endpoints to handle CRUD
operations for these models. Specifically, we’ll provide the following functionalities:

1. Create and Retrieve Users, Roles, and Permissions


2. Assign Roles to Users
3. Assign Permissions to Roles
4. Get User Information along with their Roles
5. Get Role Information along with its Permissions

Here is an implementation of a basic FastAPI API based on your models:

from fastapi import FastAPI, Depends, HTTPException


from pydantic import BaseModel
from sqlalchemy.orm import Session
from uuid import UUID
from typing import List

from sqlmodel import Session, select

from models import User, Role, Permission, UserRole, RolePermission, OtpVerification


from database import engine, get_db # Assuming your DB engine and session are set up

app = FastAPI()

# Pydantic Schemas for validation and response formatting


class UserCreate(BaseModel):
user_name: str
email: str
password_hash: str

class RoleCreate(BaseModel):
name: str

class PermissionCreate(BaseModel):
name: str

class UserOut(BaseModel):
id: UUID
user_name: str
email: str
roles: List[str] # List of role names

class Config:
orm_mode = True

class RoleOut(BaseModel):
id: UUID
name: str
permissions: List[str] # List of permission names

class Config:
orm_mode = True

class PermissionOut(BaseModel):
id: UUID
name: str

class Config:
orm_mode = True
@app.post("/users/", response_model=UserOut)
def create_user(user: UserCreate, db: Session = Depends(get_db)):
db_user = User(user_name=user.user_name, email=user.email, password_hash=user.password_hash)
db.add(db_user)
db.commit()
db.refresh(db_user)
return db_user

@app.post("/roles/", response_model=RoleOut)
def create_role(role: RoleCreate, db: Session = Depends(get_db)):
db_role = Role(name=role.name)
db.add(db_role)
db.commit()
db.refresh(db_role)
return db_role

@app.post("/permissions/", response_model=PermissionOut)
def create_permission(permission: PermissionCreate, db: Session = Depends(get_db)):
db_permission = Permission(name=permission.name)
db.add(db_permission)
db.commit()
db.refresh(db_permission)
return db_permission

@app.post("/users/{user_id}/roles/{role_id}")
def assign_role_to_user(user_id: UUID, role_id: UUID, db: Session = Depends(get_db)):
db_user = db.get(User, user_id)
db_role = db.get(Role, role_id)

if db_user is None or db_role is None:


raise HTTPException(status_code=404, detail="User or Role not found")

user_role = UserRole(user_id=user_id, role_id=role_id)


db.add(user_role)
db.commit()
db.refresh(user_role)

return {"message": "Role assigned successfully"}

@app.post("/roles/{role_id}/permissions/{permission_id}")
def assign_permission_to_role(role_id: UUID, permission_id: UUID, db: Session = Depends(get_db)):
db_role = db.get(Role, role_id)
db_permission = db.get(Permission, permission_id)

if db_role is None or db_permission is None:


raise HTTPException(status_code=404, detail="Role or Permission not found")

role_permission = RolePermission(role_id=role_id, permission_id=permission_id)


db.add(role_permission)
db.commit()
db.refresh(role_permission)

return {"message": "Permission assigned successfully"}

@app.get("/users/{user_id}", response_model=UserOut)
def get_user(user_id: UUID, db: Session = Depends(get_db)):
db_user = db.get(User, user_id)
if db_user is None:
raise HTTPException(status_code=404, detail="User not found")
return db_user

@app.get("/roles/{role_id}", response_model=RoleOut)
def get_role(role_id: UUID, db: Session = Depends(get_db)):
db_role = db.get(Role, role_id)
if db_role is None:
raise HTTPException(status_code=404, detail="Role not found")

return db_role

@app.get("/permissions/{permission_id}", response_model=PermissionOut)
def get_permission(permission_id: UUID, db: Session = Depends(get_db)):
db_permission = db.get(Permission, permission_id)
if db_permission is None:
raise HTTPException(status_code=404, detail="Permission not found")

return db_permission

@app.get("/users/{user_id}/roles", response_model=List[RoleOut])
def get_user_roles(user_id: UUID, db: Session = Depends(get_db)):
statement = select(Role).join(UserRole).where(UserRole.user_id == user_id)
roles = db.exec(statement).all()

if not roles:
raise HTTPException(status_code=404, detail="No roles found for this user")

return roles

@app.get("/roles/{role_id}/permissions", response_model=List[PermissionOut])
def get_role_permissions(role_id: UUID, db: Session = Depends(get_db)):
statement = select(Permission).join(RolePermission).where(RolePermission.role_id == role_id)
permissions = db.exec(statement).all()

if not permissions:
raise HTTPException(status_code=404, detail="No permissions found for this role")

return permissions

# Database engine setup and session dependency


from sqlmodel import SQLModel, create_engine
from sqlalchemy.orm import sessionmaker

DATABASE_URL = "postgresql://user:password@localhost/dbname"

engine = create_engine(DATABASE_URL)
SQLModel.metadata.create_all(bind=engine)

def get_db():
db = sessionmaker(autocommit=False, autoflush=False, bind=engine)()
try:
yield db
finally:
db.close()

Key Points in this Code:

1. CRUD Endpoints: We created routes for creating User, Role, and Permission.
POST /users/ creates a new user.
POST /roles/ creates a new role.
POST /permissions/ creates a new permission.

2. Many-to-Many Assignments: We have routes to:

Assign a Role to a User (via POST /users/{user_id}/roles/{role_id}).


Assign a Permission to a Role (via POST /roles/{role_id}/permissions/{permission_id}).

3. Relationship Lookups: We provide routes to fetch the roles of a user and permissions of a role:

GET /users/{user_id}/roles returns the roles assigned to a user.


GET /roles/{role_id}/permissions returns the permissions assigned to a role.

4. Pydantic Models: The Pydantic models like UserOut, RoleOut, and PermissionOut help define what will be
returned in API responses.

Testing the API

You can test the API using curl, Postman, or Swagger UI. FastAPI automatically generates Swagger UI for your
endpoints at http://localhost:8000/docs.

Make sure you have the necessary database setup and an active connection to the PostgreSQL database. You can
replace the DATABASE_URL with your actual connection string.

You might also like