Skip to Content

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 rungrpc

Do 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 -9

Check 2: Dependencies installed

pip install django-cfg[grpc]

Check 3: Migrations run

python manage.py migrate

Check 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.py

Check 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: pass

Import 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

  1. Go to /admin/integrations/grpc/grpcapikey/
  2. Click “Add gRPC API Key”
  3. Fill in name, user, type, expiration
  4. 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 min

High 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/GetUser

Option 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/UpdateProfile

Unit 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 definitions

Error 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


Still having issues? Check Django-CFG documentation or create an issue with:

  • Django version
  • Python version
  • Full error traceback
  • Configuration (without secrets)