Skip to main content

A production-ready, high-performance, async-first Python web framework.

Project description

🐍 OpenViper

A production-ready, high-performance, async-first Python web framework.

The freedom of a minimal core. The power of a full stack.

Python License Version


OpenViper is a production-ready, high-performance, async-first Python web framework designed to be both flexible and batteries-included. It gives you the freedom of a minimal, unopinionated core when you want control, while also providing a rich, fully integrated stack when you want to move fast.

Out of the box it includes a powerful ORM with model lifecycle and events, built-in authentication and authorization, an Admin UI, background task processing, a pluggable AI provider registry, and automatic OpenAPI documentation.

Whether you're building lean APIs or full-scale platforms, OpenViper scales with you — without forcing you into rigid architectural constraints.


✨ Features

🔀 Routing function-based and class-based (View) routes, path params, route groups
🗄️ ORM Async models, QuerySet API, migrations, lifecycle hooks, model events
🔐 Auth Session + JWT, password hashing, roles, permissions, @login_required
🖥️ Admin UI Auto-discovered SPA — CRUD, bulk actions, change history, inlines
🔧 Middleware Auth, CORS, CSRF, rate-limiting, security headers
⚙️ Background Tasks Task queue with retry, priorities, model-event hooks
🕐 Scheduler Cron and interval periodic jobs built into the framework
🤖 AI Registry Unified async API — OpenAI, Anthropic, Gemini, Ollama, Grok, custom
📦 Serializers Pydantic-based, ModelSerializer, Serializer, nested, partial updates, role-aware
📄 OpenAPI Live Swagger + ReDoc UIs auto-generated from your routes

🚀 Quick Start

Install

pip install openviper

Minimal — single file

# app.py
from openviper import OpenViper, JSONResponse
from openviper.http.request import Request

app = OpenViper(title="My API")


@app.get("/")
async def index(request: Request) -> JSONResponse:
    return JSONResponse({"message": "Hello, OpenViper!"})

@app.get("/users/{user_id}")
async def get_user(request: Request, user_id: int) -> JSONResponse:
    return JSONResponse({"id": user_id, "name": "Alice"})

@app.post("/users")
async def create_user(request: Request) -> JSONResponse:
    body = await request.json()
    return JSONResponse({"created": True, **body}, status_code=201)
openviper run app --reload

Open in your browser:

  • APIhttp://localhost:8000
  • Swagger UIhttp://localhost:8000/open-api/docs
  • ReDochttp://localhost:8000/open-api/redoc

Full project (with DB, auth, admin)

# Scaffold a new project
openviper create-project myproject
cd myproject
openviper create-app blog

# Configure your myproject/settings.py


# Run migrations and create an admin user
python viperctl.py makemigrations
python viperctl.py migrate
python viperctl.py createsuperuser

# Start everything
python viperctl.py runserver    # web server
python viperctl.py runworker    # background task worker (separate terminal)

📚 Core Concepts

Models & ORM

# blog/models.py
from openviper.db import Model
from openviper.db.fields import (
    CharField, TextField, BooleanField, DateTimeField, ForeignKey,
)
from openviper.auth import get_user_model

User = get_user_model()

class Post(Model):
    _app_name = "blog"

    title      = CharField(max_length=255)
    content    = TextField()
    author     = ForeignKey(User, on_delete="CASCADE")
    published  = BooleanField(default=False)
    created_at = DateTimeField(auto_now_add=True)
    updated_at = DateTimeField(auto_now=True)

    class Meta:
        table_name = "blog_posts"

    async def after_insert(self):
        # Lifecycle hook — enqueue moderation task after every new post
        print("Post created:", self.title)
        send_welcome_email.send_with_options(args=(self.id,), delay=5_000)

    async def on_update(self):
        # Lifecycle hook — update timestamp before every update
        print("Post updated:", self.title)

    async def on_delete(self):
        # Lifecycle hook — delete related comments after every post deletion
        print("Post deleted:", self.title)

