A quick list of the features of this Python API server:
- Simple and flexible server with minimum dependencies
- Process-based request workers, not thread-based nor async
- Secure server-side sessions with Redis storage
- Robust worker management: restarts, timecapping, max life
- Background tasks
- Built-in cron
- Automatic directory page listing the API methods and their docstrings Screenshot
- Redis as a generic storage with expiring keys, lightweight queues
- Email & password authentication with secure algorithms
- User role model and authorization of API methods via simple decorator
- Logging system with practical data for troubleshooting, detects slow requests, warnings&errors colorized
- Server reload on code change
- Database ORM and migrations
- Database init schemas for PostgreSQL and SQLite
- Docker image for the "big cloud" and local development
- Fast rsync deployment of updates to Linux VPS servers
- Tests for the API
- Raspberry compatible
- Simple UI for login/signup/forgot/reset password Screenshot
The whole of this server fits into a small set of files:
├── /ansible/ # ansible files for automated cloud install
├── /conf/ # configuration files
│ ├── /caddy.conf # config for Caddy www proxy that ansible setups
│ ├── /favicon.ico # site icon
│ ├── /loginscript.sh # docker shell login script, sets paths
│ ├── /pydaemon.service # systemd daemon config
│ ├── /robots.txt # deny all from robots
│ ├── /server-config-localdev.json # main server config for localdev in docker
│ ├── /server-config.json # main server config, ansible fills and copies to cloud
│ └── /uwsgi.ini # uwsgi daemon config, for localdev & server
├── /migrations/ # db migrations - postgresql
│ ├── /001_users.py # users table, the foundation
│ └── /002_movies.py # movies table, just as an example
├── /migrations_sqlite/ # db migrations - sqlite
│ ├── /001_init.py # users table, the foundation
│ └── /002_movies.py # movies table, just as an example
├── /py/ # python modules
│ ├── /account.py # account related: passwords, user session
│ ├── /api_account.py # API-endpoints for login/signup/logout
│ ├── /api_dev.py # API-endpoints for dev/testing/api list
│ ├── /api_movies.py # API-endpoints for movies basic crud
│ ├── /bgtasks.py # background tasks, 1 sample method
│ ├── /config.py # central config for the app
│ ├── /cron.py # cron methods: run every min, hourly, daily
│ ├── /db.py # database classes and methods
│ ├── /main.py # server main
│ ├── /red.py # redis: get/set keyvals, lists, atomic
│ ├── /ui_auth.py # quick auth pages
│ ├── /util.py # misc utility functions
│ └── /webutil.py # core web flow: before/after request, auth, role check
├── /scripts/ # scripts
│ └── /dbmigrate.py # db migration
├── /templates/ # templates (if you really need them)
│ ├── /auth.html # login/signup form
│ └── /example.html # very basic jinja2 example
├── /test/ # test scripts
│ ├── /quick.sh # quick adhoc curl example
│ ├── /test_api.py # test API methods
│ ├── /test_redis.py # test redis module
│ └── /sample.log.txt # sample logging output from api test
├── /www/ # static files for Caddy
├── build.sh # build Docker image in dev mode
├── Dockerfile # docker image config
├── requirements.txt # python 3rd party dependencies
├── rsync.sh # rsync sources to server and reload (instead of ansible)
├── run.sh # run server locally with Docker in dev mode
└── shell.sh # run interactive shell inside docker instance
So how do you get started with your own project? I suggest to take this route:
- browse briefly the source files, understand their role
- read and throw away
002_movies.pyandapi_movies.py, they exist only as a sample - discard
cron.py, bgtasks.pyif you don't need background processing - discard
templatesif you only create an API server - write your own business logic:
- create data classes and methods in
db.py or db_x.py - create API modules in
api_x.py - create database migrations
- create tests
- create data classes and methods in