Docs / fastkit-core / Quick Start

Quick Start

Build your first FastKit API in 5 minutes. You'll create a working Todo API with database operations, service layer, validation, and standardized responses.

5–10 minutes
Python 3.11+ installed
fastkit-core installed

Prerequisites

Before starting, make sure you have fastkit-core installed. If you haven't done that yet, check the Installation guide first.

bash
pip install fastkit-core

New to FastAPI? No problem — this guide assumes no prior FastAPI experience. You'll learn the patterns as you go.

Step 1 — Project Setup

Create a new directory and set up your project structure:

bash
mkdir fastkit-quickstart
cd fastkit-quickstart

python3 -m venv venv
source venv/bin/activate  # Windows: venv\Scripts\activate

pip install fastkit-core

mkdir config
touch main.py models.py services.py config/database.py .env

Your project structure should look like this:

text
fastkit-quickstart/
├── config/
│   └── database.py
├── .env
├── main.py
├── models.py
└── services.py

Step 2 — Configure Database

We'll use SQLite for this quickstart — no extra installation needed.

Create .env

bash
# .env
DB_DRIVER=sqlite
DB_NAME=quickstart.db

Create config/database.py

python
# config/database.py
import os

CONNECTIONS = {
    'default': {
        'driver': os.getenv('DB_DRIVER', 'sqlite'),
        'database': os.getenv('DB_NAME', 'quickstart.db'),
        'echo': False  # Set to True to see SQL queries in console
    }
}

Step 3 — Create Your Model

Create models.py with the database model and Pydantic schemas:

python
# models.py
from fastkit_core.database import Base, IntIdMixin, TimestampMixin
from fastkit_core.validation import BaseSchema
from sqlalchemy.orm import Mapped, mapped_column
from sqlalchemy import String, Boolean

# ── Database Model ────────────────────────
class Todo(Base, IntIdMixin, TimestampMixin):
    __tablename__ = 'todos'

    title:       Mapped[str]      = mapped_column(String(200))
    description: Mapped[str|None] = mapped_column(String(500), nullable=True)
    completed:   Mapped[bool]     = mapped_column(Boolean, default=False)


# ── Pydantic Schemas ──────────────────────
class TodoCreate(BaseSchema):
    title: str
    description: str | None = None

class TodoUpdate(BaseSchema):
    title:       str | None  = None
    description: str | None  = None
    completed:   bool | None = None

class TodoResponse(BaseSchema):
    id:          int
    title:       str
    description: str | None
    completed:   bool
    model_config = {"from_attributes": True}
IntIdMixin Adds an auto-incrementing id primary key
TimestampMixin Adds created_at and updated_at, managed automatically
BaseSchema Pydantic base with translated error formatting built in

Step 4 — Create the Service

Create services.py with the business logic layer:

python
# services.py
from fastkit_core.services import BaseCrudService
from fastkit_core.database import Repository
from models import Todo, TodoCreate, TodoUpdate, TodoResponse
from sqlalchemy.orm import Session


class TodoService(BaseCrudService[Todo, TodoCreate, TodoUpdate, TodoResponse]):

    def __init__(self, session: Session):
        super().__init__(
            Repository(Todo, session),
            response_schema=TodoResponse
        )

    def mark_completed(self, todo_id: int) -> Todo:
        """Custom business logic — mark a todo as done."""
        return self.update(todo_id, {"completed": True})

    def mark_incomplete(self, todo_id: int) -> Todo:
        return self.update(todo_id, {"completed": False})
BaseCrudService Provides create, find, all, paginate, update, delete out of the box
Repository(Todo, session) Data access layer — keeps database queries out of business logic
response_schema Automatically serializes model instances to Pydantic schema on every return

Step 5 — Create API Endpoints

Create main.py with the full CRUD API:

python
# main.py
from fastapi import FastAPI, Depends
from fastkit_core.config import ConfigManager
from fastkit_core.database import init_database, get_db, get_db_manager
from fastkit_core.http import success_response, paginated_response
from sqlalchemy.orm import Session
from models import Todo, TodoCreate, TodoUpdate
from services import TodoService

app = FastAPI(title="FastKit Quickstart API")

# Init database
config = ConfigManager(modules=['database'], auto_load=True)
init_database(config)
Todo.metadata.create_all(get_db_manager().engine)


