{"id":30237689,"url":"https://github.com/markolofsen/django-revolution","last_synced_at":"2025-08-15T02:07:33.916Z","repository":{"id":304206666,"uuid":"1018105076","full_name":"markolofsen/django-revolution","owner":"markolofsen","description":"A powerful Django framework extension that revolutionizes web development with modern patterns, enhanced tooling, and streamlined workflows.","archived":false,"fork":false,"pushed_at":"2025-07-30T06:30:40.000Z","size":1730,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-30T06:39:05.329Z","etag":null,"topics":["django","django-rest-framework","drf-spectacular","nextjs","nodejs","openapi","openapi3","reactjs"],"latest_commit_sha":null,"homepage":"https://revolution.unrealos.com/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/markolofsen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-11T16:02:10.000Z","updated_at":"2025-07-30T06:30:43.000Z","dependencies_parsed_at":"2025-07-11T18:43:50.554Z","dependency_job_id":null,"html_url":"https://github.com/markolofsen/django-revolution","commit_stats":null,"previous_names":["markolofsen/django-revolution"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/markolofsen/django-revolution","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markolofsen%2Fdjango-revolution","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markolofsen%2Fdjango-revolution/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markolofsen%2Fdjango-revolution/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markolofsen%2Fdjango-revolution/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/markolofsen","download_url":"https://codeload.github.com/markolofsen/django-revolution/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markolofsen%2Fdjango-revolution/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270511293,"owners_count":24597666,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-15T02:00:12.559Z","response_time":110,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["django","django-rest-framework","drf-spectacular","nextjs","nodejs","openapi","openapi3","reactjs"],"created_at":"2025-08-15T02:07:30.924Z","updated_at":"2025-08-15T02:07:33.901Z","avatar_url":"https://github.com/markolofsen.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Django Revolution\n\n\u003e **Zero-config TypeScript \u0026 Python client generator for Django REST Framework** 🚀\n\n[![PyPI version](https://badge.fury.io/py/django-revolution.svg)](https://badge.fury.io/py/django-revolution)\n[![Python Support](https://img.shields.io/pypi/pyversions/django-revolution.svg)](https://pypi.org/project/django-revolution/)\n[![Django Support](https://img.shields.io/pypi/djversions/django-revolution.svg)](https://pypi.org/project/django-revolution/)\n[![License](https://img.shields.io/badge/license-Non--Commercial-red.svg)](LICENSE)\n\n## ✨ What is Django Revolution?\n\n**The fastest way to generate fully-authenticated TypeScript + Python clients from Django REST Framework.**\n\n- 🧩 Organize your API into **zones** (`public`, `admin`, `mobile`, etc.)\n- ⚙️ Generate strongly typed clients with **one command**\n- 🔐 Built-in support for **Bearer tokens**, refresh logic, and API keys\n- 🔄 Zero config for **Swagger/OpenAPI URLs**, **frontend integration**, and **monorepos**\n- 🎯 **Optional monorepo integration** - works with or without monorepo structure\n- 🚀 **Dynamic zone management** - no static files, everything generated in-memory\n- 🎨 **Rich CLI interface** - interactive commands with beautiful output\n- ⚡ **Multithreaded generation** - parallel processing for faster client generation\n- 🧪 **Comprehensive testing** - full test suite with pytest\n- 🔧 **Ready-to-use Pydantic configs** - type-safe configuration with IDE support\n\n\u003e No boilerplate. No manual sync. Just clean clients in seconds.\n\n## 🧪 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\u003e 🔐 Auth, ⚙️ Headers, 🔄 Refresh – handled automatically.\n\n## ⛔ Without Django Revolution\n\nManually update OpenAPI spec → Run generator → Fix broken types → Sync clients → Write token logic → Repeat on every change.\n\n## ✅ With Django Revolution\n\nOne command. Done.\n\n### 🐍 Modern Python Generation\n\nDjango Revolution now uses `openapi-python-generator` for:\n\n- ✅ **Pydantic v2 compatibility** - No more validation errors\n- ✅ **Modern HTTP clients** - Using `httpx` for better performance  \n- ✅ **Async \u0026 sync support** - Both `api_service.py` and `async_api_service.py`\n- ✅ **Type-safe configuration** - Full IDE autocomplete and validation\n- ✅ **Enhanced templates** - Custom HTTP client with auth, retries, and error handling\n\n## 🚀 5-Minute Setup\n\n### 1. Install\n\n```bash\npip install django-revolution\n```\n\n\u003e **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** 🎯\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) -\u003e 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) -\u003e 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** ⚡\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## 🧬 What Does It Generate?\n\n| Language       | Location                      | Structure                                                 |\n| -------------- | ----------------------------- | --------------------------------------------------------- |\n| **TypeScript** | `openapi/clients/typescript/` | `public/`, `admin/` → `index.ts`, `types.ts`, `services/` |\n| **Python**     | `openapi/clients/python/`     | `public/`, `admin/` → `models/`, `services/`, `api_config.py` |\n\n💡 Each zone gets its own NPM/PyPI-style package. Ready to publish or import.\n\n### 🐍 Modern Python Client Structure\n\nThe new Python client generation using `openapi-python-generator` creates:\n\n```\npython/\n├── models/\n│   ├── __init__.py\n│   ├── User.py          # Pydantic v2 models\n│   ├── Post.py\n│   └── ...\n├── services/\n│   ├── __init__.py\n│   ├── api_service.py   # Sync HTTP client\n│   └── async_api_service.py  # Async HTTP client\n├── api_config.py        # Configuration \u0026 auth\n├── __init__.py\n├── http_client.py       # Enhanced client (templates)\n├── example.py           # Usage examples\n├── README.md           # Documentation\n└── requirements.txt    # Dependencies\n```\n\n**Features:**\n- ✅ **Pydantic v2 compatibility** - Modern type validation\n- ✅ **Async \u0026 sync clients** - Both `httpx` and `aiohttp` support\n- ✅ **Type-safe configuration** - Full IDE autocomplete\n- ✅ **Modern HTTP client** - Using `httpx` for better performance\n- ✅ **Enhanced templates** - Custom HTTP client with auth \u0026 retries\n\n## ⚡️ TypeScript Client Auth \u0026 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- ✅ Automatic token management (localStorage)\n- ✅ Custom headers support\n- ✅ API key authentication\n- ✅ Zone-based endpoint organization\n- ✅ TypeScript types for all endpoints\n- ✅ Error handling and validation\n\n## 🌐 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## 🧪 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## 🪆 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## 🔧 Configuration\n\n### **Easy Configuration with Ready-to-Use Configs** 🎯\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## ✅ When to Use\n\n### ✅ 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### ❌ 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## 🧠 Power Features\n\n### Dynamic Zone Management\n\n**No more static files!** Django Revolution uses **in-memory dynamic module generation**:\n\n- ✅ **Zero static files** - Everything generated dynamically\n- ✅ **Zone caching** - Fast repeated generation\n- ✅ **Module registry** - Automatic cleanup and management\n- ✅ **URL pattern validation** - Real-time validation\n- ✅ **Schema testing** - Test generation before production\n\n### Archive Management\n\n```bash\n# Automatic versioning with timestamped archives\nopenapi/archive/\n├── files/\n│   ├── 2024-01-15_14-30-00/\n│   │   ├── public.zip\n│   │   └── admin.zip\n│   └── 2024-01-15_15-45-00/\n│       ├── public.zip\n│       └── admin.zip\n└── latest/\n    ├── public.zip\n    └── 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## 📊 Comparison Table\n\n| Feature                           | Django Revolution  | drf-spectacular + generators | openapi-generator-cli | Fern.dev | Manual Setup |\n| --------------------------------- | ------------------ | ---------------------------- | --------------------- | -------- | ------------ |\n| **Zone-based architecture**       | ✅ **UNIQUE**      | ❌                           | ❌                    | ✅       | ❌           |\n| **Dynamic zone management**       | ✅ **UNIQUE**      | ❌                           | ❌                    | ❌       | ❌           |\n| **Automatic URL generation**      | ✅ **UNIQUE**      | ❌                           | ❌                    | ❌       | ❌           |\n| **Monorepo integration**          | ✅ **OPTIONAL**    | ❌                           | ❌                    | ✅       | ❌           |\n| **Django management commands**    | ✅ **UNIQUE**      | ❌                           | ❌                    | ❌       | ❌           |\n| **Rich CLI interface**            | ✅ **UNIQUE**      | ❌                           | ❌                    | ✅       | ❌           |\n| **Zone validation \u0026 testing**     | ✅ **UNIQUE**      | ❌                           | ❌                    | ❌       | ❌           |\n| **Archive management**            | ✅ **UNIQUE**      | ❌                           | ❌                    | ❌       | ❌           |\n| **TypeScript + Python clients**   | ✅                 | ✅                           | ✅                    | ✅       | ✅           |\n| **DRF native integration**        | ✅ **SEAMLESS**    | ✅                           | ⚠️ (via schema)       | ❌       | ✅           |\n| **Ready-to-use Pydantic configs** | ✅ **UNIQUE**      | ❌                           | ❌                    | ❌       | ❌           |\n| **Zero configuration**            | ✅ **UNIQUE**      | ❌                           | ❌                    | ❌       | ❌           |\n| **Environment variables**         | ✅ **Pydantic**    | ❌                           | ❌                    | ❌       | ❌           |\n| **CLI interface**                 | ✅ **Rich output** | ❌                           | ✅                    | ✅       | ❌           |\n| **Multithreaded generation**      | ✅ **UNIQUE**      | ❌                           | ❌                    | ❌       | ❌           |\n| **Comprehensive testing**         | ✅ **UNIQUE**      | ❌                           | ❌                    | ❌       | ❌           |\n| **Modern Python client generation** | ✅ **openapi-python-generator** | ❌ | ✅ | ❌ | ❌ |\n\n## 🙋 FAQ\n\n**Q: Is this production-ready?**  \n✅ 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- 🚀 **Dynamic zone management** - No more static files, everything generated in-memory\n- 🎨 **Rich CLI interface** - Beautiful interactive commands with progress tracking\n- ✅ **Zone validation \u0026 testing** - Validate zones and test schema generation\n- 🔧 **Unified CLI architecture** - Single codebase for Django commands and standalone CLI\n- 📊 **Enhanced output** - Rich tables and progress indicators\n- ⚡ **Multithreaded generation** - Parallel processing for faster client generation\n- 🧪 **Comprehensive testing** - Full test suite with pytest and proper mocking\n- 📦 **Multi-monorepo support** - Support for multiple monorepo configurations\n- 🔧 **pnpm-only integration** - Simplified package manager support\n- 🐍 **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## 🤝 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## 📞 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## 📝 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 ❤️ 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","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarkolofsen%2Fdjango-revolution","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarkolofsen%2Fdjango-revolution","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarkolofsen%2Fdjango-revolution/lists"}