Quick Start¶
Build and run a Craft Easy API in under five minutes. At the end you will have a running API with a Product resource, automatic CRUD endpoints, and a working curl flow.
1. Create the project¶
The fastest path is the API cookiecutter template:
Answer the prompts (defaults are fine for a first run) and cd into the generated directory:
If you prefer to start from scratch, see the manual setup at the end of this page.
2. Define a model¶
Open src/my_project/models/product.py and define a Beanie document:
from beanie import Document, Indexed
from pydantic import Field
from craft_easy.core.models import TenantScopedDocument
class Product(TenantScopedDocument):
name: Indexed(str)
price: float = Field(..., ge=0)
sku: str
in_stock: bool = True
class Settings:
name = "products"
TenantScopedDocument adds tenant_id, soft-delete, timestamps, and audit fields automatically. Every query is filtered by the caller's tenant.
3. Register the resource¶
In src/my_project/app.py, register the model as a resource:
from craft_easy import create_base_app
from craft_easy.core.crud import Resource
from my_project.models.product import Product
def create_app():
app = create_base_app()
app.register_resource(Resource(Product, path="/products"))
return app
That single register_resource call gives you:
| Method | Path | Purpose |
|---|---|---|
GET |
/products |
List with filtering, sorting, pagination |
GET |
/products/{id} |
Get one by id, returns ETag |
POST |
/products |
Create |
PATCH |
/products/{id} |
Partial update (ETag required) |
DELETE |
/products/{id} |
Soft delete |
4. Run the API¶
MONGODB_URI="mongodb://localhost:27017/?directConnection=true" \
DATABASE_NAME="my-project-dev" \
ENVIRONMENT="development" \
AUTH_ENABLED="false" \
DEFAULT_CURRENCY="EUR" \
DEFAULT_VAT_RATE="0.20" \
uvicorn my_project.app:create_app --factory --port 5001
Verify it is up:
The interactive OpenAPI docs are at http://localhost:5001/docs.
5. Create, list, update, delete¶
BASE=http://localhost:5001
# Create
curl -X POST $BASE/products \
-H "Content-Type: application/json" \
-d '{"name": "Coffee Mug", "price": 12.50, "sku": "MUG-001"}'
# List (filter active ones)
curl "$BASE/products?in_stock=true&sort=name&per_page=20"
# Get one (capture the ETag)
ETAG=$(curl -sD - $BASE/products/{id} | awk '/^ETag/ {print $2}' | tr -d '\r')
# Update (must supply If-Match)
curl -X PATCH $BASE/products/{id} \
-H "Content-Type: application/json" \
-H "If-Match: $ETAG" \
-d '{"price": 14.00}'
# Soft delete
curl -X DELETE $BASE/products/{id}
For the full filter syntax (where JSON clauses, suffix operators, sorting) see Filtering & Querying.
6. Enable the admin UI¶
Start the admin app and point it at your API:
# In another terminal
git clone https://github.com/easy-software-system/craft-easy-admin.git
cd craft-easy-admin
npm install
npm run web
On the Connect screen, enter http://localhost:5001. The admin app calls /admin/schema, discovers your Product resource, and renders a list/detail/create/edit UI — without you writing any UI code. See Admin App overview for the schema protocol.
Manual setup (without the template)¶
If you skipped cookiecutter, here is the minimum working project:
my-project/
├── pyproject.toml
└── src/
└── my_project/
├── __init__.py
├── app.py
├── settings.py
└── models/
├── __init__.py
└── product.py
src/my_project/settings.py:
from craft_easy.settings import Settings as BaseSettings
class Settings(BaseSettings):
app_name: str = "my-project"
src/my_project/app.py:
from craft_easy import create_base_app
from craft_easy.core.crud import Resource
from my_project.models.product import Product
from my_project.settings import Settings
def create_app():
settings = Settings()
app = create_base_app(settings=settings)
app.register_resource(Resource(Product, path="/products"))
return app
pyproject.toml:
[project]
name = "my-project"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = ["craft-easy-api>=0.1"]
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.build.targets.wheel]
packages = ["src/my_project"]
Run it the same way as step 4.
Next steps¶
- Configuration — every setting you can tune.
- Resources & CRUD — customise endpoints, override behaviour.
- Authentication — turn on OTP login and get a real JWT.
- Multi-Tenancy — how tenant scoping works.