manage.py check booted a full Django interpreter every 30s (~1.5s CPU per run) and never verified the server was actually responding. Probe the HTTP endpoint directly instead and relax the interval.
Kakebo
Japanese budgeting method web app built with Django, Django LiveView, SQLite, DaisyUI, and Docker.
Screenshots
| Expense | Week | Month |
|---|---|---|
![]() |
![]() |
![]() |
| Month end | Year | Settings |
|---|---|---|
![]() |
![]() |
![]() |
Features
- Expense tracking: add expenses with category and subcategory
- Weekly view: expenses grouped by category with edit/delete
- Monthly view: income, fixed expenses, budget calculator, goals, promises, self-assessment
- Yearly view: charts (income vs expenses, category breakdown, monthly evolution), planned expenses
- Settings: manage categories, subcategories, fixed expense concepts
- CSV export: download all expenses from Settings
- REST API: add expenses programmatically (iOS Shortcuts, scripts, etc.)
- Mobile-first: responsive design with bottom navigation
- Real-time: all interactions via WebSocket (Django LiveView)
Deployment
git clone https://git.andros.dev/andros/kakebo.git
cd kakebo
cp .env.example .env # edit with your settings
docker compose up -d --build
docker compose exec django python manage.py createsuperuser
docker compose exec django python manage.py seed_categories
Local development
git clone https://git.andros.dev/andros/kakebo.git
cd kakebo
docker compose up -d --build
# http://localhost:8080
Vite builds CSS automatically before Django starts. If you change templates or assets/css/main.css, rebuild:
docker compose up -d --build vite django
Without Docker
npm install
npm run build # compile CSS once
npm run dev # or watch mode with HMR
python manage.py runserver
Running tests
docker compose exec django python manage.py test app.api -v2
API
RESTful API for adding expenses programmatically.
Authentication
All endpoints require a Bearer token via the Authorization header. The token is defined in the API_TOKEN environment variable.
Authorization: Bearer <your-token>
Response format
{
"type": "Success",
"data": [...],
"_links": {
"self": {"href": "/api/...", "method": "GET"}
}
}
Error types: ParametersError (400), ResourceError (404), SystemError (500).
Endpoints
GET /api/
Returns all available endpoints.
GET /api/categories/
Returns all categories with their subcategories.
curl -H "Authorization: Bearer $API_TOKEN" \
https://kakebo.andros.dev/api/categories/
GET /api/categories/{id}/subcategories/
Returns subcategories for a specific category.
POST /api/expenses/
Creates a new expense.
curl -X POST \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"concept": "Groceries", "amount": "42.50", "category": 1, "subcategory": 1}' \
https://kakebo.andros.dev/api/expenses/
| Field | Type | Required | Description |
|---|---|---|---|
| concept | string | yes | Expense description |
| amount | decimal | yes | Amount (e.g. "42.50") |
| category | integer | yes | Category ID |
| subcategory | integer | yes | Subcategory ID (must belong to the category) |
Contributing
Contributions are welcome! Please see CONTRIBUTING.md for instructions.
License
This project is licensed under the GPL-3.0 License. See LICENSE for details.





