https://github.com/nexios-labs/voltar
Sift Validator is a lightweight and expressive Python library for defining, parsing, and validating data structures with ease. Designed for clarity, speed, and full control.
https://github.com/nexios-labs/voltar
asgi async nexios nexios-api voltar
Last synced: 12 months ago
JSON representation
Sift Validator is a lightweight and expressive Python library for defining, parsing, and validating data structures with ease. Designed for clarity, speed, and full control.
- Host: GitHub
- URL: https://github.com/nexios-labs/voltar
- Owner: nexios-labs
- License: bsd-3-clause
- Created: 2025-04-26T03:31:48.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-05-04T04:21:18.000Z (about 1 year ago)
- Last Synced: 2025-06-01T13:15:17.698Z (about 1 year ago)
- Topics: asgi, async, nexios, nexios-api, voltar
- Language: Python
- Homepage: https://nexios-labs.gitbook.io/voltar
- Size: 361 KB
- Stars: 2
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Voltar
A modern Python validation library with Zod-like syntax, async support, and OpenAPI integration.
## Features
- 🔄 **Chainable API**: Intuitive, fluent interface for building validation schemas
- ⚡ **Async Support**: Fast, non-blocking validation for high-performance applications
- 📝 **Type Hints**: Comprehensive typing for excellent editor integration
- 📊 **OpenAPI**: Seamless generation of OpenAPI schemas from your validators
- 🔍 **Powerful Validation**: Built-in validators for common use cases with custom validation support
- 🔧 **Data Transformation**: Transform and normalize data during validation
## Installation
```bash
pip install voltar
```
## Quick Start
```python
import voltar as v
# Define a schema
user_schema = v.Object({
"username": v.String().min(3).max(20).trim(),
"email": v.String().email(),
"age": v.Number().int().min(18).optional(),
"tags": v.List(v.String()).min(1).max(5),
})
# Validate data
try:
valid_user = user_schema.validate({
"username": " johndoe ", # Will be trimmed
"email": "john@example.com",
"tags": ["python", "validation"]
})
print(valid_user)
except ValueError as e:
print(f"Validation error: {e}")
# Async validation
import asyncio
async def validate_user_async():
try:
valid_user = await user_schema.validate_async({
"username": "johndoe",
"email": "john@example.com",
"tags": ["python", "validation"]
})
print(valid_user)
except ValueError as e:
print(f"Validation error: {e}")
asyncio.run(validate_user_async())
```
## OpenAPI Integration
```python
import voltar as v
from voltar.openapi import generate_openapi_schema
user_schema = v.Object({
"username": v.String().min(3).max(20),
"email": v.String().email(),
"age": v.Number().int().min(18),
})
# Generate OpenAPI schema
openapi_schema = generate_openapi_schema(user_schema)
print(openapi_schema)
```
# Schema Modification
Voltar provides powerful schema modification capabilities through three main methods: `extend`, `exclude`, and `omit`. These methods allow you to adapt and reuse schemas flexibly while maintaining type safety and validation rules.
## Extending Schemas (`extend`)
Use `extend` to add new fields to an existing schema without modifying the original:
```python
import voltar as v
# Base user schema
user_schema = v.Object({
"name": v.String(),
"age": v.Number()
})
# Create employee schema by extending user schema
employee_schema = user_schema.extend({
"department": v.String(),
"salary": v.Number()
})
# Base schema remains unchanged
user_data = user_schema.validate({
"name": "John",
"age": 30
})
# Extended schema includes all fields
employee_data = employee_schema.validate({
"name": "John",
"age": 30,
"department": "Engineering",
"salary": 75000
})
```
## Excluding Fields (`exclude`)
Use `exclude` to temporarily ignore specific fields during validation. The fields remain in the schema but aren't validated:
```python
import voltar as v
# Schema with sensitive data
user_schema = v.Object({
"name": v.String(),
"age": v.Number(),
"email": v.Email(),
"ssn": v.String()
})
# Create public view that doesn't validate sensitive fields
public_schema = user_schema.exclude("email", "ssn")
# These fields are allowed but not validated
public_schema.validate({
"name": "John",
"age": 30,
"email": "not-validated", # Would normally fail Email validation
"ssn": "any-value" # No validation performed
})
```
## Omitting Fields (`omit`)
Use `omit` to create a new schema without specific fields. Unlike `exclude`, omitted fields are not allowed in the data:
```python
import voltar as v
# Full user schema
user_schema = v.Object({
"name": v.String(),
"age": v.Number(),
"email": v.Email(),
"password": v.String()
})
# Create public profile schema without sensitive data
profile_schema = user_schema.omit(["password", "email"])
# Valid: only includes allowed fields
profile_schema.validate({
"name": "John",
"age": 30
})
# Invalid: raises ValidationError for omitted fields
profile_schema.validate({
"name": "John",
"age": 30,
"password": "secret" # Error: unexpected field
})
```
## Key Differences: `exclude` vs `omit`
- `exclude`:
- Fields remain in schema but are ignored during validation
- Excluded fields can still be present in the data
- Useful for temporary validation skipping or partial validation
- Validation rules remain for non-excluded fields
- `omit`:
- Creates new schema without specified fields
- Omitted fields are not allowed in the data
- Useful for creating permanent subsets of schemas
- Validates against unexpected fields
## Combining Operations
You can chain or combine these operations for more complex schema modifications:
```python
import voltar as v
# Start with comprehensive schema
full_schema = v.Object({
"name": v.String(),
"age": v.Number(),
"email": v.Email(),
"password": v.String(),
"preferences": v.Object({
"theme": v.String(),
"notifications": v.Boolean()
})
})
# Create public profile schema:
# 1. Omit sensitive fields
# 2. Extend with additional fields
# 3. Exclude validation for specific fields
public_profile = (
full_schema
.omit(["password", "email"]) # Remove sensitive fields
.extend({
"avatar": v.String(),
"bio": v.String()
}) # Add public profile fields
.exclude("preferences") # Don't validate preferences
)
# Usage:
profile = public_profile.validate({
"name": "John",
"age": 30,
"avatar": "https://example.com/avatar.jpg",
"bio": "Software developer",
"preferences": {"invalid": "structure"} # Allowed but not validated
})
```
## Common Use Cases
1. **API Response Schemas**
```python
import voltar as v
# Internal schema with all fields
internal = v.Object({
"id": v.Number(),
"name": v.String(),
"email": v.Email(),
"created_at": v.DateTime(),
"internal_notes": v.String()
})
# Public API response schema
api_response = internal.omit(["internal_notes"])
```
2. **Form Validation**
```python
import voltar as v
# Complete user schema
user = v.Object({
"username": v.String(),
"email": v.Email(),
"password": v.String(),
"confirm_password": v.String()
})
# Schema for profile update form (no password fields)
profile_update = user.omit(["password", "confirm_password"])
```
3. **Role-Based Schemas**
```python
import voltar as v
# Base product schema
product = v.Object({
"id": v.Number(),
"name": v.String(),
"price": v.Number(),
"cost": v.Number(),
"supplier_id": v.String()
})
# Customer view (omit internal fields)
customer_view = product.omit(["cost", "supplier_id"])
# Sale view (exclude validation for internal calculations)
sale_view = product.exclude("cost")
```
## Tips and Best Practices
1. Use `extend` when you need to add new fields while keeping existing ones
2. Use `exclude` when:
- Fields should remain in the data but not be validated
- Validation skipping is temporary
- You need to preserve the field in the output
3. Use `omit` when:
- Fields should not be present in the data
- You're creating a permanent subset of a schema
- You want to enforce field absence
4. When combining operations, consider the order:
- `extend` then `omit` to remove fields from the complete schema
- `omit` then `extend` to add new fields to a reduced schema
- `exclude` can be used at any point to skip validation