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.6.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.6-py3-none-any.whl (1.1 MB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: openviper-0.0.6.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.6.tar.gz
Algorithm Hash digest
SHA256 0e1d7c80c6afc64f1f3b4956c8f69680caf0ca50ace6510c4195f77120364f77
MD5 7b5a64e253309fd29c4ee92fac779e50
BLAKE2b-256 db468336645abfea3699c57c7251f45f18e3374fc538c32eda8786be2674e665

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: openviper-0.0.6-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.6-py3-none-any.whl
Algorithm Hash digest
SHA256 d4dea355aa91704af6e17a149d69554646687de42302cc37f3bd33653bb74cd4
MD5 486c05344c991d0f0bed3821300b16a9
BLAKE2b-256 7cfafc8c98322214ec560da9144c0271926ebf3bbce89d182452689e649092d7

See more details on using hashes here.

Provenance

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