def get_service(session: Session = Depends(get_db)) -> TodoService:
    return TodoService(session)


@app.post("/todos", status_code=201)
def create_todo(data: TodoCreate, svc: TodoService = Depends(get_service)):
    todo = svc.create(data.model_dump())
    return success_response(data=todo.model_dump(), message="Todo created")


@app.get("/todos")
def list_todos(
    page: int = 1,
    per_page: int = 10,
    completed: bool | None = None,
    svc: TodoService = Depends(get_service)
):
    filters = {"completed": completed} if completed is not None else {}
    todos, meta = svc.paginate(page=page, per_page=per_page, **filters)
    return paginated_response(items=[t.model_dump() for t in todos], pagination=meta)


@app.get("/todos/{todo_id}")
def get_todo(todo_id: int, svc: TodoService = Depends(get_service)):
    return success_response(data=svc.find_or_fail(todo_id).model_dump())


@app.put("/todos/{todo_id}")
def update_todo(todo_id: int, data: TodoUpdate, svc: TodoService = Depends(get_service)):
    todo = svc.update(todo_id, data.model_dump(exclude_unset=True))
    return success_response(data=todo.model_dump(), message="Todo updated")


@app.post("/todos/{todo_id}/complete")
def complete_todo(todo_id: int, svc: TodoService = Depends(get_service)):
    return success_response(data=svc.mark_completed(todo_id).model_dump())


@app.delete("/todos/{todo_id}", status_code=204)
def delete_todo(todo_id: int, svc: TodoService = Depends(get_service)):
    svc.delete(todo_id)

Step 6 — Run Your API

bash
uvicorn main:app --reload

You should see:

text
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Started reloader process
INFO:     Application startup complete.

Your API is running! Visit http://127.0.0.1:8000/docs for the interactive Swagger UI.

Test Your API

bash
# Create a todo
curl -X POST http://127.0.0.1:8000/todos \
  -H "Content-Type: application/json" \
  -d '{"title": "Learn FastKit Core", "description": "Complete the quickstart"}'

# List todos (with pagination)
curl http://127.0.0.1:8000/todos

# Get specific todo
curl http://127.0.0.1:8000/todos/1

# Mark as completed
curl -X POST http://127.0.0.1:8000/todos/1/complete

# Update todo
curl -X PUT http://127.0.0.1:8000/todos/1 \
  -H "Content-Type: application/json" \
  -d '{"title": "Master FastKit Core"}'

# Delete todo
curl -X DELETE http://127.0.0.1:8000/todos/1
python
import requests

BASE = "http://127.0.0.1:8000"

# Create a todo
res = requests.post(f"{BASE}/todos", json={
    "title": "Learn FastKit Core",
    "description": "Complete the quickstart"
})
todo = res.json()["data"]
print(f"Created: {todo['id']} — {todo['title']}")

# List todos
res = requests.get(f"{BASE}/todos")
print(f"Total: {res.json()['pagination']['total']}")

# Mark as completed
requests.post(f"{BASE}/todos/{todo['id']}/complete")

# Update
requests.put(f"{BASE}/todos/{todo['id']}", json={"title": "Master FastKit Core"})

# Delete
requests.delete(f"{BASE}/todos/{todo['id']}")

FastAPI automatically generates interactive documentation:

  1. Open http://127.0.0.1:8000/docs in your browser
  2. Click POST /todosTry it out
  3. Enter the request body and click Execute
json
{
  "title": "Learn FastKit Core",
  "description": "Complete the quickstart guide"
}

What You Built

In just a few minutes, you created a production-ready API with all of these features working out of the box:

Database Layer
  • SQLAlchemy model with mixins
  • Auto ID and timestamps
  • Repository pattern
Business Logic
  • Service with full CRUD
  • Custom methods
  • Reusable across the app
Validation
  • Pydantic schema validation
  • Type-safe data handling
  • Automatic error messages
API Responses
  • Standardized JSON format
  • Pagination with metadata
  • Filtering by field

Next Steps

Now that you have a working API, explore FastKit Core's features in depth:

Troubleshooting

Import errors
bash
pip install --upgrade fastkit-core
Port 8000 already in use
bash
uvicorn main:app --reload --port 8001
Database connection errors

For PostgreSQL or MySQL, make sure the driver is installed:

bash
pip install psycopg2-binary   # PostgreSQL
pip install pymysql           # MySQL