What's included

Features

Production-ready from day one. Every component you need,
nothing you don't.

Python 3.12 Flask Gunicorn WSGI Docker GCP Cloud Run Jinja2 JWT Auth Adhara
01

Server & Runtime

A solid, modern Python stack — no Node.js, no build steps.

Flask Framework

Clean Blueprint routing, controller pattern, Jinja2 templating, and a factory-based app config. Everything Flask does right, applied consistently.

🔄

Gunicorn WSGI

4 sync workers, configurable timeout, stdout logging — production-grade HTTP server included and pre-configured out of the box.

📈

JSON Message API

Route POST messages through a typed MessageParser dispatcher. Add new message handlers by subclassing — no routing boilerplate.

🔁

WebSocket Support

Persistent bidirectional connections for real-time features. WebSocket handlers live alongside HTTP controllers in the same service layer.

📱

AJAX / Fetch API

JSON endpoints wired to vanilla JS fetch calls. Forms submit without a page reload. Newsletter and contact forms included and ready to wire up.

📄

File Upload

Multipart file upload over HTTP POST with configurable storage path. Files land in a mounted volume — no cloud bucket needed to get started.

02

Deployment

From local dev to Cloud Run — one command at each step.

📦

Docker Container

python:3.12-slim base image. Multi-stage ready. Environment variables drive all runtime config — no secrets baked into the image.

docker-compose

One file wires together the app, port mappings, and persistent volume mounts for data, auth tokens, uploads, and TLS certs.

GCP Cloud Run

Deploy to Google Cloud Run in minutes. Image published to Artifact Registry, service configured for HTTPS, autoscaling to zero when idle.

🔧

Makefile Workflow

make dev, make build, make push, make logs — the full lifecycle in muscle memory. make help prints every target.

🔒

SSL / TLS

Self-signed cert generation via make generate-key. Mount your cert in the security volume for production HTTPS without a reverse proxy.

📋

Environment Config

.env.example documents every variable. GRAVITY_TEMPLATE selects the theme. GRAVITY_ROOT sets the runtime path. Zero hardcoded values.

03

Design System

Change one file — change the entire look and feel.

--color-accent:
#B8860B

Change this one variable → every button, badge, link, and highlight updates across the entire site.

GRAVITY_TEMPLATE=
gravity

Point this at a different folder → completely different HTML structure and CSS, zero code changes.

🎨

CSS Design Tokens

All colors, fonts, spacing, radii, and shadows live in :root {}. Edit the token block — nothing else. The whole site updates.

🔄

Swappable Themes

Each client gets their own views/<theme>/ folder and public/themes/<theme>/main.css. Switch at runtime with one env var.

🔍

Jinja2 SSR

All HTML is server-rendered. No hydration, no JavaScript frameworks, no build pipeline. Fast first paint, great SEO, full accessibility by default.

📷

Mobile Responsive

Every layout collapses cleanly at 768px. Nav becomes a hamburger overlay. Grids go single-column. No media query archaeology required.

Google Fonts

Playfair Display for display headings, Inter for body copy, JetBrains Mono for code — all loaded from the token system, all swappable.

🌈

Scroll Reveal

IntersectionObserver-based fade-up animation on any element with class="reveal". No library, no dependency — 12 lines of vanilla JS.

04

Auth & Admin

Login flows and admin tooling, wired up from day one.

🔐

JWT Authentication

Token-based auth via signed JWTs stored in secure cookies. login_required decorator protects any route with one line.

👔

Admin Dashboard

Fixed sidebar layout with sectioned navigation. Manage blog posts, events, contacts, and users from a unified interface.

👤

Role-Based Access

User records carry admin flags. Controllers check roles before rendering. Public and admin routes are cleanly separated blueprints.

💌

Login / Register

Full auth flow: registration, login, and forgot-password pages — all themeable, all server-rendered, all wired to the user management service.

👥

User Management

Admin user list with add/edit/remove modals. Token file-backed user store — no database required. Swap in a DB layer whenever you're ready.

📋

Member Dashboard

Authenticated member landing page. Shows user context, role info, and a starting point for any member-specific features you want to build.

05

Adhara Integrations

Gravity ships wired for Adhara. Content works out of the box — Commerce unlocks with the SDK.

Adhara

Gravity integrates natively with Adhara — a headless CMS, form engine, commerce platform, and email service built for Python web apps. Blog, events, forms, and newsletter are active by default with an API key. Commerce and advanced features require the Adhara SDK, available as an add-on.

📝

Blog via Adhara

Blog posts pulled from Adhara CMS. Create and publish from your Adhara dashboard — Gravity renders the card grid and post pages automatically.

API key
📅

Events via Adhara

Event listings, details, and registration flows — all managed in Adhara and rendered by Gravity. No separate event database to maintain.

API key
📧

Newsletter via Adhara

AJAX newsletter sign-up routed to Adhara's email list API. Subscribers land in your Adhara workspace, ready for campaigns.

API key
📞

Forms via Adhara

Any form on the site submits to Adhara by slug. Contact, registration, waitlist — responses collected and managed in one place.

API key
💳

Adhara Commerce

Product listings and hosted checkout through Adhara Commerce. The integration point is built in — pip install adhara-sdk and it lights up.

SDK required
📁

File Upload

Upload images and documents via the admin. Files stored in a mounted volume outside the container — persists across deploys and rebuilds.

Built-in

Everything here.
Yours from day one.

Clone, configure, deploy. All the features above ship in the base framework.