kupio-backend GitHub Details, Stars and Alternatives | OpenRepoFinder
kupio-app / repository
kupio-backend
REST API backend for the Kupio marketplace - built with FastAPI, PostgreSQL, Redis, Stripe payments, FCM push notifications, and real-time WebSocket chat
A transparent discovery signal based on current public GitHub metadata.
Recent activity35% weight
72
Community adoption25% weight
0
Maintenance state20% weight
40
License clarity10% weight
0
Project information10% weight
75
This score does not audit code, security, maintainers, documentation quality, or suitability. Verify the repository and its current documentation before adoption.
README preview
kupio-backend
REST API backend for the Kupio marketplace platform. Built with FastAPI, PostgreSQL, and Redis.
Tech Stack
Python 3.14+ with async/await throughout
FastAPI - HTTP framework
SQLAlchemy 2 (async) + asyncpg - ORM and PostgreSQL driver
Alembic - database migrations
Redis - session/token storage
Poetry - dependency management
Ruff - linting and formatting
Prerequisites
Tool
Version
Python
3.14+
Poetry
2.0+
Docker + Docker Compose
latest
Quick Start (Docker)
The fastest way to get everything running:
# 1. Clone the repository
git clone <repo-url>
cd kupio-backend
# 2. Create your environment file
cp .env.dist .env
# Edit .env - at minimum set AUTH__JWT_SECRET to a random string
# 3. Start the full stack (app + PostgreSQL + Redis)
make app-run
# API is now available at http://localhost:8080
# Swagger UI: http://localhost:8080/api/docs (only when SERVER__DEBUG=true)
Note: The app container automatically runs migrations on startup before starting the server.
Development Setup
For local development you run the app directly (hot-reload) while services run in Docker.
Copy .env.dist to .env and configure the values below.
Variable
Required
Default
Description
POSTGRES__HOST
yes
localhost
PostgreSQL host
POSTGRES__PORT
yes
5432
PostgreSQL port
POSTGRES__DB
yes
kupio
Database name
POSTGRES__USER
yes
-
Database user
POSTGRES__PASSWORD
yes
-
Database password
REDIS__HOST
yes
localhost
Redis host
REDIS__PORT
yes
6379
Redis port
REDIS__PASSWORD
no
-
Redis password (leave empty if none)
REDIS__DB
yes
0
Redis database index
AUTH__JWT_SECRET
yes
-
Secret key for signing JWT tokens
AUTH__JWT_ALGORITHM
no
HS256
JWT signing algorithm
AUTH__ACCESS_TTL
no
15
Access token TTL in minutes
AUTH__REFRESH_TTL
no
7
Refresh token TTL in days
AUTH__NOT_VALIDATE_EXP
no
false
Disable token expiry check (testing only)
SERVER__HOST
no
localhost
Server bind host
SERVER__PORT
no
8080
Server port
SERVER__RELOAD
no
false
Enable auto-reload (dev only)
SERVER__DEBUG
no
false
Enable debug mode and Swagger UI
FIREBASE__CREDENTIALS_PATH
yes
-
Path to Firebase service account JSON file
FIREBASE__PROJECT_ID
yes
-
Firebase project ID
STRIPE__SECRET_KEY
yes
-
Stripe secret key (sk_test_... for dev)
STRIPE__WEBHOOK_SECRET
yes
-
Stripe webhook signing secret (whsec_...)
STRIPE__SUCCESS_URL
yes
-
Redirect URL after successful payment
STRIPE__CANCEL_URL
yes
-
Redirect URL after cancelled payment
When running with Docker (make app-run):SERVER__HOST, POSTGRES__HOST, and REDIS__HOST are automatically set to the correct values for the container network - you do not need to change them.
Firebase Setup
Firebase is used for sending push notifications to mobile devices (FCM).
The path is resolved from the working directory where the server is launched (the project root when using make run).
Important: Add the credentials file to .gitignore — never commit it to version control.
Make Commands
make install # Install Python dependencies via Poetry
make install-hooks # Install pre-commit git hooks
make run # Start dev server locally (requires running services)
make app-run # Start full stack via Docker (app + db + redis)
make app-run-services # Start PostgreSQL + Redis only via Docker
make down # Stop all Docker services
make logs # Follow app container logs
make migrate # Apply pending Alembic migrations
make migration message="describe change" # Autogenerate a new migration
make db-reset # Drop and recreate public schema, then apply all migrations
make lint # Check code style (ruff)
make reformat # Auto-fix and format code (ruff)
make tests # Run full test suite (starts services automatically)
Running Tests
# Run full suite
make tests
# Run a specific test file or case
poetry run pytest tests/auth/test_auth.py -v
poetry run pytest tests/auth/test_auth.py::test_login -v
Tests use an in-memory SQLite database - no running PostgreSQL required.
Testing Stripe Locally
Stripe webhooks require a publicly accessible URL. In development, use the Stripe CLI to forward events to your local server.
1. Install Stripe CLI
# macOS
brew install stripe/stripe-cli/stripe
# Windows and others
Check the official installation guide: https://stripe.com/docs/stripe-cli#install
2. Authenticate
stripe login
This opens a browser to authorize the CLI against your Stripe account.
Restart the dev server after updating .env. Keep the stripe listen process running in a separate terminal - it must stay alive to receive forwarded events.
4. Set your Stripe test secret key
In the Stripe Dashboard, copy the Secret key from the test environment (sk_test_...) and set:
The response contains a checkout_url. Open it in the browser and complete the payment using Stripe's test card:
Field
Value
Card number
4242 4242 4242 4242
Expiry
any future date
CVC
any 3 digits
After completing the payment, Stripe sends a checkout.session.completed event to the CLI, which forwards it to your server. The user's balance is updated automatically.
6. Trigger events manually (without UI)
# Simulate a completed payment
stripe trigger checkout.session.completed
# Simulate an expired session
stripe trigger checkout.session.expired
Note: Manually triggered events use Stripe-generated test data and will not match sessions created via your API. Use them only to verify webhook handler logic in isolation.
Each domain follows the pattern: model.py → repository.py → service.py → router.py.
API
All routes are prefixed with /api:
Prefix
Domain
/api/auth
Authentication (login, logout, refresh)
/api/users
User management
/api/categories
Category tree
/api/categories/{id}/filters
Per-category filter definitions
/api/listings
Listings CRUD
/api/listings/favourites
User favourites
/api/listings/promotions
Listing promotions
/api/promotions/packets
Promotion packets
/api/payments
Stripe checkout, balance transactions, webhooks
/api/chat
Conversations, messages, unread counts, WebSocket
With SERVER__DEBUG=true, interactive docs are available at:
Swagger UI: http://localhost:8080/api/docs
ReDoc: http://localhost:8080/api/redoc
Chat
The chat system uses REST for conversation and message management and WebSockets for real-time delivery.
Key REST endpoints:
Method
Path
Description
POST
/api/chat/conversations/{listing_id}
Start or retrieve a conversation for a listing
GET
/api/chat/conversations
List conversations (role: buyer or seller)
GET
/api/chat/conversations/unread-count
Total unread message count across all conversations
GET
/api/chat/conversations/{id}
Get a single conversation with unread count
GET
/api/chat/conversations/{id}/messages
Paginated message history (also marks as read)
POST
/api/chat/conversations/{id}/messages
Send a message
DELETE
/api/chat/conversations/{id}/messages/{msg_id}
Soft-delete a message
WS
/api/chat/conversations/{id}/ws
Real-time WebSocket connection
Every ConversationResponse includes an unread_count field. Messages are marked as read when the user connects via WebSocket or fetches message history via REST; a messages_read event is broadcast to the conversation channel so the other participant can update their UI in real time.