Skip to main 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)