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.5.tar.gz (1.0 MB 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.5-py3-none-any.whl (1.1 MB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for openviper-0.0.5.tar.gz
Algorithm Hash digest
SHA256 f60df44c63eabba3d6e4d7a8693c3002ad1bc48df56837636b96569e2ce71149
MD5 56c5f079e3b4f01c2eaee86cc3bcb5e9
BLAKE2b-256 7ce5471925f810f1d8af79c5d2c12d00e029203a363e1ebb5ecd7de1cd16da2f

See more details on using hashes here.

Provenance

The following attestation bundles were made for openviper-0.0.5.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.5-py3-none-any.whl.

File metadata

  • Download URL: openviper-0.0.5-py3-none-any.whl
  • Upload date:
  • Size: 1.1 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.5-py3-none-any.whl
Algorithm Hash digest
SHA256 b6687aae53afcee5bf4e3fcf956d81892b961d287d0c0a3283195fa80e937c22
MD5 20b25c5306837b12ed6777fa4406d46b
BLAKE2b-256 a6a2b0768a0d8583a47a189eb77ef67b87e9a023b3193d6e29046abc9dc57528

See more details on using hashes here.

Provenance

The following attestation bundles were made for openviper-0.0.5-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