markdowntohtml.com (43).html
markdowntohtml.com (43).html
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:
app = FastAPI()
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)
@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)
@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_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()
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.
3. Relationship Lookups: We provide routes to fetch the roles of a user and permissions of a role:
4. Pydantic Models: The Pydantic models like UserOut, RoleOut, and PermissionOut help define what will be
returned in API responses.
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.