FAQ & Troubleshooting
Common questions and solutions for Django-CFG gRPC integration.
🎯 General Questions
What is gRPC?
gRPC is Google’s high-performance RPC framework using Protocol Buffers. It’s faster and more efficient than REST for service-to-service communication.
When to use gRPC:
- ✅ Microservices communication
- ✅ Mobile app backends (efficient binary protocol)
- ✅ Real-time streaming
- ✅ High-performance APIs
When to use REST:
- ✅ Public APIs (easier for third-party integration)
- ✅ Browser-based apps (limited gRPC-web support)
- ✅ Simple CRUD operations
Why use Django-CFG gRPC?
- ✅ Zero configuration - Auto-discovers services
- ✅ Django integration - Full ORM, auth, admin access
- ✅ Production-ready - Logging, metrics, error handling
- ✅ Developer-friendly - Base classes, helpers, good DX
Can I run gRPC and Django HTTP together?
Yes! They run on different ports:
- Django HTTP:
localhost:8000 - gRPC:
localhost:50051
Start both servers:
# Terminal 1: Django HTTP
python manage.py runserver
# Terminal 2: gRPC
python manage.py rungrpcDo I need proto files?
For development: No! Use Dynamic Invocation with reflection.
For production clients: Yes, recommended for type safety and performance.
For testing: No, use grpcurl or DynamicGRPCClient.
🔧 Setup & Configuration
Server won’t start
Check 1: Port in use
lsof -ti :50051 | xargs kill -9Check 2: Dependencies installed
pip install django-cfg[grpc]Check 3: Migrations run
python manage.py migrateCheck 4: Config enabled
grpc: GRPCConfig = GRPCConfig(enabled=True)Service not discovered
Check file name:
✅ apps/users/grpc_services.py
❌ apps/users/grpc_service.py (missing 's')
❌ apps/users/services.pyCheck app in enabled_apps:
grpc: GRPCConfig = GRPCConfig(
enabled_apps=["apps.users"] # Must include app
)Check class inheritance:
# ✅ Correct
class UserService(BaseService):
pass
# ❌ Wrong
class UserService:
passImport errors
Wrong path:
# ❌ Old path (doesn't work)
from django_cfg.apps.grpc.services import BaseService
# ✅ Correct path
from django_cfg.apps.integrations.grpc.services import BaseService🔐 Authentication
How to create API key?
Option 1: Django admin
from django_cfg.apps.integrations.grpc.models import GrpcApiKey
from django.contrib.auth import get_user_model
User = get_user_model()
user = User.objects.get(username='admin')
api_key = GrpcApiKey.objects.create_for_user(
user=user,
name="My Service",
key_type="service",
expires_in_days=365
)
print(f"API Key: {api_key.key}")Option 2: Django Admin UI
- Go to
/admin/integrations/grpc/grpcapikey/ - Click “Add gRPC API Key”
- Fill in name, user, type, expiration
- Save and copy the generated key
Authentication not working
Check 1: Auth enabled
auth=GRPCAuthConfig(enabled=True)Check 2: API key in metadata
grpcurl -H "x-api-key: <your_key>" ...Check 3: API key is valid
from django_cfg.apps.integrations.grpc.models import GrpcApiKey
# Check if API key exists and is active
GrpcApiKey.objects.filter(key='<your_key>', is_active=True).exists()Make method public
# Option 1: In config
auth=GRPCAuthConfig(
enabled=True,
public_methods=[
"/api.users.UserService/GetUser",
],
)
# Option 2: In service (use get_user instead of require_user)
def GetUser(self, request, context):
user = self.get_user(context) # Optional
if user:
# Authenticated
pass
else:
# Anonymous
pass🐛 Common Errors
”UNAUTHENTICATED: Authentication required”
Cause: Method requires API key but none provided.
Solution:
# Add x-api-key header
grpcurl -H "x-api-key: <your_api_key>" \
localhost:50051 api.users.UserService/Method“NOT_FOUND: User not found”
Cause: Database record doesn’t exist.
Solution: Check database, verify ID exists:
User.objects.filter(id=request.user_id).exists()“PERMISSION_DENIED: No access”
Cause: User lacks required permission.
Solution: Check user permissions:
user.has_perm('app.permission_name')
user.is_staff
user.is_superuser“INVALID_ARGUMENT: Bad request”
Cause: Invalid request data (missing required fields, wrong types).
Solution: Validate input in service:
if not request.field:
self.abort_invalid_argument(context, "field is required")“INTERNAL: Internal server error”
Cause: Unhandled exception in service.
Solution: Check logs, add error handling:
try:
# Your code
pass
except SpecificException as e:
self.abort_invalid_argument(context, str(e))
except Exception as e:
logger.exception("Unexpected error")
self.abort_internal(context, "Internal error")📊 Performance
Slow requests
Check 1: Database queries (N+1)
# ❌ Bad: N+1 queries
users = User.objects.all()
for user in users:
profile = user.profile # Extra query per user!
# ✅ Good: Single query
users = User.objects.select_related('profile').all()Check 2: Missing indexes
# Add index to frequently queried fields
class Meta:
indexes = [
models.Index(fields=['user_id', 'status']),
]Check 3: Thread pool size
# Increase workers for high concurrency
server=GRPCServerConfig(max_workers=20)Memory usage high
Check 1: Limit queryset size
# ❌ Bad: Load all
users = User.objects.all()
# ✅ Good: Limit + pagination
users = User.objects.all()[:100]
# ✅ Better: Streaming
for user in User.objects.iterator(chunk_size=100):
yield user_pb2.User(...)Check 2: Close connections
# Django handles this, but verify:
CONN_MAX_AGE = 600 # Close after 10 minHigh latency
Check 1: Network latency
ping <server-ip>Check 2: Database location
- Use same region/datacenter for DB and app
- Consider read replicas for read-heavy workloads
Check 3: Disable logging (testing only)
# Temporarily disable request logging
# Not recommended for production🧪 Testing
How to test without client code?
Option 1: grpcurl
grpcurl -plaintext -d '{"user_id": 1}' \
localhost:50051 api.users.UserService/GetUserOption 2: DynamicGRPCClient
from django_cfg.apps.integrations.grpc.services.grpc_client import DynamicGRPCClient
client = DynamicGRPCClient("localhost", 50051)
response = client.invoke_method(
"api.users.UserService",
"GetUser",
{"user_id": 1}
)How to test with authentication?
# Get token first
TOKEN=$(curl -X POST http://localhost:8000/api/token/ \
-d '{"username": "admin", "password": "password"}' \
| jq -r '.access_token')
# Use token in gRPC call
grpcurl -H "Authorization: Bearer $TOKEN" \
-plaintext -d '{"user_id": 1}' \
localhost:50051 api.users.UserService/UpdateProfileUnit testing services
from django.test import TestCase
from apps.users.grpc_services import UserService
class UserServiceTest(TestCase):
def setUp(self):
self.service = UserService()
self.user = User.objects.create_user(username='test')
def test_get_user(self):
# Create mock context
class MockContext:
pass
context = MockContext()
request = type('Request', (), {'user_id': self.user.id})()
response = self.service.GetUser(request, context)
self.assertEqual(response.username, 'test')Best Practices
Service organization
apps/users/
├── models.py # Django models
├── serializers.py # DRF serializers (for REST)
├── grpc_services.py # gRPC services
├── views.py # Django views (for web)
└── protos/
└── user.proto # Proto definitionsError handling
class UserService(BaseService):
def GetUser(self, request, context):
try:
user = User.objects.get(id=request.user_id)
return user_pb2.User(...)
except User.DoesNotExist:
self.abort_not_found(context, "User not found")
except ValidationError as e:
self.abort_invalid_argument(context, str(e))
except Exception as e:
logger.exception("Unexpected error in GetUser")
self.abort_internal(context, "Internal error")Logging
import logging
logger = logging.getLogger(__name__)
class UserService(BaseService):
def GetUser(self, request, context):
logger.info(f"GetUser called for user_id={request.user_id}")
user = User.objects.get(id=request.user_id)
logger.debug(f"Found user: {user.username}")
return user_pb2.User(...)Transaction management
from django.db import transaction
class OrderService(BaseService):
@transaction.atomic
def CreateOrder(self, request, context):
# All or nothing
order = Order.objects.create(...)
OrderItem.objects.create(...)
Payment.objects.create(...)
return order_pb2.Order(...)🚀 Deployment
Production checklist
-
enable_reflection=False(security) -
auth.enabled=True(security) - Use PostgreSQL (not SQLite)
- Environment variables for secrets
- Monitoring enabled
- Health checks configured
- Load balancer configured
- TLS/SSL enabled
- Rate limiting (if needed)
- Backups configured
Docker deployment
# Dockerfile
FROM python:3.11
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
# Expose ports
EXPOSE 8000 50051
# Start both servers
CMD ["sh", "-c", "python manage.py runserver 0.0.0.0:8000 & python manage.py rungrpc --host 0.0.0.0"]Kubernetes deployment
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: django-app
spec:
replicas: 3
template:
spec:
containers:
- name: django
image: myapp:latest
ports:
- containerPort: 8000 # HTTP
- containerPort: 50051 # gRPC
env:
- name: GRPC_ENABLED
value: "true"
- name: GRPC_HOST
value: "0.0.0.0"🔍 Debugging
Enable debug logging
# settings.py
LOGGING = {
'loggers': {
'django_cfg.apps.integrations.grpc': {
'level': 'DEBUG',
},
},
}Check request logs
from django_cfg.apps.integrations.grpc.models import GRPCRequestLog
# Recent errors
GRPCRequestLog.objects.filter(status='error').order_by('-created_at')[:10]
# Slow requests
GRPCRequestLog.objects.filter(duration_ms__gt=1000).order_by('-duration_ms')Debug with grpcurl
# Very verbose output
grpcurl -v -plaintext localhost:50051 list
# See request/response
grpcurl -plaintext -v \
-d '{"user_id": 1}' \
localhost:50051 api.users.UserService/GetUser📚 Additional Resources
- Getting Started - Build your first service
- Concepts - Understand architecture
- Configuration - All config options
- Dynamic Invocation - Testing guide
Still having issues? Check Django-CFG documentation or create an issue with:
- Django version
- Python version
- Full error traceback
- Configuration (without secrets)