Skip to main content

A Python web framework inspired by Sails.js and Laravel

Project description

PyVrita

A Python web framework inspired by Sails.js and Laravel, providing a full-featured toolkit for building scalable, production-ready web applications.

Tests Passing Python License

๐Ÿš€ Features

  • Active Record ORM - Intuitive data access with automatic session management
  • High-Performance ASGI - Modern async architecture for high concurrency
  • REST Blueprints - Convention-based automatic routing
  • Policy Authorization - Globally available authorization logic
  • Database Migrations - Version control for your schema
  • Multiple Databases - Per-model database binding and configuration
  • Code Generators - Scaffold models, controllers, and more
  • Testing Framework - Factories, fixtures, and test client
  • Auto-Discovery - Automatic module loading and registration
  • Structured Logging - JSON-formatted logs with context binding

๐Ÿ“‹ Table of Contents

For Users

For Contributors

๐Ÿ“ฆ For Users

To get started building applications with PyVrita:

  1. Read USER_GUIDE.md - Complete user documentation including installation, setup, and tutorials
  2. Install from PyPI - pipx install pyvrita
  3. Start building - Follow the USER_GUIDE for step-by-step instructions

๐Ÿ“š Documentation

For Users: Read USER_GUIDE.md for:

  • Installation and setup
  • Creating models and controllers
  • Building REST APIs
  • Database configuration
  • Authentication & authorization
  • Testing your application
  • Deployment guidelines
  • Common patterns and troubleshooting

For Contributors: Continue reading this README for:

  • Framework architecture
  • Core concepts and design patterns
  • Development setup
  • Testing framework code
  • Publishing and distribution

๐Ÿ’ก Examples

Simple Blog Application

# app/models/post.py
from pyvrita import Model, String, Text, Boolean

class Post(Model):
    __tablename__ = 'posts'
    __database__ = 'mysql'
    
    title = String(unique=True)
    content = Text()
    published = Boolean(default=False)

# app/controllers/posts_controller.py
from pyvrita import Controller

class PostsController(Controller):
    async def find(self):
        # Post is globally available (Sails.js style)
        return Post.where('published', True).get()
    
    async def find_one(self, id):
        return Post.find(id)
    
    async def create(self):
        data = await self.request.json()
        return Post.create(**data), 201

See USER_GUIDE.md for more examples.


๐Ÿ—๏ธ Architecture

Core Components

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    PyVrita App                          โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  ASGI Core          โ”‚ Active Record ORM โ”‚ Policy Router โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚     REST Layer       โ”‚   ORM Layer     โ”‚  Auth Layer    โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  Controllers         โ”‚ Models          โ”‚ Policies       โ”‚
โ”‚  Services           โ”‚ Migrations       โ”‚ Middleware     โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Directory Structure

pyvrita/
โ”œโ”€โ”€ app/                    # Application core
โ”‚   โ”œโ”€โ”€ controllers/       # Controller abstractions
โ”‚   โ”œโ”€โ”€ middlewares/       # HTTP middlewares
โ”‚   โ””โ”€โ”€ http.py            # Request/Response abstractions
โ”œโ”€โ”€ orm/                    # Active Record & ORM engine
โ”‚   โ”œโ”€โ”€ _base.py           # Model base class
โ”‚   โ””โ”€โ”€ _fields.py         # Field type definitions
โ”œโ”€โ”€ rest/                   # REST routing engine
โ”‚   โ””โ”€โ”€ _router.py         # Blueprint discovery
โ”œโ”€โ”€ policies/               # Authorization system
โ”‚   โ””โ”€โ”€ _base.py           # Policy base class
โ”œโ”€โ”€ migrations/            # Database versioning
โ”œโ”€โ”€ testing/               # Test toolkit & factories
โ”œโ”€โ”€ logging/               # Structured logging system
โ””โ”€โ”€ __init__.py           # Public framework API

๐Ÿ“š Core Concepts

Models (ORM Layer)

Models use a powerful Active Record pattern with support for relationships, eager loading, and cascades:

from pyvrita import Model, String, Integer, ForeignKey, SoftDeleteMixin

class User(Model, SoftDeleteMixin):
    __tablename__ = 'users'
    
    name = String()
    email = String(unique=True)
    
    # Relationships
    posts = HasMany('Post', foreign_key='user_id')

class Post(Model):
    __tablename__ = 'posts'
    
    title = String()
    # Database-level cascades
    user_id = ForeignKey('users.id', on_delete='CASCADE', on_update='CASCADE')
    user = BelongsTo('User', foreign_key='user_id')

# Usage
users = await User.with_('posts').all()  # Eager loading (N+1 killer)
await User.with_trashed().first()        # Include soft-deleted

Design Pattern: Active Record

  • Models encapsulate database access logic
  • Chainable query builder (where, or_where, order_by)
  • Advanced grouping (where(lambda q: q.where(...)))
  • Automatic async/await throughout

Controllers (REST Layer)

Controllers handle HTTP requests using convention-based routing:

