A powerful Django library for automatic GraphQL API generation with advanced features
Project description
Rail Django GraphQL
A powerful Django library for automatic GraphQL schema generation with advanced features including type generation, query optimization, permissions, and comprehensive debugging tools.
Features
- 🚀 Automatic Schema Generation: Generate GraphQL schemas from Django models with zero configuration
- 🔧 Type Generators: Automatic GraphQL type creation with customizable field mappings
- 🔍 Query Optimization: Built-in query optimization and N+1 problem prevention
- 🛡️ Advanced Permissions: Flexible permission system with field-level access control
- 🐛 Debugging Tools: Comprehensive debugging and introspection capabilities
- 📊 Performance Monitoring: Built-in performance metrics and query analysis
- 🔌 Plugin System: Extensible architecture with custom plugins
- 🎨 GraphiQL Integration: Enhanced GraphiQL interface with custom tools
- 📝 Auto Documentation: Automatic API documentation generation
- 🔒 Security Features: Built-in security measures and validation
Installation
From PyPI (Recommended)
pip install rail-django-graphql
From GitHub (Development Version)
# Install directly from GitHub
pip install git+https://github.com/raillogistic/rail-django-graphql.git
# Or clone and install locally
git clone https://github.com/raillogistic/rail-django-graphql.git
cd rail-django-graphql
pip install -e .
Optional Dependencies
Install additional features:
# Authentication support
pip install rail-django-graphql[auth]
# Performance optimizations
pip install rail-django-graphql[performance]
# Media handling
pip install rail-django-graphql[media]
# Monitoring and metrics
pip install rail-django-graphql[monitoring]
# All optional features
pip install rail-django-graphql[all]
Quick Start
1. Add to Django Settings
# settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# GraphQL dependencies
'graphene_django',
'django_filters',
'corsheaders',
# Rail Django GraphQL
'rail_django_graphql',
# Your apps
'your_app',
]
# GraphQL Configuration
GRAPHENE = {
'SCHEMA': 'your_project.schema.schema',
'MIDDLEWARE': [
'rail_django_graphql.middleware.QueryOptimizationMiddleware',
'rail_django_graphql.middleware.PermissionMiddleware',
'rail_django_graphql.middleware.DebuggingMiddleware',
],
}
# Rail Django GraphQL Settings
RAIL_GRAPHQL = {
'AUTO_GENERATE_SCHEMA': True,
'ENABLE_DEBUGGING': True,
'ENABLE_INTROSPECTION': True,
'MAX_QUERY_DEPTH': 10,
'ENABLE_QUERY_OPTIMIZATION': True,
}
2. Create Your Schema
# schema.py
import graphene
from rail_django_graphql import (
TypeGenerator,
QueryGenerator,
MutationGenerator,
SchemaBuilder
)
from your_app.models import User, Post, Comment
# Generate types automatically
UserType = TypeGenerator.from_model(User)
PostType = TypeGenerator.from_model(Post)
CommentType = TypeGenerator.from_model(Comment)
# Generate queries
class Query(graphene.ObjectType):
# Auto-generated queries
users = QueryGenerator.list_field(User)
user = QueryGenerator.detail_field(User)
posts = QueryGenerator.list_field(Post)
post = QueryGenerator.detail_field(Post)
# Custom queries
my_posts = graphene.List(PostType)
def resolve_my_posts(self, info):
return Post.objects.filter(author=info.context.user)
# Generate mutations
class Mutation(graphene.ObjectType):
create_post = MutationGenerator.create_mutation(Post)
update_post = MutationGenerator.update_mutation(Post)
delete_post = MutationGenerator.delete_mutation(Post)
# Build schema
schema = SchemaBuilder.build(
query=Query,
mutation=Mutation,
auto_discover=True # Automatically discover and include all models
)
3. Add URLs
# urls.py
from django.contrib import admin
from django.urls import path, include
from graphene_django.views import GraphQLView
from rail_django_graphql.views.graphql_views import (
MultiSchemaGraphQLView,
SchemaListView,
GraphQLPlaygroundView,
)
from rail_django_graphql.health_urls import health_urlpatterns
urlpatterns = [
path('admin/', admin.site.urls),
# Single schema endpoint (backward compatible)
path('graphql/', GraphQLView.as_view(graphiql=True)),
# Multi-schema endpoints
path('graphql/<str:schema_name>/', MultiSchemaGraphQLView.as_view(), name='graphql-by-schema'),
path('schemas/', SchemaListView.as_view(), name='graphql-schemas'),
path('playground/<str:schema_name>/', GraphQLPlaygroundView.as_view(), name='graphql-playground'),
# Health endpoints
path('health/', include(health_urlpatterns)),
]
4. Run Migrations and Start Server
python manage.py migrate
python manage.py runserver
Visit http://localhost:8000/graphql/ to access the GraphiQL interface.
Advanced Usage
Multi-Schema Setup
The library supports multiple schemas with per-schema settings, endpoints, and GraphiQL control.
- Enable multi-schema in settings and register schemas via the registry:
# settings.py
RAIL_DJANGO_GRAPHQL = {
"MULTI_SCHEMA_ENABLED": True,
}
# myapp/schema_config.py
from rail_django_graphql.core.registry import schema_registry
schema_registry.register_schema(
name="public_api",
description="Public API for customers",
version="1.0.0",
apps=["customers", "products"],
models=["Customer", "Product"],
enabled=True,
settings={
"enable_graphiql": True,
"authentication_required": False,
},
)
schema_registry.register_schema(
name="admin_api",
description="Admin API for internal use",
version="1.0.0",
apps=["customers", "products", "orders"],
models=["Customer", "Product", "Order", "User"],
enabled=True,
settings={
"enable_graphiql": True,
"authentication_required": True,
},
)
- Configure URLs to expose per-schema endpoints:
from django.urls import path
from rail_django_graphql.views.graphql_views import MultiSchemaGraphQLView, SchemaListView, GraphQLPlaygroundView
urlpatterns = [
path('graphql/<str:schema_name>/', MultiSchemaGraphQLView.as_view(), name='graphql-by-schema'),
path('schemas/', SchemaListView.as_view(), name='graphql-schemas'),
path('playground/<str:schema_name>/', GraphQLPlaygroundView.as_view(), name='graphql-playground'),
]
Endpoints provided:
GET/POST /graphql/<schema_name>/— Execute queries against the specified schemaGET /schemas/— List registered schemas and their metadataGET /playground/<schema_name>/— Open a schema-specific GraphQL Playground
- Control per-schema authentication and GraphiQL:
schema_registry.register_schema(
name="secure_api",
enabled=True,
settings={
"authentication_required": True,
"permission_classes": ["django.contrib.auth.permissions.IsAuthenticated"],
"enable_graphiql": False, # Disable GraphiQL for production
},
)
See more details in rail_django_graphql/views/graphql_views.py and the integration tests in rail_django_graphql/tests/integration/test_multi_schema.py.
Custom Type Generation
from rail_django_graphql import TypeGenerator
from your_app.models import User
# Basic type generation
UserType = TypeGenerator.from_model(User)
# Advanced type generation with custom fields
UserType = TypeGenerator.from_model(
User,
fields=['id', 'username', 'email', 'first_name', 'last_name'],
exclude_fields=['password'],
custom_fields={
'full_name': graphene.String(),
'post_count': graphene.Int(),
},
custom_resolvers={
'full_name': lambda user, info: f"{user.first_name} {user.last_name}",
'post_count': lambda user, info: user.posts.count(),
}
)
Permission System
from rail_django_graphql.permissions import BasePermission
class IsOwnerOrReadOnly(BasePermission):
def has_permission(self, info, obj=None):
if info.context.method == 'GET':
return True
return obj and obj.owner == info.context.user
# Apply to queries
posts = QueryGenerator.list_field(
Post,
permission_classes=[IsOwnerOrReadOnly]
)
Query Optimization
# Automatic optimization is enabled by default
# Manual optimization for complex queries
from rail_django_graphql.optimization import QueryOptimizer
class Query(graphene.ObjectType):
posts = graphene.List(PostType)
@QueryOptimizer.optimize(['author', 'comments__user'])
def resolve_posts(self, info):
return Post.objects.all()
Configuration
Settings Reference
RAIL_GRAPHQL = {
# Schema Generation
'AUTO_GENERATE_SCHEMA': True,
'AUTO_DISCOVER_MODELS': True,
'SCHEMA_OUTPUT_PATH': 'schema.json',
# Security
'ENABLE_INTROSPECTION': True, # Disable in production
'MAX_QUERY_DEPTH': 10,
'MAX_QUERY_COMPLEXITY': 1000,
'ENABLE_QUERY_WHITELIST': False,
# Performance
'ENABLE_QUERY_OPTIMIZATION': True,
'ENABLE_DATALOADER': True,
'CACHE_TIMEOUT': 300,
# Debugging
'ENABLE_DEBUGGING': True, # Disable in production
'LOG_QUERIES': True,
'LOG_SLOW_QUERIES': True,
'SLOW_QUERY_THRESHOLD': 1.0, # seconds
# Permissions
'DEFAULT_PERMISSION_CLASSES': [
'rail_django_graphql.permissions.IsAuthenticated',
],
'ENABLE_FIELD_PERMISSIONS': True,
# Extensions
'ENABLE_EXTENSIONS': True,
'EXTENSION_CLASSES': [
'rail_django_graphql.extensions.QueryComplexityExtension',
'rail_django_graphql.extensions.PerformanceExtension',
],
}
Development
Setting up Development Environment
# Clone the repository
git clone https://github.com/raillogistic/rail-django-graphql.git
cd rail-django-graphql
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install development dependencies
pip install -r requirements-dev.txt
# Install the package in development mode
pip install -e .
# Run tests
python -m pytest
# Run linting
black rail_django_graphql
isort rail_django_graphql
flake8 rail_django_graphql
mypy rail_django_graphql
Running Tests
# Run all tests
python -m pytest
# Run with coverage
python -m pytest --cov=rail_django_graphql --cov-report=html
# Run specific test file
python -m pytest rail_django_graphql/tests/test_generators.py
# Run with verbose output
python -m pytest -v
Contributing
We welcome contributions! Please see our Contributing Guide for details.
Development Workflow
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Add tests for your changes
- Run the test suite (
python -m pytest) - Run linting (
black . && isort . && flake8) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Documentation
Requirements
- Python 3.8+
- Django 4.2+
- graphene-django 3.0+
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
Acknowledgments
- Built on top of Graphene-Django
- Inspired by Django REST Framework's design patterns
- Thanks to all contributors and the Django/GraphQL community
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rail_django_graphql-1.1.7.tar.gz.
File metadata
- Download URL: rail_django_graphql-1.1.7.tar.gz
- Upload date:
- Size: 478.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.8.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
240da71695b80a5e82757f0db425b5141be5160f6ed258c1d4ec9db6ea0053a7
|
|
| MD5 |
90a407070a51e0281ca29b346695cef7
|
|
| BLAKE2b-256 |
8279b78c13ff76ea765501e719b815f3c4bccd47e6a02de5ab88fd12b043b9b7
|
File details
Details for the file rail_django_graphql-1.1.7-py3-none-any.whl.
File metadata
- Download URL: rail_django_graphql-1.1.7-py3-none-any.whl
- Upload date:
- Size: 460.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.8.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6f6e931ab5a84481ce3c1768e0ab90182a2a74c8d5244607b2de4e75a644b1c7
|
|
| MD5 |
bcf7c22213d8d3009c3435b9fe4da3a5
|
|
| BLAKE2b-256 |
48600121a12aeb2708b7e12997092435d2c73bc8409667fc5d66c12e5ef36b02
|