An open API service indexing awesome lists of open source software.

https://github.com/zechcodes/skrift

A lightweight CMS built with Litestar and SQLAlchemy
https://github.com/zechcodes/skrift

Last synced: about 2 months ago
JSON representation

A lightweight CMS built with Litestar and SQLAlchemy

Awesome Lists containing this project

README

          

# Skrift

[![Python 3.12+](https://img.shields.io/badge/python-3.12+-blue.svg?style=flat-square)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](https://opensource.org/licenses/MIT)
[![Built with Litestar](https://img.shields.io/badge/Built%20with-Litestar-blue.svg?style=flat-square)](https://litestar.dev/)

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
- **Dynamic Controllers**: Load controllers from `app.yaml` configuration
- **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

```bash
# 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:

```bash
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:

1. **Database Configuration**: Choose SQLite (dev) or PostgreSQL (production)
2. **Authentication Providers**: Configure OAuth credentials
3. **Site Settings**: Set site name, tagline, and copyright info
4. **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:

```yaml
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:

```bash
skrift-db upgrade head
skrift
```

## Documentation

- **[Full Documentation](docs/README.md)**: Comprehensive guide covering all features
- **[Deployment Guide](docs/deployment.md)**: VPS, Docker, and Kubernetes deployment
- **[CSS Framework](docs/css-framework.md)**: 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):

```yaml
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

```bash
# 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

```bash
hypercorn skrift.asgi:app --workers 4 --bind 0.0.0.0:8080
```

See the [Deployment Guide](docs/deployment.md) for detailed instructions including Docker, Docker Compose, and Kubernetes deployments.

## Database Migrations

```bash
# 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

1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Submit a pull request

## License

MIT