A backend-first Library Management System API built with FastAPI and SQLAlchemy, designed with real-world backend practices in mind: layered architecture, authentication, role-based access control, and clean separation of concerns.
This project intentionally focuses on backend correctness and design, not UI.
- deployed: https://lms-api-wtg5.onrender.com
- open api docs: https://lms-api-wtg5.onrender.com/docs
The API was previously deployed on Render.
The public instance is currently offline due to free-tier resource limits.
The project can still be run locally using the instructions provided below.
-
User management (create, list, retrieve)
-
Book management (create, update, list)
-
Loan management (issue, return, list loans)
-
SQLite-backed relational database using SQLAlchemy ORM
-
JWT-based authentication
-
OAuth2 password flow
-
Role-Based Access Control (RBAC)
-
Roles:
ADMIN,LIBRARIAN,MEMBER -
Access to endpoints restricted by role
-
-
Secure password hashing
-
Clean layered structure:
- API (routers)
- Services (business logic)
- Repositories (database access)
- Schemas (request/response validation)
- Models (SQLAlchemy ORM)
-
Dependency Injection using FastAPI Depends
-
UUID-based primary keys
-
Environment-based configuration using .env
-
Python 3.12
-
FastAPI
-
SQLAlchemy 2.x
-
Neon (PostgeSQL)
-
Pydantic
-
JWT (python-jose)
-
OAuth2
-
Uvicorn
-
ADMIN
-
Create users
-
Full access to system
-
-
LIBRARIAN
-
Manage books
-
Issue and return loans
-
-
MEMBER
-
View own profile
-
View available books
-
View own loans
-
Authorization is enforced using FastAPI dependencies, not inside route logic.
-
Relational schema with proper foreign keys
-
UUIDs used as primary identifiers
-
Loan records track:
-
Issue date
-
Due date
-
Return date
-
-
Business state (e.g. overdue loans) is derived, not stored
The application uses environment variables for configuration.
Example .env file:
DATABASE_URL=sqlite:///./lms.db
SECRET_KEY=DEVELOPMENT
ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=60
INITIAL_ADMIN_EMAIL=admin@example.com
INITIAL_ADMIN_PASSWORD=strongpasswordAn initial admin account is auto-created if the database is empty.
1. Create a virtual environment
2. Install dependencies
3. Run the server:
fastapi runSwagger UI available at:
http://localhost:8000/docs-
FastAPI over Flask for type safety, validation, and dependency injection
-
Service + Repository pattern to avoid fat routes
-
No hardcoded business states (e.g. overdue loans are computed)
-
SQLite first, PostgreSQL planned next (executed)
-
Focus on correctness over shortcuts
-
Alembic migrations
-
Background jobs for policy enforcement
-
Account suspension automation
-
Penalty system for overdue loans
Srijan Kargupta (c) 2026