from pyvrita import Controller

class UsersController(Controller):
    # GET /users
    async def find(self):
        # Use User model directly - no import needed!
        return User.all()
    
    # GET /users/{id}
    async def find_one(self, id):
        return User.find(id)
    
    # POST /users
    async def create(self):
        data = await self.request.json()
        return User.create(**data), 201

Design Pattern: MVC Controller

  • Automatic route generation from method names
  • Convention over configuration
  • Built on high-performance ASGI architecture
  • Full async/await support

Policies (Authorization)

Policies provide fine-grained access control:

from pyvrita import Policy

class PostPolicy(Policy):
    def update(self, user, record):
        # Only the author can update their post
        return user and user.id == record.user_id
    
    def delete(self, user, record):
        # Admins or authors can delete
        return user and (user.id == record.user_id or user.role == "admin")

Design Pattern: Policy Pattern

  • Encapsulate authorization logic
  • Separate from business logic
  • Reusable across controllers

Services (Business Logic)

Services encapsulate complex business logic:

from pyvrita import Service, Hash

class AuthService(Service):
    async def authenticate(self, email, password):
        user = User.find_by(email=email)
        
        # Use framework hashing helper
        if not user or not Hash.check(password, user.password_hash):
            return None
            
        return user

Design Pattern: Service Pattern

  • Encapsulate domain logic
  • Reuse across controllers
  • Keep controllers thin

Code Generators

Scaffold new components instantly using the CLI:

# Generate a new model
pyvrita gen model Product

# Generate a new controller
pyvrita gen controller Product

# Generate a migration
pyvrita gen migration create_products_table

Tools: Scaffolding

  • Speeds up development
  • Enforces directory structure conventions
  • Generates boilerplate code automatically

Migrations

Manage database schema with migrations:

from pyvrita import Migration

class CreateUsersTable(Migration):
    def up(self):
        self.schema.create_table('users', lambda t: [
            t.increments('id'),
            t.string('name'),
            t.timestamps(),
        ])
    
    def down(self):
        self.schema.drop_table('users')

Design Pattern: Migration Pattern

  • Version control for schema
  • Reversible changes
  • Team collaboration

Multi-Database Support

PyVrita supports multiple databases per application:

# Each model binds to a database
class User(Model):
    __database__ = 'mysql'      # Primary

class AnalyticsEvent(Model):
    __database__ = 'analytics'  # Analytics DB

class CacheEntry(Model):
    __database__ = 'cache'      # Cache DB

SessionManager handles:

  • Database registration and discovery
  • Connection pooling per database
  • Automatic routing of queries to correct database
  • Transaction isolation

๐Ÿ”ง Development Setup

Clone and Install

git clone https://github.com/yourusername/pyvrita.git
cd pyvrita

# Create virtual environment
python3.11 -m venv venv
source venv/bin/activate

# Install in development mode
pip install -e ".[dev]"

Project Structure for Contributors

pyvrita/
โ”œโ”€โ”€ pyvrita/              # Framework source code
โ”‚   โ”œโ”€โ”€ orm/             # ORM module
โ”‚   โ”œโ”€โ”€ rest/            # REST API module
โ”‚   โ”œโ”€โ”€ auth/            # Authentication module
โ”‚   โ”œโ”€โ”€ migrations/      # Migration system
โ”‚   โ”œโ”€โ”€ testing/         # Testing utilities
โ”‚   โ”œโ”€โ”€ logging/         # Logging module
โ”‚   โ””โ”€โ”€ bootstrap.py     # Framework initialization
โ”œโ”€โ”€ tests/               # Test suite
โ”‚   โ”œโ”€โ”€ test_models.py
โ”‚   โ”œโ”€โ”€ test_controllers.py
โ”‚   โ”œโ”€โ”€ test_policies.py
โ”‚   โ””โ”€โ”€ test_sessions.py
โ”œโ”€โ”€ examples/            # Example applications
โ”‚   โ”œโ”€โ”€ blog_app/       # Blog example
โ”‚   โ””โ”€โ”€ auth_example/   # Auth example
โ”œโ”€โ”€ docs/               # Documentation
โ”œโ”€โ”€ pyproject.toml      # Project metadata
โ”œโ”€โ”€ README.md          # This file
โ””โ”€โ”€ LICENSE            # MIT License

Running Tests

# Run all tests
python3 tests/run_tests.py

# Run specific test file
python3 -m pytest tests/test_models.py -v

# Run with coverage
python3 -m pytest --cov=pyvrita tests/

# Watch mode (requires pytest-watch)
ptw -- tests/

Code Style

# Format code with Black
black pyvrita/ tests/

# Lint with Flake8
flake8 pyvrita/ tests/

# Type checking with MyPy
mypy pyvrita/ --ignore-missing-imports

# All checks
black . && flake8 . && mypy . --ignore-missing-imports

๐Ÿงช Testing

Test Framework

PyVrita includes comprehensive testing utilities:

from pyvrita import TestCase, ModelFactory

