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 start-server    # web server
python viperctl.py start-worker    # 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 start-server

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 start-worker

📂 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.9.tar.gz (471.4 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.9-py3-none-any.whl (579.8 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for openviper-0.0.9.tar.gz
Algorithm Hash digest
SHA256 d85d18d9f7a9365af8207209496d2839fef98ad6c0972aa7500bbb58efaf07a3
MD5 bb60c4a7dbb3e9fa821fcd3cf9195d34
BLAKE2b-256 1cdb10804507cc381f3673917a1077fb984454698934e724d75b96e3396549dd

See more details on using hashes here.

Provenance

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

Publisher: publish-pypi.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.9-py3-none-any.whl.

File metadata

  • Download URL: openviper-0.0.9-py3-none-any.whl
  • Upload date:
  • Size: 579.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for openviper-0.0.9-py3-none-any.whl
Algorithm Hash digest
SHA256 62de7f20da75da470457b04f19c1be472d2a0dd5749f4b437b1db9e852e62f60
MD5 81cedb053d4cb0be55720434145b8ba6
BLAKE2b-256 12b0c80140148c3b16550f3cf62d93a142b121cc2f4b509f6c4424f194c5c81d

See more details on using hashes here.

Provenance

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

Publisher: publish-pypi.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