This release is a pre-release and may not be stable for production use.
Skrift
A modern Litestar-powered content management framework with multi-provider OAuth authentication, role-based access control, and WordPress-like template resolution.
Features
- Multi-Provider OAuth: Authenticate with Google, GitHub, Microsoft, Discord, Facebook, or Twitter/X
- Role-Based Access Control: Flexible permission system with Admin, Editor, Author, and Moderator roles
- Setup Wizard: Guided first-time configuration without manual file editing
- Admin Interface: Web-based management for users, pages, and site settings
- WordPress-like Templates: Hierarchical template resolution for content pages
- Content Fields: Declare editable fields in code; non-developers edit them in the admin
- Dynamic Controllers: Load controllers from
app.yamlconfiguration - SQLAlchemy Integration: Async database support with SQLite/PostgreSQL
- Client-Side Sessions: Encrypted cookie sessions for horizontal scalability
- Hook/Filter System: WordPress-like extensibility with async support
- SEO Metadata: Built-in meta descriptions, OpenGraph tags, and robots directives
- Content Scheduling: Schedule pages to publish at a future date
- Page Revisions: Automatic content history with restore capability
- Sitemap & Robots.txt: Auto-generated with filter extensibility
Quick Start
Prerequisites
- Python 3.13+
Installation
# Install Skrift
pip install skrift
# Or install from git
pip install git+https://github.com/ZechCodes/skrift.git
Getting Started
Create a project directory and set up your environment:
mkdir mysite && cd mysite
# Create minimal environment file
echo "SECRET_KEY=$(python -c 'import secrets; print(secrets.token_urlsafe(32))')" > .env
# Start Skrift
skrift
Open http://localhost:8080 to launch the setup wizard.
Setup Wizard
The setup wizard guides you through initial configuration:
- Database Configuration: Choose SQLite (dev) or PostgreSQL (production)
- Authentication Providers: Configure OAuth credentials
- Site Settings: Set site name, tagline, and copyright info
- Admin Account: Create your first admin user via OAuth login
After completing the wizard, an app.yaml configuration file is created in your project directory.
Manual Configuration
Alternatively, create app.yaml manually:
controllers:
- skrift.controllers.auth:AuthController
- skrift.admin.controller:AdminController
- skrift.controllers.web:WebController
db:
url: sqlite+aiosqlite:///./app.db
auth:
redirect_base_url: http://localhost:8080
providers:
google:
client_id: $GOOGLE_CLIENT_ID
client_secret: $GOOGLE_CLIENT_SECRET
scopes: [openid, email, profile]
Then run migrations and start the server:
skrift-db upgrade head
skrift
Documentation
- Full Documentation: Comprehensive guide covering all features
- Deployment Guide: VPS, Docker, and Kubernetes deployment
- CSS Framework: Styling documentation
Project Structure
skrift/
├── skrift/ # Main Python package
│ ├── asgi.py # Application factory
│ ├── config.py # Settings management
│ ├── controllers/ # Route handlers (auth, web, sitemap)
│ ├── admin/ # Admin panel
│ ├── auth/ # RBAC and guards
│ ├── db/ # Models and services
│ │ ├── models/ # Page, User, Role, PageRevision
│ │ └── services/ # page_service, revision_service
│ ├── lib/ # Core utilities
│ │ ├── hooks.py # Hook/filter system
│ │ ├── seo.py # SEO metadata utilities
│ │ ├── flash.py # Enhanced flash messages
│ │ └── template.py # Template resolver
│ └── setup/ # Setup wizard
├── templates/ # Jinja2 templates
├── static/ # Static assets
├── alembic/ # Database migrations
├── docs/ # Documentation
├── app.yaml # Application config (generated)
└── main.py # Development entry point
Configuration
Environment Variables
| Variable | Required | Description |
|---|---|---|
SECRET_KEY |
Yes | Session encryption key |
DEBUG |
No | Enable debug mode (default: false) |
DATABASE_URL |
No | Database connection string |
OAUTH_REDIRECT_BASE_URL |
No | OAuth callback base URL |
OAuth credentials are configured per-provider (e.g., GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET).
app.yaml
Application configuration is stored in app.yaml (generated by setup wizard):
controllers:
- skrift.controllers.auth:AuthController
- skrift.admin.controller:AdminController
- skrift.controllers.web:WebController
db:
url: $DATABASE_URL
pool_size: 5
auth:
redirect_base_url: $OAUTH_REDIRECT_BASE_URL
providers:
google:
client_id: $GOOGLE_CLIENT_ID
client_secret: $GOOGLE_CLIENT_SECRET
Environment variables (prefixed with $) are interpolated at runtime.
Deployment
Minimal VPS Deployment
# Install Skrift
pip install skrift
# Create project directory
mkdir -p /opt/skrift && cd /opt/skrift
# Configure environment
cat > .env << EOF
SECRET_KEY=$(python -c "import secrets; print(secrets.token_urlsafe(32))")
DATABASE_URL=sqlite+aiosqlite:///./app.db
OAUTH_REDIRECT_BASE_URL=https://yourdomain.com
EOF
# Start server (use setup wizard or create app.yaml manually)
skrift
Production with Hypercorn
hypercorn skrift.asgi:app --workers 4 --bind 0.0.0.0:8080
See the Deployment Guide for detailed instructions including Docker, Docker Compose, and Kubernetes deployments.
Database Migrations
# Apply migrations
skrift-db upgrade head
# Create new migration
skrift-db revision --autogenerate -m "description"
# Rollback
skrift-db downgrade -1
Template Resolution
Templates follow WordPress-like hierarchical resolution:
| URL Path | Templates Tried |
|---|---|
/about |
page-about.html -> page.html |
/services/web |
page-services-web.html -> page-services.html -> page.html |
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Submit a pull request
License
MIT
Metadata
Release files for skrift 0.2.0a14
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| skrift-0.2.0a14.tar.gz | 452.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| skrift-0.2.0a14-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.1 MB
Release files / skrift-0.2.0a14.tar.gz
| Download URL | skrift-0.2.0a14.tar.gz |
|---|---|
| Size | 452.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bbb4bf46ea4b395b990c37510242e19c1f56b5d3cefdf37d7bfdc42b79213922
|
|
BLAKE2b-256 checksum How to use checksums |
699e32737d608d423cd83ab63ea8260f4e2fbcaf7bbbd89abdfd5032e7459162
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.11.32 {"installer":{"name":"uv","version":"0.11.32","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / skrift-0.2.0a14-py3-none-any.whl
| Download URL | skrift-0.2.0a14-py3-none-any.whl |
|---|---|
| Size | 623.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b163115817d1b04448b70259239688a8e580c9bb80b9fd61591357853a6db893
|
|
BLAKE2b-256 checksum How to use checksums |
ce67be1309acd777b07ba5448423ee81ceb3c3dc09a182a8ee8a993f604827cb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.11.32 {"installer":{"name":"uv","version":"0.11.32","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|