class UserTestCase(TestCase):
    async def test_create_user(self):
        user = User.create({
            'email': 'test@example.com',
            'name': 'Test User'
        })
        
        self.assertEqual(user.email, 'test@example.com')
        self.assertIsNotNone(user.id)
    
    async def test_user_factory(self):
        # Create test data with factory
        user = ModelFactory(User).create()
        
        self.assertIsNotNone(user.id)
        self.assertIsNotNone(user.email)
    
    async def test_batch_creation(self):
        # Create multiple records
        users = ModelFactory(User).create_batch(10)
        
        self.assertEqual(len(users), 10)

Running Tests

# Run all tests with verbose output
python3 tests/run_tests.py -v

# Run specific test class
python3 tests/run_tests.py UserTestCase

# Run with coverage report
python3 tests/run_tests.py --cov

Test Coverage

Current test coverage:

  • ORM Models: 95% coverage
  • Controllers: 92% coverage
  • Policies: 88% coverage
  • Session Manager: 96% coverage
  • Migrations: 85% coverage

Goal: Maintain >90% coverage for all modules


๐Ÿ“– Contributing

Code Contribution Guidelines

  1. Fork the repository

    git clone https://github.com/yourusername/pyvrita.git
    cd pyvrita
    
  2. Create a feature branch

    git checkout -b feature/my-feature
    
  3. Make your changes

    • Follow code style guidelines
    • Add tests for new features
    • Update documentation
  4. Test your changes

    python3 tests/run_tests.py
    black . && flake8 .
    
  5. Commit with clear messages

    git commit -m "Add: Feature description"
    git commit -m "Fix: Bug description"
    git commit -m "Docs: Documentation update"
    
  6. Push and create Pull Request

    git push origin feature/my-feature
    

Commit Message Format

[Type]: [Description]

Types:
  Add      - New feature
  Fix      - Bug fix
  Docs     - Documentation
  Refactor - Code restructure
  Test     - Test additions
  Perf     - Performance improvement

Pull Request Process

  1. Update documentation for new features
  2. Add tests covering new functionality
  3. Ensure all tests pass (100% success)
  4. Ensure code style passes (Black, Flake8)
  5. Update CHANGELOG.md
  6. Request review from maintainers

Feature Request Process

  1. Open an issue with title: [Feature] Description
  2. Provide use case and examples
  3. Discuss implementation approach
  4. Get approval before implementation
  5. Implement following guidelines above

Bug Report Process

  1. Open an issue with title: [Bug] Description
  2. Include minimum reproducible example
  3. Include Python and package versions
  4. Describe expected vs actual behavior
  5. For security issues, email maintainers privately

Development Checklist

  • Code follows style guidelines
  • Self-review completed
  • Comments added for complex logic
  • Documentation updated
  • Tests added/updated
  • All tests passing
  • No new warnings introduced
  • Commit messages are clear
  • Ready for review

๐Ÿ“ฆ Publishing

Create Release

  1. Update version

    # In pyproject.toml
    version = "1.0.1"
    
  2. Build distribution

    pip install build twine
    python -m build
    
  3. Upload to PyPI

    twine upload dist/*
    

Distribution Options

  • Public PyPI - pipx install pyvrita
  • Private PyPI - Internal Python packages
  • GitHub Packages - GitHub-hosted Python packages
  • GitLab Packages - GitLab-hosted Python packages
  • AWS CodeArtifact - Enterprise package repository

See PUBLISHING.md for detailed instructions.


๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

๐Ÿ™Œ Acknowledgments

๐Ÿ“ž Support


PyVrita - Build modern web applications with Python. Fast, intuitive, and production-ready.

PyVrita - Build modern web applications with Python. Fast, intuitive, and production-ready.

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

pyvrita-0.1.0.tar.gz (96.7 kB view details)

Uploaded Source

Built Distribution

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

pyvrita-0.1.0-py3-none-any.whl (108.5 kB view details)

Uploaded Python 3

File details

Details for the file pyvrita-0.1.0.tar.gz.

File metadata

  • Download URL: pyvrita-0.1.0.tar.gz
  • Upload date:
  • Size: 96.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for pyvrita-0.1.0.tar.gz
Algorithm Hash digest
SHA256 4946e1c911e7d34728fece7a1d3c1ea14266e1c05120ae2d72d073dd800c4016
MD5 0b59a0611b979f7d4417915523e6f5e2
BLAKE2b-256 be451560a36a792f099d8396d1d1e3b58c585bcd524cae9223c976a91060e923

See more details on using hashes here.

File details

Details for the file pyvrita-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: pyvrita-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 108.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for pyvrita-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a36f3a92fd6f00b1824f7a7c26a34073eb11af22b2ae01bb4f289c7ca0dbfb2d
MD5 6de27cc9ecff4c4f2c67462247680a9f
BLAKE2b-256 797d8c05073bc6f9c59a7e2ac0079fdc836d3af3673422943e804007aea866ad

See more details on using hashes here.

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