# Django Revolution
> **Zero-config TypeScript & Python client generator for Django REST Framework** ๐
[](https://badge.fury.io/py/django-revolution)
[](https://pypi.org/project/django-revolution/)
[](https://pypi.org/project/django-revolution/)
[](LICENSE)
## โจ What is Django Revolution?
**The fastest way to generate fully-authenticated TypeScript + Python clients from Django REST Framework.**
- ๐งฉ Organize your API into **zones** (`public`, `admin`, `mobile`, etc.)
- โ๏ธ Generate strongly typed clients with **one command**
- ๐ Built-in support for **Bearer tokens**, refresh logic, and API keys
- ๐ Zero config for **Swagger/OpenAPI URLs**, **frontend integration**, and **monorepos**
- ๐ฏ **Optional monorepo integration** - works with or without monorepo structure
- ๐ **Dynamic zone management** - no static files, everything generated in-memory
- ๐จ **Rich CLI interface** - interactive commands with beautiful output
- โก **Multithreaded generation** - parallel processing for faster client generation
- ๐งช **Comprehensive testing** - full test suite with pytest
- ๐ง **Ready-to-use Pydantic configs** - type-safe configuration with IDE support
> No boilerplate. No manual sync. Just clean clients in seconds.
## ๐งช Example: Instantly Get a Typed API Client
### TypeScript Client
```typescript
import API from '@myorg/api-client';
const api = new API('https://api.example.com');
api.setToken('your-access-token');
const profile = await api.public.getProfile();
const items = await api.public.listItems();
```
### Python Client
```python
from public.services.api_service import api_public_api_posts_list
from public.api_config import APIConfig
# Configure API
config = APIConfig(base_path="https://api.example.com")
config.set_access_token("your-access-token")
# Use generated functions
posts = api_public_api_posts_list(api_config_override=config)
print(f"Found {len(posts.results)} posts")
```
> ๐ Auth, โ๏ธ Headers, ๐ Refresh โ handled automatically.
## โ Without Django Revolution
Manually update OpenAPI spec โ Run generator โ Fix broken types โ Sync clients โ Write token logic โ Repeat on every change.
## โ
With Django Revolution
One command. Done.
### ๐ Modern Python Generation
Django Revolution now uses `openapi-python-generator` for:
- โ
**Pydantic v2 compatibility** - No more validation errors
- โ
**Modern HTTP clients** - Using `httpx` for better performance
- โ
**Async & sync support** - Both `api_service.py` and `async_api_service.py`
- โ
**Type-safe configuration** - Full IDE autocomplete and validation
- โ
**Enhanced templates** - Custom HTTP client with auth, retries, and error handling
## ๐ 5-Minute Setup
### 1. Install
```bash
pip install django-revolution
```
> **Note:** Django Revolution now uses `openapi-python-generator` for modern Python client generation with Pydantic v2 compatibility. The system automatically detects the environment and works with Poetry, pip, or direct installation.
### 2. Add to Django Settings
```python
# settings.py
INSTALLED_APPS = [
'drf_spectacular',
'django_revolution', # Add this line
]
```
### 3. **Easy Configuration with Ready-to-Use Configs** ๐ฏ
Django Revolution provides **pre-built Pydantic configurations** that you can import and use directly:
#### **DRF + Spectacular Configuration** (services.py)
```python
# api/settings/config/services.py
from django_revolution.drf_config import create_drf_config
class SpectacularConfig(BaseModel):
"""API documentation configuration using django_revolution DRF config."""
title: str = Field(default='API')
description: str = Field(default='RESTful API')
version: str = Field(default='1.0.0')
schema_path_prefix: str = Field(default='/apix/')
enable_browsable_api: bool = Field(default=False)
enable_throttling: bool = Field(default=False)
def get_django_settings(self) -> Dict[str, Any]:
"""Get drf-spectacular settings using django_revolution config."""
# Use django_revolution DRF config - zero boilerplate!
drf_config = create_drf_config(
title=self.title,
description=self.description,
version=self.version,
schema_path_prefix=self.schema_path_prefix,
enable_browsable_api=self.enable_browsable_api,
enable_throttling=self.enable_throttling,
)
return drf_config.get_django_settings()
```
#### **Zone Configuration** (revolution.py)
```python
# api/settings/config/revolution.py
from django_revolution.app_config import (
DjangoRevolutionConfig,
ZoneConfig,
MonorepoConfig,
get_revolution_config
)
def create_revolution_config(env) -> Dict[str, Any]:
"""Get Django Revolution configuration as dictionary."""
# Define zones with typed Pydantic models
zones = {
'public': ZoneConfig(
apps=['accounts', 'billing', 'payments', 'support', 'public'],
title='Public API',
description='API for public client applications',
public=True,
auth_required=False,
version='v1'
),
'internal': ZoneConfig(
apps=['system', 'mailer'],
title='Internal API',
description='Internal API for backend services',
public=False,
auth_required=True,
version='v1'
),
'admin': ZoneConfig(
apps=['admin_panel', 'services'],
title='Admin API',
description='Administrative API endpoints',
public=False,
auth_required=True,
version='v1'
)
}
# Option 1: Without monorepo (simplest setup)
project_root = env.root_dir
return get_revolution_config(project_root=project_root, zones=zones, debug=env.debug)
# Option 2: With monorepo integration
# monorepo = MonorepoConfig(
# enabled=True,
# path=str(env.root_dir.parent / 'monorepo'),
# api_package_path='packages/api/src'
# )
# return get_revolution_config(project_root=project_root, zones=zones, debug=env.debug, monorepo=monorepo)
```
### 4. **Multithreaded Generation** โก
Django Revolution supports **multithreaded generation** for faster processing:
```python
# settings.py
DJANGO_REVOLUTION = {
'enable_multithreading': True, # Enable parallel processing
'max_workers': 20, # Maximum worker threads (default: 20)
# ... other settings
}
```
**CLI Options:**
```bash
# Use 10 worker threads
python manage.py revolution --generate --max-workers 10
# Disable multithreading
python manage.py revolution --generate --no-multithreading
```
### 5. Generate Clients
```bash
# Generate everything (interactive mode)
python manage.py revolution
# Generate specific zones
python manage.py revolution --zones client admin
# TypeScript only
python manage.py revolution --typescript
# Without monorepo sync
python manage.py revolution --no-monorepo
```
## ๐งฌ What Does It Generate?
| Language | Location | Structure |
| -------------- | ----------------------------- | --------------------------------------------------------- |
| **TypeScript** | `openapi/clients/typescript/` | `public/`, `admin/` โ `index.ts`, `types.ts`, `services/` |
| **Python** | `openapi/clients/python/` | `public/`, `admin/` โ `models/`, `services/`, `api_config.py` |
๐ก Each zone gets its own NPM/PyPI-style package. Ready to publish or import.
### ๐ Modern Python Client Structure
The new Python client generation using `openapi-python-generator` creates:
```
python/
โโโ models/
โ โโโ __init__.py
โ โโโ User.py # Pydantic v2 models
โ โโโ Post.py
โ โโโ ...
โโโ services/
โ โโโ __init__.py
โ โโโ api_service.py # Sync HTTP client
โ โโโ async_api_service.py # Async HTTP client
โโโ api_config.py # Configuration & auth
โโโ __init__.py
```
**Features:**
- โ
**Pydantic v2 compatibility** - Modern type validation
- โ
**Async & sync clients** - Both `httpx` and `aiohttp` support
- โ
**Type-safe configuration** - Full IDE autocomplete
- โ
**Modern HTTP client** - Using `httpx` for better performance
- โ
**Clean structure** - No duplicate files, only essential components
## โก๏ธ TypeScript Client Auth & Usage
Django Revolution automatically generates a smart TypeScript API client with built-in authentication:
```typescript
import API from '@myorg/api-client';
const api = new API('https://api.example.com');
// Authentication
api.setToken('your-access-token', 'your-refresh-token');
// Call any endpoint
const user = await api.public.getCurrentUser();
const products = await api.public.listProducts();
// Check authentication status
if (api.isAuthenticated()) {
// User is logged in
}
```
**Features included:**
- โ
Automatic token management (localStorage)
- โ
Custom headers support
- โ
API key authentication
- โ
Zone-based endpoint organization
- โ
TypeScript types for all endpoints
- โ
Error handling and validation
## ๐ Auto-Generated URLs
Django Revolution **automatically generates** all necessary URLs for your API zones:
```python
# urls.py
from django_revolution import add_revolution_urls
urlpatterns = [
# Your existing URLs
path('admin/', admin.site.urls),
]
# Django Revolution automatically adds:
# - /schema/public/schema/ (OpenAPI spec)
# - /schema/public/schema/swagger/ (Swagger UI)
# - /schema/public/redoc/ (Redoc UI)
# - /schema/admin/schema/ (OpenAPI spec)
# - /schema/admin/schema/swagger/ (Swagger UI)
# - /schema/admin/redoc/ (Redoc UI)
# - /api/public/ (Public API endpoints)
# - /api/admin/ (Admin API endpoints)
# - /openapi/archive/ (Generated clients)
urlpatterns = add_revolution_urls(urlpatterns)
```
## ๐งช CLI Toolbox
### Django Management Commands
```bash
# Generate all clients (interactive mode)
python manage.py revolution
# Specific zones
python manage.py revolution --zones public admin
# Generator options
python manage.py revolution --typescript
python manage.py revolution --python
python manage.py revolution --no-archive
# Monorepo options
python manage.py revolution --no-monorepo
# Utility commands
python manage.py revolution --status
python manage.py revolution --list-zones
python manage.py revolution --validate
python manage.py revolution --clean
# New validation commands
python manage.py revolution --validate-zones
python manage.py revolution --show-urls
python manage.py revolution --test-schemas
```
### Standalone CLI (Interactive)
```bash
# Interactive CLI with rich interface
django-revolution
# Or run directly
python -m django_revolution.cli
```
## ๐ช Multi-Monorepo Integration (Optional)
Django Revolution supports **multiple monorepo configurations** with **pnpm**:
### With Multiple Monorepos
```python
# settings.py - With multiple monorepo configurations
from django_revolution.app_config import MonorepoConfig, MonorepoSettings
# Configure multiple monorepos
monorepo_settings = MonorepoSettings(
enabled=True,
configurations=[
# Main frontend monorepo
MonorepoConfig(
name="frontend",
enabled=True,
path=str(BASE_DIR.parent / 'monorepo'),
api_package_path='packages/api'
),
# Mobile app monorepo
MonorepoConfig(
name="mobile",
enabled=True,
path=str(BASE_DIR.parent / 'mobile-monorepo'),
api_package_path='packages/api-client'
),
# Admin panel monorepo
MonorepoConfig(
name="admin",
enabled=False, # Disabled for now
path=str(BASE_DIR.parent / 'admin-monorepo'),
api_package_path='packages/admin-api'
),
]
)
DJANGO_REVOLUTION = get_revolution_config(
project_root=BASE_DIR,
zones=zones,
monorepo=monorepo_settings
)
```
### With Single Monorepo
```python
# settings.py - With single monorepo (simplest)
from django_revolution.app_config import MonorepoConfig, MonorepoSettings
monorepo_settings = MonorepoSettings(
enabled=True,
configurations=[
MonorepoConfig(
name="frontend",
enabled=True,
path=str(BASE_DIR.parent / 'monorepo'),
api_package_path='packages/api'
),
]
)
DJANGO_REVOLUTION = get_revolution_config(
project_root=BASE_DIR,
zones=zones,
monorepo=monorepo_settings
)
```
### Without Monorepo
```python
# settings.py - Without monorepo (simplest)
DJANGO_REVOLUTION = get_revolution_config(
project_root=BASE_DIR,
zones=zones
)
```
**Auto-generated monorepo structure:**
```yaml
# pnpm-workspace.yaml (auto-generated)
packages:
- 'packages/**'
- 'packages/api/**' # Added automatically
```
**Package.json dependencies:**
```json
{
"dependencies": {
"@markolofsen/public-api-client": "workspace:*",
"@markolofsen/admin-api-client": "workspace:*"
}
}
```
**Generated locally:**
- `openapi/clients/typescript/` - TypeScript clients
- `openapi/clients/python/` - Python clients
- `openapi/archive/` - Versioned archives
## ๐ง Configuration
### **Easy Configuration with Ready-to-Use Configs** ๐ฏ
Django Revolution provides **pre-built Pydantic configurations** that eliminate manual setup:
#### **1. DRF + Spectacular Configuration**
```python
# api/settings/config/services.py
from django_revolution.drf_config import create_drf_config
# One function call - everything configured!
drf_config = create_drf_config(
title="My API",
description="My awesome API",
version="1.0.0",
schema_path_prefix="/apix/",
enable_browsable_api=False,
enable_throttling=True,
)
# Get Django settings
settings = drf_config.get_django_settings()
REST_FRAMEWORK = settings['REST_FRAMEWORK']
SPECTACULAR_SETTINGS = settings['SPECTACULAR_SETTINGS']
```
#### **2. Zone Configuration**
```python
# api/settings/config/revolution.py
from django_revolution.app_config import ZoneConfig, get_revolution_config
# Typed zone definitions with Pydantic models
zones = {
'public': ZoneConfig(
apps=['accounts', 'billing', 'payments'],
title='Public API',
description='API for public client applications',
public=True,
auth_required=False,
version='v1'
),
'admin': ZoneConfig(
apps=['admin_panel', 'analytics'],
title='Admin API',
description='Administrative API endpoints',
public=False,
auth_required=True,
version='v1'
)
}
# Option 1: Without monorepo (simplest)
config = get_revolution_config(project_root=Path.cwd(), zones=zones)
# Option 2: With single monorepo
from django_revolution.app_config import MonorepoConfig, MonorepoSettings
monorepo_settings = MonorepoSettings(
enabled=True,
configurations=[
MonorepoConfig(
name="frontend",
enabled=True,
path=str(Path.cwd().parent / 'monorepo'),
api_package_path='packages/api'
),
]
)
config = get_revolution_config(project_root=Path.cwd(), zones=zones, monorepo=monorepo_settings)
# Option 3: With multiple monorepos
monorepo_settings = MonorepoSettings(
enabled=True,
configurations=[
MonorepoConfig(name="frontend", enabled=True, path=str(Path.cwd().parent / 'monorepo'), api_package_path='packages/api'),
MonorepoConfig(name="mobile", enabled=True, path=str(Path.cwd().parent / 'mobile-monorepo'), api_package_path='packages/api-client'),
MonorepoConfig(name="admin", enabled=False, path=str(Path.cwd().parent / 'admin-monorepo'), api_package_path='packages/admin-api'),
]
)
config = get_revolution_config(project_root=Path.cwd(), zones=zones, monorepo=monorepo_settings)
```
## โ
When to Use
### โ
Perfect For
- **Large Django projects** with multiple API audiences
- **Monorepo architectures** with frontend/backend separation
- **Teams** needing consistent API client generation
- **Projects** requiring zone-based API organization
- **Automated CI/CD** pipelines
- **Simple projects** without monorepo (optional integration)
### โ Not For
- **Simple single-zone APIs** (overkill)
- **Non-Django projects** (use Fern.dev instead)
- **Manual control freaks** (use drf-spectacular + generators)
## ๐ง Power Features
### Dynamic Zone Management
**No more static files!** Django Revolution uses **in-memory dynamic module generation**:
- โ
**Zero static files** - Everything generated dynamically
- โ
**Zone caching** - Fast repeated generation
- โ
**Module registry** - Automatic cleanup and management
- โ
**URL pattern validation** - Real-time validation
- โ
**Schema testing** - Test generation before production
### Archive Management
```bash
# Automatic versioning with timestamped archives
openapi/archive/
โโโ files/
โ โโโ 2024-01-15_14-30-00/
โ โ โโโ public.zip
โ โ โโโ admin.zip
โ โโโ 2024-01-15_15-45-00/
โ โโโ public.zip
โ โโโ admin.zip
โโโ latest/
โโโ public.zip
โโโ admin.zip
```
Each archive contains both TypeScript and Python clients:
- `typescript/` - Generated TypeScript client
- `python/` - Generated Python client
### Custom Templates
```python
'generators': {
'typescript': {
'custom_templates': './templates/typescript'
},
'python': {
'custom_templates': './templates/python'
}
}
```
### Programmatic Usage
```python
from django_revolution import OpenAPIGenerator, get_settings
config = get_settings()
generator = OpenAPIGenerator(config)
summary = generator.generate_all(zones=['public', 'admin'])
```
## ๐ Comparison Table
| Feature | Django Revolution | drf-spectacular + generators | openapi-generator-cli | Fern.dev | Manual Setup |
| --------------------------------- | ------------------ | ---------------------------- | --------------------- | -------- | ------------ |
| **Zone-based architecture** | โ
**UNIQUE** | โ | โ | โ
| โ |
| **Dynamic zone management** | โ
**UNIQUE** | โ | โ | โ | โ |
| **Automatic URL generation** | โ
**UNIQUE** | โ | โ | โ | โ |
| **Monorepo integration** | โ
**OPTIONAL** | โ | โ | โ
| โ |
| **Django management commands** | โ
**UNIQUE** | โ | โ | โ | โ |
| **Rich CLI interface** | โ
**UNIQUE** | โ | โ | โ
| โ |
| **Zone validation & testing** | โ
**UNIQUE** | โ | โ | โ | โ |
| **Archive management** | โ
**UNIQUE** | โ | โ | โ | โ |
| **TypeScript + Python clients** | โ
| โ
| โ
| โ
| โ
|
| **DRF native integration** | โ
**SEAMLESS** | โ
| โ ๏ธ (via schema) | โ | โ
|
| **Ready-to-use Pydantic configs** | โ
**UNIQUE** | โ | โ | โ | โ |
| **Zero configuration** | โ
**UNIQUE** | โ | โ | โ | โ |
| **Environment variables** | โ
**Pydantic** | โ | โ | โ | โ |
| **CLI interface** | โ
**Rich output** | โ | โ
| โ
| โ |
| **Multithreaded generation** | โ
**UNIQUE** | โ | โ | โ | โ |
| **Comprehensive testing** | โ
**UNIQUE** | โ | โ | โ | โ |
| **Modern Python client generation** | โ
**openapi-python-generator** | โ | โ
| โ | โ |
## ๐ FAQ
**Q: Is this production-ready?**
โ
Yes. Used in monorepos and multi-tenant production apps.
**Q: What if I use DRF with custom auth?**
Use `setHeaders()` or `setApiKey()` to inject custom logic.
**Q: Can I use this in non-monorepo setups?**
Absolutely! Monorepo integration is completely optional. Just don't pass the `monorepo` parameter to `get_revolution_config()`.
**Q: How do I configure multiple monorepos?**
Use `MonorepoSettings` with a list of `MonorepoConfig` objects. Each config can be enabled/disabled independently.
**Q: What if I need only TypeScript clients?**
Use `--typescript` flag to generate only TS clients.
**Q: Does it support custom OpenAPI decorators?**
Yes, built on `drf-spectacular` so all extensions apply.
**Q: How do I use the ready-to-use Pydantic configs?**
Simply import and use: `from django_revolution.drf_config import create_drf_config` and `from django_revolution.app_config import ZoneConfig, get_revolution_config`.
**Q: Are the Pydantic configs type-safe?**
Yes! Full Pydantic v2 validation with IDE autocomplete and error checking.
**Q: How do I disable monorepo integration?**
Either don't pass the `monorepo` parameter to `get_revolution_config()`, or use the `--no-monorepo` flag when running the command.
**Q: What's new in the latest version?**
- ๐ **Dynamic zone management** - No more static files, everything generated in-memory
- ๐จ **Rich CLI interface** - Beautiful interactive commands with progress tracking
- โ
**Zone validation & testing** - Validate zones and test schema generation
- ๐ง **Unified CLI architecture** - Single codebase for Django commands and standalone CLI
- ๐ **Enhanced output** - Rich tables and progress indicators
- โก **Multithreaded generation** - Parallel processing for faster client generation
- ๐งช **Comprehensive testing** - Full test suite with pytest and proper mocking
- ๐ฆ **Multi-monorepo support** - Support for multiple monorepo configurations
- ๐ง **pnpm-only integration** - Simplified package manager support
- ๐ **Modern Python client generation** - Switched to `openapi-python-generator` for better Pydantic v2 compatibility
**Q: How does the dynamic zone system work?**
Django Revolution creates URL configuration modules in-memory using Python's `importlib` and `exec`. This eliminates the need for static `.py` files and provides better performance and flexibility.
**Q: How does multithreading improve performance?**
Multithreading allows parallel processing of multiple zones, schema generation, and client generation. For 3 zones, you can see 2-3x speedup compared to sequential processing.
**Q: Why only pnpm support?**
We focus on pnpm for its superior monorepo support, faster installation, and better workspace management. This simplifies the codebase and provides a consistent experience.
**Q: What's the difference between the old and new Python client generation?**
We switched from `datamodel-code-generator` to `openapi-python-generator` for better Pydantic v2 compatibility, improved type safety, and more modern HTTP client generation with proper async support and better error handling.
**Q: Does it work without Poetry?**
Yes! Django Revolution automatically detects your environment and tries multiple ways to run `openapi-python-generator`:
1. Direct command: `openapi-python-generator`
2. Poetry: `poetry run openapi-python-generator`
3. Python module: `python -m openapi_python_generator`
4. Fallback to Poetry (most common)
This ensures it works in any environment - development, production, CI/CD, or Docker containers.
**Q: How do I manage multiple monorepo configurations?**
Use `MonorepoSettings` with a list of `MonorepoConfig` objects. Each configuration can be enabled/disabled independently, and clients are synced to all enabled configurations.
## ๐ค Contributing
```bash
# Development setup
git clone https://github.com/markolofsen/django-revolution.git
cd django-revolution
pip install -e ".[dev]"
# Run tests
pytest
black django_revolution/
isort django_revolution/
```
## ๐ Support
- **Documentation**: [https://revolution.unrealos.com/](https://revolution.unrealos.com/)
- **Issues**: [https://github.com/markolofsen/django-revolution/issues](https://github.com/markolofsen/django-revolution/issues)
- **Discussions**: [https://github.com/markolofsen/django-revolution/discussions](https://github.com/markolofsen/django-revolution/discussions)
## ๐ License
Non-Commercial License - see [LICENSE](LICENSE) file for details.
For commercial use, please contact Unrealos Inc. at licensing@unrealos.com
---
**Made with โค๏ธ by the [Unrealos Team](https://unrealos.com)**
**Django Revolution** - The **ONLY** tool that makes Django API client generation **truly automated** and **zone-aware**.
Raw data
{
"_id": null,
"home_page": "https://unrealos.com",
"name": "django-revolution",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.9",
"maintainer_email": "Unrealos <developers@unrealos.com>",
"keywords": "django, api, openapi, rest, zones, typescript, python, client, generation",
"author": "Unrealos",
"author_email": "Unrealos <developers@unrealos.com>",
"download_url": "https://files.pythonhosted.org/packages/ac/88/b5b15a786bb05795a71486fc3a5a7fade3796edd385189b9a40ced649cd7/django_revolution-1.0.26.tar.gz",
"platform": null,
"description": "# Django Revolution\n\n> **Zero-config TypeScript & Python client generator for Django REST Framework** \ud83d\ude80\n\n[](https://badge.fury.io/py/django-revolution)\n[](https://pypi.org/project/django-revolution/)\n[](https://pypi.org/project/django-revolution/)\n[](LICENSE)\n\n## \u2728 What is Django Revolution?\n\n**The fastest way to generate fully-authenticated TypeScript + Python clients from Django REST Framework.**\n\n- \ud83e\udde9 Organize your API into **zones** (`public`, `admin`, `mobile`, etc.)\n- \u2699\ufe0f Generate strongly typed clients with **one command**\n- \ud83d\udd10 Built-in support for **Bearer tokens**, refresh logic, and API keys\n- \ud83d\udd04 Zero config for **Swagger/OpenAPI URLs**, **frontend integration**, and **monorepos**\n- \ud83c\udfaf **Optional monorepo integration** - works with or without monorepo structure\n- \ud83d\ude80 **Dynamic zone management** - no static files, everything generated in-memory\n- \ud83c\udfa8 **Rich CLI interface** - interactive commands with beautiful output\n- \u26a1 **Multithreaded generation** - parallel processing for faster client generation\n- \ud83e\uddea **Comprehensive testing** - full test suite with pytest\n- \ud83d\udd27 **Ready-to-use Pydantic configs** - type-safe configuration with IDE support\n\n> No boilerplate. No manual sync. Just clean clients in seconds.\n\n## \ud83e\uddea Example: Instantly Get a Typed API Client\n\n### TypeScript Client\n\n```typescript\nimport API from '@myorg/api-client';\n\nconst api = new API('https://api.example.com');\napi.setToken('your-access-token');\n\nconst profile = await api.public.getProfile();\nconst items = await api.public.listItems();\n```\n\n### Python Client\n\n```python\nfrom public.services.api_service import api_public_api_posts_list\nfrom public.api_config import APIConfig\n\n# Configure API\nconfig = APIConfig(base_path=\"https://api.example.com\")\nconfig.set_access_token(\"your-access-token\")\n\n# Use generated functions\nposts = api_public_api_posts_list(api_config_override=config)\nprint(f\"Found {len(posts.results)} posts\")\n```\n\n> \ud83d\udd10 Auth, \u2699\ufe0f Headers, \ud83d\udd04 Refresh \u2013 handled automatically.\n\n## \u26d4 Without Django Revolution\n\nManually update OpenAPI spec \u2192 Run generator \u2192 Fix broken types \u2192 Sync clients \u2192 Write token logic \u2192 Repeat on every change.\n\n## \u2705 With Django Revolution\n\nOne command. Done.\n\n### \ud83d\udc0d Modern Python Generation\n\nDjango Revolution now uses `openapi-python-generator` for:\n\n- \u2705 **Pydantic v2 compatibility** - No more validation errors\n- \u2705 **Modern HTTP clients** - Using `httpx` for better performance \n- \u2705 **Async & sync support** - Both `api_service.py` and `async_api_service.py`\n- \u2705 **Type-safe configuration** - Full IDE autocomplete and validation\n- \u2705 **Enhanced templates** - Custom HTTP client with auth, retries, and error handling\n\n## \ud83d\ude80 5-Minute Setup\n\n### 1. Install\n\n```bash\npip install django-revolution\n```\n\n> **Note:** Django Revolution now uses `openapi-python-generator` for modern Python client generation with Pydantic v2 compatibility. The system automatically detects the environment and works with Poetry, pip, or direct installation.\n\n### 2. Add to Django Settings\n\n```python\n# settings.py\nINSTALLED_APPS = [\n 'drf_spectacular',\n 'django_revolution', # Add this line\n]\n```\n\n### 3. **Easy Configuration with Ready-to-Use Configs** \ud83c\udfaf\n\nDjango Revolution provides **pre-built Pydantic configurations** that you can import and use directly:\n\n#### **DRF + Spectacular Configuration** (services.py)\n\n```python\n# api/settings/config/services.py\nfrom django_revolution.drf_config import create_drf_config\n\nclass SpectacularConfig(BaseModel):\n \"\"\"API documentation configuration using django_revolution DRF config.\"\"\"\n\n title: str = Field(default='API')\n description: str = Field(default='RESTful API')\n version: str = Field(default='1.0.0')\n schema_path_prefix: str = Field(default='/apix/')\n enable_browsable_api: bool = Field(default=False)\n enable_throttling: bool = Field(default=False)\n\n def get_django_settings(self) -> Dict[str, Any]:\n \"\"\"Get drf-spectacular settings using django_revolution config.\"\"\"\n # Use django_revolution DRF config - zero boilerplate!\n drf_config = create_drf_config(\n title=self.title,\n description=self.description,\n version=self.version,\n schema_path_prefix=self.schema_path_prefix,\n enable_browsable_api=self.enable_browsable_api,\n enable_throttling=self.enable_throttling,\n )\n\n return drf_config.get_django_settings()\n```\n\n#### **Zone Configuration** (revolution.py)\n\n```python\n# api/settings/config/revolution.py\nfrom django_revolution.app_config import (\n DjangoRevolutionConfig,\n ZoneConfig,\n MonorepoConfig,\n get_revolution_config\n)\n\ndef create_revolution_config(env) -> Dict[str, Any]:\n \"\"\"Get Django Revolution configuration as dictionary.\"\"\"\n\n # Define zones with typed Pydantic models\n zones = {\n 'public': ZoneConfig(\n apps=['accounts', 'billing', 'payments', 'support', 'public'],\n title='Public API',\n description='API for public client applications',\n public=True,\n auth_required=False,\n version='v1'\n ),\n 'internal': ZoneConfig(\n apps=['system', 'mailer'],\n title='Internal API',\n description='Internal API for backend services',\n public=False,\n auth_required=True,\n version='v1'\n ),\n 'admin': ZoneConfig(\n apps=['admin_panel', 'services'],\n title='Admin API',\n description='Administrative API endpoints',\n public=False,\n auth_required=True,\n version='v1'\n )\n }\n\n # Option 1: Without monorepo (simplest setup)\n project_root = env.root_dir\n return get_revolution_config(project_root=project_root, zones=zones, debug=env.debug)\n\n # Option 2: With monorepo integration\n # monorepo = MonorepoConfig(\n # enabled=True,\n # path=str(env.root_dir.parent / 'monorepo'),\n # api_package_path='packages/api/src'\n # )\n # return get_revolution_config(project_root=project_root, zones=zones, debug=env.debug, monorepo=monorepo)\n```\n\n### 4. **Multithreaded Generation** \u26a1\n\nDjango Revolution supports **multithreaded generation** for faster processing:\n\n```python\n# settings.py\nDJANGO_REVOLUTION = {\n 'enable_multithreading': True, # Enable parallel processing\n 'max_workers': 20, # Maximum worker threads (default: 20)\n # ... other settings\n}\n```\n\n**CLI Options:**\n```bash\n# Use 10 worker threads\npython manage.py revolution --generate --max-workers 10\n\n# Disable multithreading\npython manage.py revolution --generate --no-multithreading\n```\n\n### 5. Generate Clients\n\n```bash\n# Generate everything (interactive mode)\npython manage.py revolution\n\n# Generate specific zones\npython manage.py revolution --zones client admin\n\n# TypeScript only\npython manage.py revolution --typescript\n\n# Without monorepo sync\npython manage.py revolution --no-monorepo\n```\n\n## \ud83e\uddec What Does It Generate?\n\n| Language | Location | Structure |\n| -------------- | ----------------------------- | --------------------------------------------------------- |\n| **TypeScript** | `openapi/clients/typescript/` | `public/`, `admin/` \u2192 `index.ts`, `types.ts`, `services/` |\n| **Python** | `openapi/clients/python/` | `public/`, `admin/` \u2192 `models/`, `services/`, `api_config.py` |\n\n\ud83d\udca1 Each zone gets its own NPM/PyPI-style package. Ready to publish or import.\n\n### \ud83d\udc0d Modern Python Client Structure\n\nThe new Python client generation using `openapi-python-generator` creates:\n\n```\npython/\n\u251c\u2500\u2500 models/\n\u2502 \u251c\u2500\u2500 __init__.py\n\u2502 \u251c\u2500\u2500 User.py # Pydantic v2 models\n\u2502 \u251c\u2500\u2500 Post.py\n\u2502 \u2514\u2500\u2500 ...\n\u251c\u2500\u2500 services/\n\u2502 \u251c\u2500\u2500 __init__.py\n\u2502 \u251c\u2500\u2500 api_service.py # Sync HTTP client\n\u2502 \u2514\u2500\u2500 async_api_service.py # Async HTTP client\n\u251c\u2500\u2500 api_config.py # Configuration & auth\n\u2514\u2500\u2500 __init__.py\n```\n\n**Features:**\n- \u2705 **Pydantic v2 compatibility** - Modern type validation\n- \u2705 **Async & sync clients** - Both `httpx` and `aiohttp` support\n- \u2705 **Type-safe configuration** - Full IDE autocomplete\n- \u2705 **Modern HTTP client** - Using `httpx` for better performance\n- \u2705 **Clean structure** - No duplicate files, only essential components\n\n## \u26a1\ufe0f TypeScript Client Auth & Usage\n\nDjango Revolution automatically generates a smart TypeScript API client with built-in authentication:\n\n```typescript\nimport API from '@myorg/api-client';\n\nconst api = new API('https://api.example.com');\n\n// Authentication\napi.setToken('your-access-token', 'your-refresh-token');\n\n// Call any endpoint\nconst user = await api.public.getCurrentUser();\nconst products = await api.public.listProducts();\n\n// Check authentication status\nif (api.isAuthenticated()) {\n // User is logged in\n}\n```\n\n**Features included:**\n\n- \u2705 Automatic token management (localStorage)\n- \u2705 Custom headers support\n- \u2705 API key authentication\n- \u2705 Zone-based endpoint organization\n- \u2705 TypeScript types for all endpoints\n- \u2705 Error handling and validation\n\n## \ud83c\udf10 Auto-Generated URLs\n\nDjango Revolution **automatically generates** all necessary URLs for your API zones:\n\n```python\n# urls.py\nfrom django_revolution import add_revolution_urls\n\nurlpatterns = [\n # Your existing URLs\n path('admin/', admin.site.urls),\n]\n\n# Django Revolution automatically adds:\n# - /schema/public/schema/ (OpenAPI spec)\n# - /schema/public/schema/swagger/ (Swagger UI)\n# - /schema/public/redoc/ (Redoc UI)\n# - /schema/admin/schema/ (OpenAPI spec)\n# - /schema/admin/schema/swagger/ (Swagger UI)\n# - /schema/admin/redoc/ (Redoc UI)\n# - /api/public/ (Public API endpoints)\n# - /api/admin/ (Admin API endpoints)\n# - /openapi/archive/ (Generated clients)\nurlpatterns = add_revolution_urls(urlpatterns)\n```\n\n## \ud83e\uddea CLI Toolbox\n\n### Django Management Commands\n\n```bash\n# Generate all clients (interactive mode)\npython manage.py revolution\n\n# Specific zones\npython manage.py revolution --zones public admin\n\n# Generator options\npython manage.py revolution --typescript\npython manage.py revolution --python\npython manage.py revolution --no-archive\n\n# Monorepo options\npython manage.py revolution --no-monorepo\n\n# Utility commands\npython manage.py revolution --status\npython manage.py revolution --list-zones\npython manage.py revolution --validate\npython manage.py revolution --clean\n\n# New validation commands\npython manage.py revolution --validate-zones\npython manage.py revolution --show-urls\npython manage.py revolution --test-schemas\n```\n\n### Standalone CLI (Interactive)\n\n```bash\n# Interactive CLI with rich interface\ndjango-revolution\n\n# Or run directly\npython -m django_revolution.cli\n```\n\n## \ud83e\ude86 Multi-Monorepo Integration (Optional)\n\nDjango Revolution supports **multiple monorepo configurations** with **pnpm**:\n\n### With Multiple Monorepos\n\n```python\n# settings.py - With multiple monorepo configurations\nfrom django_revolution.app_config import MonorepoConfig, MonorepoSettings\n\n# Configure multiple monorepos\nmonorepo_settings = MonorepoSettings(\n enabled=True,\n configurations=[\n # Main frontend monorepo\n MonorepoConfig(\n name=\"frontend\",\n enabled=True,\n path=str(BASE_DIR.parent / 'monorepo'),\n api_package_path='packages/api'\n ),\n # Mobile app monorepo\n MonorepoConfig(\n name=\"mobile\",\n enabled=True,\n path=str(BASE_DIR.parent / 'mobile-monorepo'),\n api_package_path='packages/api-client'\n ),\n # Admin panel monorepo\n MonorepoConfig(\n name=\"admin\",\n enabled=False, # Disabled for now\n path=str(BASE_DIR.parent / 'admin-monorepo'),\n api_package_path='packages/admin-api'\n ),\n ]\n)\n\nDJANGO_REVOLUTION = get_revolution_config(\n project_root=BASE_DIR,\n zones=zones,\n monorepo=monorepo_settings\n)\n```\n\n### With Single Monorepo\n\n```python\n# settings.py - With single monorepo (simplest)\nfrom django_revolution.app_config import MonorepoConfig, MonorepoSettings\n\nmonorepo_settings = MonorepoSettings(\n enabled=True,\n configurations=[\n MonorepoConfig(\n name=\"frontend\",\n enabled=True,\n path=str(BASE_DIR.parent / 'monorepo'),\n api_package_path='packages/api'\n ),\n ]\n)\n\nDJANGO_REVOLUTION = get_revolution_config(\n project_root=BASE_DIR,\n zones=zones,\n monorepo=monorepo_settings\n)\n```\n\n### Without Monorepo\n\n```python\n# settings.py - Without monorepo (simplest)\nDJANGO_REVOLUTION = get_revolution_config(\n project_root=BASE_DIR,\n zones=zones\n)\n```\n\n**Auto-generated monorepo structure:**\n\n```yaml\n# pnpm-workspace.yaml (auto-generated)\npackages:\n - 'packages/**'\n - 'packages/api/**' # Added automatically\n```\n\n**Package.json dependencies:**\n\n```json\n{\n \"dependencies\": {\n \"@markolofsen/public-api-client\": \"workspace:*\",\n \"@markolofsen/admin-api-client\": \"workspace:*\"\n }\n}\n```\n\n**Generated locally:**\n\n- `openapi/clients/typescript/` - TypeScript clients\n- `openapi/clients/python/` - Python clients\n- `openapi/archive/` - Versioned archives\n\n## \ud83d\udd27 Configuration\n\n### **Easy Configuration with Ready-to-Use Configs** \ud83c\udfaf\n\nDjango Revolution provides **pre-built Pydantic configurations** that eliminate manual setup:\n\n#### **1. DRF + Spectacular Configuration**\n\n```python\n# api/settings/config/services.py\nfrom django_revolution.drf_config import create_drf_config\n\n# One function call - everything configured!\ndrf_config = create_drf_config(\n title=\"My API\",\n description=\"My awesome API\",\n version=\"1.0.0\",\n schema_path_prefix=\"/apix/\",\n enable_browsable_api=False,\n enable_throttling=True,\n)\n\n# Get Django settings\nsettings = drf_config.get_django_settings()\nREST_FRAMEWORK = settings['REST_FRAMEWORK']\nSPECTACULAR_SETTINGS = settings['SPECTACULAR_SETTINGS']\n```\n\n#### **2. Zone Configuration**\n\n```python\n# api/settings/config/revolution.py\nfrom django_revolution.app_config import ZoneConfig, get_revolution_config\n\n# Typed zone definitions with Pydantic models\nzones = {\n 'public': ZoneConfig(\n apps=['accounts', 'billing', 'payments'],\n title='Public API',\n description='API for public client applications',\n public=True,\n auth_required=False,\n version='v1'\n ),\n 'admin': ZoneConfig(\n apps=['admin_panel', 'analytics'],\n title='Admin API',\n description='Administrative API endpoints',\n public=False,\n auth_required=True,\n version='v1'\n )\n}\n\n# Option 1: Without monorepo (simplest)\nconfig = get_revolution_config(project_root=Path.cwd(), zones=zones)\n\n# Option 2: With single monorepo\nfrom django_revolution.app_config import MonorepoConfig, MonorepoSettings\nmonorepo_settings = MonorepoSettings(\n enabled=True,\n configurations=[\n MonorepoConfig(\n name=\"frontend\",\n enabled=True,\n path=str(Path.cwd().parent / 'monorepo'),\n api_package_path='packages/api'\n ),\n ]\n)\nconfig = get_revolution_config(project_root=Path.cwd(), zones=zones, monorepo=monorepo_settings)\n\n# Option 3: With multiple monorepos\nmonorepo_settings = MonorepoSettings(\n enabled=True,\n configurations=[\n MonorepoConfig(name=\"frontend\", enabled=True, path=str(Path.cwd().parent / 'monorepo'), api_package_path='packages/api'),\n MonorepoConfig(name=\"mobile\", enabled=True, path=str(Path.cwd().parent / 'mobile-monorepo'), api_package_path='packages/api-client'),\n MonorepoConfig(name=\"admin\", enabled=False, path=str(Path.cwd().parent / 'admin-monorepo'), api_package_path='packages/admin-api'),\n ]\n)\nconfig = get_revolution_config(project_root=Path.cwd(), zones=zones, monorepo=monorepo_settings)\n```\n\n## \u2705 When to Use\n\n### \u2705 Perfect For\n\n- **Large Django projects** with multiple API audiences\n- **Monorepo architectures** with frontend/backend separation\n- **Teams** needing consistent API client generation\n- **Projects** requiring zone-based API organization\n- **Automated CI/CD** pipelines\n- **Simple projects** without monorepo (optional integration)\n\n### \u274c Not For\n\n- **Simple single-zone APIs** (overkill)\n- **Non-Django projects** (use Fern.dev instead)\n- **Manual control freaks** (use drf-spectacular + generators)\n\n## \ud83e\udde0 Power Features\n\n### Dynamic Zone Management\n\n**No more static files!** Django Revolution uses **in-memory dynamic module generation**:\n\n- \u2705 **Zero static files** - Everything generated dynamically\n- \u2705 **Zone caching** - Fast repeated generation\n- \u2705 **Module registry** - Automatic cleanup and management\n- \u2705 **URL pattern validation** - Real-time validation\n- \u2705 **Schema testing** - Test generation before production\n\n### Archive Management\n\n```bash\n# Automatic versioning with timestamped archives\nopenapi/archive/\n\u251c\u2500\u2500 files/\n\u2502 \u251c\u2500\u2500 2024-01-15_14-30-00/\n\u2502 \u2502 \u251c\u2500\u2500 public.zip\n\u2502 \u2502 \u2514\u2500\u2500 admin.zip\n\u2502 \u2514\u2500\u2500 2024-01-15_15-45-00/\n\u2502 \u251c\u2500\u2500 public.zip\n\u2502 \u2514\u2500\u2500 admin.zip\n\u2514\u2500\u2500 latest/\n \u251c\u2500\u2500 public.zip\n \u2514\u2500\u2500 admin.zip\n```\n\nEach archive contains both TypeScript and Python clients:\n\n- `typescript/` - Generated TypeScript client\n- `python/` - Generated Python client\n\n### Custom Templates\n\n```python\n'generators': {\n 'typescript': {\n 'custom_templates': './templates/typescript'\n },\n 'python': {\n 'custom_templates': './templates/python'\n }\n}\n```\n\n### Programmatic Usage\n\n```python\nfrom django_revolution import OpenAPIGenerator, get_settings\n\nconfig = get_settings()\ngenerator = OpenAPIGenerator(config)\nsummary = generator.generate_all(zones=['public', 'admin'])\n```\n\n## \ud83d\udcca Comparison Table\n\n| Feature | Django Revolution | drf-spectacular + generators | openapi-generator-cli | Fern.dev | Manual Setup |\n| --------------------------------- | ------------------ | ---------------------------- | --------------------- | -------- | ------------ |\n| **Zone-based architecture** | \u2705 **UNIQUE** | \u274c | \u274c | \u2705 | \u274c |\n| **Dynamic zone management** | \u2705 **UNIQUE** | \u274c | \u274c | \u274c | \u274c |\n| **Automatic URL generation** | \u2705 **UNIQUE** | \u274c | \u274c | \u274c | \u274c |\n| **Monorepo integration** | \u2705 **OPTIONAL** | \u274c | \u274c | \u2705 | \u274c |\n| **Django management commands** | \u2705 **UNIQUE** | \u274c | \u274c | \u274c | \u274c |\n| **Rich CLI interface** | \u2705 **UNIQUE** | \u274c | \u274c | \u2705 | \u274c |\n| **Zone validation & testing** | \u2705 **UNIQUE** | \u274c | \u274c | \u274c | \u274c |\n| **Archive management** | \u2705 **UNIQUE** | \u274c | \u274c | \u274c | \u274c |\n| **TypeScript + Python clients** | \u2705 | \u2705 | \u2705 | \u2705 | \u2705 |\n| **DRF native integration** | \u2705 **SEAMLESS** | \u2705 | \u26a0\ufe0f (via schema) | \u274c | \u2705 |\n| **Ready-to-use Pydantic configs** | \u2705 **UNIQUE** | \u274c | \u274c | \u274c | \u274c |\n| **Zero configuration** | \u2705 **UNIQUE** | \u274c | \u274c | \u274c | \u274c |\n| **Environment variables** | \u2705 **Pydantic** | \u274c | \u274c | \u274c | \u274c |\n| **CLI interface** | \u2705 **Rich output** | \u274c | \u2705 | \u2705 | \u274c |\n| **Multithreaded generation** | \u2705 **UNIQUE** | \u274c | \u274c | \u274c | \u274c |\n| **Comprehensive testing** | \u2705 **UNIQUE** | \u274c | \u274c | \u274c | \u274c |\n| **Modern Python client generation** | \u2705 **openapi-python-generator** | \u274c | \u2705 | \u274c | \u274c |\n\n## \ud83d\ude4b FAQ\n\n**Q: Is this production-ready?** \n\u2705 Yes. Used in monorepos and multi-tenant production apps.\n\n**Q: What if I use DRF with custom auth?** \nUse `setHeaders()` or `setApiKey()` to inject custom logic.\n\n**Q: Can I use this in non-monorepo setups?** \nAbsolutely! Monorepo integration is completely optional. Just don't pass the `monorepo` parameter to `get_revolution_config()`.\n\n**Q: How do I configure multiple monorepos?** \nUse `MonorepoSettings` with a list of `MonorepoConfig` objects. Each config can be enabled/disabled independently.\n\n**Q: What if I need only TypeScript clients?** \nUse `--typescript` flag to generate only TS clients.\n\n**Q: Does it support custom OpenAPI decorators?** \nYes, built on `drf-spectacular` so all extensions apply.\n\n**Q: How do I use the ready-to-use Pydantic configs?** \nSimply import and use: `from django_revolution.drf_config import create_drf_config` and `from django_revolution.app_config import ZoneConfig, get_revolution_config`.\n\n**Q: Are the Pydantic configs type-safe?** \nYes! Full Pydantic v2 validation with IDE autocomplete and error checking.\n\n**Q: How do I disable monorepo integration?** \nEither don't pass the `monorepo` parameter to `get_revolution_config()`, or use the `--no-monorepo` flag when running the command.\n\n**Q: What's new in the latest version?** \n- \ud83d\ude80 **Dynamic zone management** - No more static files, everything generated in-memory\n- \ud83c\udfa8 **Rich CLI interface** - Beautiful interactive commands with progress tracking\n- \u2705 **Zone validation & testing** - Validate zones and test schema generation\n- \ud83d\udd27 **Unified CLI architecture** - Single codebase for Django commands and standalone CLI\n- \ud83d\udcca **Enhanced output** - Rich tables and progress indicators\n- \u26a1 **Multithreaded generation** - Parallel processing for faster client generation\n- \ud83e\uddea **Comprehensive testing** - Full test suite with pytest and proper mocking\n- \ud83d\udce6 **Multi-monorepo support** - Support for multiple monorepo configurations\n- \ud83d\udd27 **pnpm-only integration** - Simplified package manager support\n- \ud83d\udc0d **Modern Python client generation** - Switched to `openapi-python-generator` for better Pydantic v2 compatibility\n\n**Q: How does the dynamic zone system work?** \nDjango Revolution creates URL configuration modules in-memory using Python's `importlib` and `exec`. This eliminates the need for static `.py` files and provides better performance and flexibility.\n\n**Q: How does multithreading improve performance?** \nMultithreading allows parallel processing of multiple zones, schema generation, and client generation. For 3 zones, you can see 2-3x speedup compared to sequential processing.\n\n**Q: Why only pnpm support?** \nWe focus on pnpm for its superior monorepo support, faster installation, and better workspace management. This simplifies the codebase and provides a consistent experience.\n\n**Q: What's the difference between the old and new Python client generation?** \nWe switched from `datamodel-code-generator` to `openapi-python-generator` for better Pydantic v2 compatibility, improved type safety, and more modern HTTP client generation with proper async support and better error handling.\n\n**Q: Does it work without Poetry?** \nYes! Django Revolution automatically detects your environment and tries multiple ways to run `openapi-python-generator`:\n1. Direct command: `openapi-python-generator`\n2. Poetry: `poetry run openapi-python-generator` \n3. Python module: `python -m openapi_python_generator`\n4. Fallback to Poetry (most common)\n\nThis ensures it works in any environment - development, production, CI/CD, or Docker containers.\n\n**Q: How do I manage multiple monorepo configurations?** \nUse `MonorepoSettings` with a list of `MonorepoConfig` objects. Each configuration can be enabled/disabled independently, and clients are synced to all enabled configurations.\n\n## \ud83e\udd1d Contributing\n\n```bash\n# Development setup\ngit clone https://github.com/markolofsen/django-revolution.git\ncd django-revolution\npip install -e \".[dev]\"\n\n# Run tests\npytest\nblack django_revolution/\nisort django_revolution/\n```\n\n## \ud83d\udcde Support\n\n- **Documentation**: [https://revolution.unrealos.com/](https://revolution.unrealos.com/)\n- **Issues**: [https://github.com/markolofsen/django-revolution/issues](https://github.com/markolofsen/django-revolution/issues)\n- **Discussions**: [https://github.com/markolofsen/django-revolution/discussions](https://github.com/markolofsen/django-revolution/discussions)\n\n## \ud83d\udcdd License\n\nNon-Commercial License - see [LICENSE](LICENSE) file for details.\n\nFor commercial use, please contact Unrealos Inc. at licensing@unrealos.com\n\n---\n\n**Made with \u2764\ufe0f by the [Unrealos Team](https://unrealos.com)**\n\n**Django Revolution** - The **ONLY** tool that makes Django API client generation **truly automated** and **zone-aware**.\n",
"bugtrack_url": null,
"license": null,
"summary": "Zone-based API architecture for Django. Install and go.",
"version": "1.0.26",
"project_urls": {
"Documentation": "https://revolution.unrealos.com/",
"Homepage": "https://unrealos.com",
"Repository": "https://github.com/markolofsen/django-revolution"
},
"split_keywords": [
"django",
" api",
" openapi",
" rest",
" zones",
" typescript",
" python",
" client",
" generation"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "b807797dcf23ac8297ffe8dba739d153552e505f9a2f526cf9ff9abc8f9a860c",
"md5": "c3d0b0fc17913f33e6ed4f7c10b9f9be",
"sha256": "206d318e3168a6a7c1ab97d4abb99273197e930eb821b7e43d4f8c90b04d753f"
},
"downloads": -1,
"filename": "django_revolution-1.0.26-py3-none-any.whl",
"has_sig": false,
"md5_digest": "c3d0b0fc17913f33e6ed4f7c10b9f9be",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.9",
"size": 68448,
"upload_time": "2025-08-01T18:54:20",
"upload_time_iso_8601": "2025-08-01T18:54:20.647077Z",
"url": "https://files.pythonhosted.org/packages/b8/07/797dcf23ac8297ffe8dba739d153552e505f9a2f526cf9ff9abc8f9a860c/django_revolution-1.0.26-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "ac88b5b15a786bb05795a71486fc3a5a7fade3796edd385189b9a40ced649cd7",
"md5": "5c6063a65017367b1877b93b028cd54d",
"sha256": "e2534e19f7d2653840ace46dd85b94525d5a941f49a1ed746a93ac9eb961bf96"
},
"downloads": -1,
"filename": "django_revolution-1.0.26.tar.gz",
"has_sig": false,
"md5_digest": "5c6063a65017367b1877b93b028cd54d",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.9",
"size": 73978,
"upload_time": "2025-08-01T18:54:22",
"upload_time_iso_8601": "2025-08-01T18:54:22.692760Z",
"url": "https://files.pythonhosted.org/packages/ac/88/b5b15a786bb05795a71486fc3a5a7fade3796edd385189b9a40ced649cd7/django_revolution-1.0.26.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-01 18:54:22",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "markolofsen",
"github_project": "django-revolution",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "django-revolution"
}