QuerySet API:

# All published posts, newest first
posts = await Post.objects.filter(published=True).order_by("-created_at").all()

# Single record — returns None if not found
post = await Post.objects.get_or_none(id=42)

# Count
drafts = await Post.objects.filter(published=False).count()

# Async iteration
async for post in Post.objects.filter(author_id=user.id):
    print(post.title)

# Bulk update
await Post.objects.filter(author_id=user.id).update(published=True)

Admin Panel

Register models in blog/admin.py — OpenViper discovers it automatically:

from openviper.admin import ModelAdmin, ActionResult, action, register
from .models import Post

@register(Post)
class PostAdmin(ModelAdmin):
    list_display  = ["id", "title", "author", "published", "created_at"]
    list_filter   = ["published"]
    search_fields = ["title", "content"]
    actions       = ["publish_selected"]

    @action(description="Publish selected posts")
    async def publish_selected(self, queryset, request):
        count = await queryset.update(published=True)
        return ActionResult(success=True, count=count, message=f"Published {count} posts.")

start server

python viperctl.py runserver

Visit http://localhost:8000/admin

Background Tasks

# blog/tasks.py
from openviper.tasks import task

@task()
async def send_welcome_email(post_id: int):
    """
    Do something
    """

Periodic Scheduler

from openviper.tasks.scheduler import periodic
from openviper.tasks.schedule import CronSchedule, IntervalSchedule
from datetime import timedelta

@periodic(every=60)
async def morning_digest():
    ...

@periodic(every=300)
async def refresh_cache():
    ...
python viperctl.py runworker

📂 Examples

Example Description
todoapp Single-file app — auth, admin, SQLite, HTML templates
ai_moderation_platform Multi-app platform — AI moderation, Dramatiq tasks, Docker, PostgreSQL
ai_smart_recipe_generator AI-powered recipe generator with meal planning and nutrition analysis
ecommerce_clone Full e-commerce platform — products, orders, cart, chat, admin
custom_provider_demo Writing and registering a custom AI provider plugin
flexible Minimal decorator-based routing example
fx FX / financial data example
tp Minimal project scaffold example

📖 Documentation

Full reference documentation lives in https://mymi14s.github.io/openviper/.


⚙️ Requirements

  • Python ≥ 3.14
  • Supported DB driver — PostgreSQL, MySQL/MariaDB, SQLite

📜 License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

openviper-0.0.3.tar.gz (937.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

openviper-0.0.3-py3-none-any.whl (1.0 MB view details)

Uploaded Python 3

File details

Details for the file openviper-0.0.3.tar.gz.

File metadata

  • Download URL: openviper-0.0.3.tar.gz
  • Upload date:
  • Size: 937.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for openviper-0.0.3.tar.gz
Algorithm Hash digest
SHA256 5321c6f169cd63516c844dea4cdd4ce02541bafcacef51539186fe67a5c117ac
MD5 1280c3081c0969fe0759679b2d391d63
BLAKE2b-256 788f03986033fc749abdb1cea98a48b87e0188d00f7683487951996e45aa8ff1

See more details on using hashes here.

Provenance

The following attestation bundles were made for openviper-0.0.3.tar.gz:

Publisher: release.yml on mymi14s/openviper

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file openviper-0.0.3-py3-none-any.whl.

File metadata

  • Download URL: openviper-0.0.3-py3-none-any.whl
  • Upload date:
  • Size: 1.0 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for openviper-0.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 ec172e5e8f7f991e66ef1f7df359f87ed106dcf769cfe287c230d83805448f77
MD5 77fce9f0011aa8737ddbad785844596c
BLAKE2b-256 5b32f067902dadb6c3cbd48a9f8bb5af25c19adce9c0c3f3e5314cb637e58412

See more details on using hashes here.

Provenance

The following attestation bundles were made for openviper-0.0.3-py3-none-any.whl:

Publisher: release.yml on mymi14s/openviper

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page