Skip to Content
FeaturesModulesgRPC ServerConfiguration

gRPC Configuration

Complete reference for configuring Django-CFG gRPC integration.

📋 Configuration Structure

# api/config.py from typing import Optional from django_cfg import ( DjangoConfig, GRPCConfig, GRPCServerConfig, GRPCKeepaliveConfig, GRPCConnectionLimitsConfig, GRPCAuthConfig, GRPCProtoConfig, ) class MyConfig(DjangoConfig): grpc: Optional[GRPCConfig] = GRPCConfig( enabled=True, server=GRPCServerConfig(...), auth=GRPCAuthConfig(...), proto=GRPCProtoConfig(...), auto_register_apps=True, enabled_apps=[...], )

⚙️ GRPCConfig

Main gRPC configuration container.

FieldTypeDefaultDescription
enabledboolFalseEnable/disable gRPC server
serverGRPCServerConfig-Server configuration
authGRPCAuthConfig-Authentication configuration
protoGRPCProtoConfig-Protocol Buffer configuration
tlsTLSConfig-TLS/SSL configuration (new!)
auto_register_appsboolTrueAuto-discover services
enabled_appslist[str][]Apps to scan for services
TLS Flatten Fields
tls_enabledboolNoneEnable TLS (shortcut)
tls_cert_pathstrNoneServer certificate path
tls_key_pathstrNoneServer private key path

Example

grpc: GRPCConfig = GRPCConfig( enabled=True, auto_register_apps=True, enabled_apps=["apps.users", "apps.products", "apps.orders"], )

🎯 Simplified Configuration (Flatten Fields)

For simpler configs, you can use flatten fields instead of nested config objects:

Traditional (Nested):

grpc = GRPCConfig( enabled=True, server=GRPCServerConfig( host="[::]", port=50051, ), proto=GRPCProtoConfig( package_prefix="api", output_dir="protos", ), enabled_apps=["apps.crypto"], )

Simplified (Flatten):

grpc = GRPCConfig( enabled=True, enabled_apps=["apps.crypto"], # Server fields (flatten) host="[::]", # Instead of server=GRPCServerConfig(host=...) port=50051, # Proto fields (flatten) package_prefix="api", # Instead of proto=GRPCProtoConfig(package_prefix=...) # Environment integration public_url=env.grpc_url, )

Benefits:

  • Less boilerplate code
  • No need to import nested config classes
  • Cleaner configuration
  • Same functionality

When to use nested: When you need to organize complex configs or reuse config objects. When to use flatten: For simple configs (recommended for most cases).

🖥️ GRPCServerConfig

gRPC server settings.

FieldTypeDefaultDescription
hoststr"[::]"Server host address
portint50051Server port
enable_reflectionboolTrueEnable server reflection
enable_health_checkboolTrueEnable health check service
compressionstr | NoneNoneCompression algorithm ("gzip", "deflate")
max_send_message_lengthint4MBMax outbound message size
max_receive_message_lengthint4MBMax inbound message size
keepaliveGRPCKeepaliveConfig-HTTP/2 keepalive settings
connection_limitsGRPCConnectionLimitsConfig-Connection lifecycle limits

Host Options

# All interfaces (IPv6) - Recommended host="[::]" # All interfaces (IPv4) host="0.0.0.0" # Localhost only host="127.0.0.1" # Specific IP host="192.168.1.100"

Reflection

# Development: Enable for grpcurl testing enable_reflection=True # Production: Disable to hide service schema enable_reflection=False

Health Check

# Always recommended for production enable_health_check=True # For load balancers # GET /grpc.health.v1.Health/Check

Complete Example

from django_cfg import GRPCServerConfig, GRPCKeepaliveConfig server=GRPCServerConfig( host="[::]", # All interfaces port=50051, # Standard port enable_reflection=True, # Enable grpcurl enable_health_check=True, # Enable health checks compression="gzip", # Enable gzip compression # Nested keepalive config for streaming keepalive=GRPCKeepaliveConfig.for_streaming(), )

🔄 GRPCKeepaliveConfig

HTTP/2 keepalive configuration for connection health and dead connection detection.

from django_cfg import GRPCKeepaliveConfig
FieldTypeDefaultDescription
time_msint10000Keepalive ping interval (ms). How often to send HTTP/2 PING.
timeout_msint5000Keepalive timeout (ms). How long to wait for PING ACK.
permit_without_callsboolTrueAllow pings even without active RPC calls.
min_time_between_pings_msint5000Minimum time between successive pings (anti-abuse).
max_pings_without_dataint0Max pings without data. 0 = unlimited (streaming).

Factory Methods

# For long-lived bidirectional streaming connections (recommended) # Optimized: 10s ping, 5s timeout = 15s dead connection detection keepalive = GRPCKeepaliveConfig.for_streaming() # For short-lived RPC connections # Less aggressive: 30s ping, 10s timeout keepalive = GRPCKeepaliveConfig.for_short_lived()

Custom Configuration

keepalive = GRPCKeepaliveConfig( time_ms=15000, # Ping every 15 seconds timeout_ms=10000, # Wait 10 seconds for ACK permit_without_calls=True, max_pings_without_data=0, # Unlimited for streaming )

Converting to gRPC Options

# Use to_grpc_options() method for low-level gRPC configuration options = keepalive.to_grpc_options() # Returns: [("grpc.keepalive_time_ms", 15000), ("grpc.keepalive_timeout_ms", 10000), ...]

🔗 GRPCConnectionLimitsConfig

Connection lifecycle limits for server-side connection management.

from django_cfg import GRPCConnectionLimitsConfig
FieldTypeDefaultDescription
max_connection_idle_msint7200000Max idle time (ms) before closing. Default: 2 hours.
max_connection_age_msint0Max connection age (ms). 0 = unlimited (streaming).
max_connection_age_grace_msint300000Grace period (ms) for in-flight RPCs. Default: 5 min.

Example

from django_cfg import GRPCConnectionLimitsConfig # Default: optimized for long-lived streaming connection_limits = GRPCConnectionLimitsConfig() # Custom: shorter limits for REST-like RPC connection_limits = GRPCConnectionLimitsConfig( max_connection_idle_ms=3600000, # 1 hour max_connection_age_ms=86400000, # 24 hours max_connection_age_grace_ms=60000, # 1 minute )

Streaming Recommendation: For bidirectional streaming, use max_connection_age_ms=0 (unlimited) to prevent premature connection closure during long-running streams.

🔐 GRPCAuthConfig

Authentication configuration (supports API keys).

FieldTypeDefaultDescription
enabledboolFalseEnable authentication
require_authboolFalseRequire auth for all methods
API Key Settings
api_key_headerstr"x-api-key"Header name for API key
accept_django_secret_keyboolTrueAccept Django SECRET_KEY as valid API key (for dev/internal use)
General
public_methodslist[str][]Public methods (no auth required)

Authentication Modes

Mode 1: Disabled (Development)

auth=GRPCAuthConfig( enabled=False, # No authentication )

Mode 2: Optional Auth (Recommended)

auth=GRPCAuthConfig( enabled=True, require_auth=False, # Some methods can be public api_key_header="x-api-key", accept_django_secret_key=True, # Allow SECRET_KEY for dev ) # In service: # - Use self.get_user(context) for optional auth # - Use self.require_user(context) for protected methods # - Access context.api_key to check which API key was used

Mode 3: Required Auth (Strict - Production)

auth=GRPCAuthConfig( enabled=True, require_auth=True, # All methods require API key api_key_header="x-api-key", accept_django_secret_key=False, # Production: only DB keys public_methods=[ # Except these "/grpc.health.v1.Health/Check", ], )

Public Methods

auth=GRPCAuthConfig( enabled=True, require_auth=False, public_methods=[ # Health check (always public) "/grpc.health.v1.Health/Check", "/grpc.health.v1.Health/Watch", # Your public methods "/api.users.UserService/GetUser", "/api.products.ProductService/ListProducts", ], )

Complete Example

# Production configuration with API keys auth=GRPCAuthConfig( enabled=True, require_auth=True, # Strict auth in production # API key configuration api_key_header="x-api-key", accept_django_secret_key=False, # Disable SECRET_KEY in production # Public methods public_methods=[ "/grpc.health.v1.Health/Check", "/grpc.health.v1.Health/Watch", ], )

API Key Settings

Custom Header Name

auth=GRPCAuthConfig( api_key_header="x-custom-api-key", # Change header name )

Disable SECRET_KEY (Production)

auth=GRPCAuthConfig( accept_django_secret_key=False, # Only accept keys from database )

Enable SECRET_KEY (Development)

auth=GRPCAuthConfig( accept_django_secret_key=True, # Allow using settings.SECRET_KEY ) # Usage: # grpcurl -H "x-api-key: $(python manage.py shell -c 'from django.conf import settings; print(settings.SECRET_KEY)')" ...

📄 GRPCProtoConfig

Protocol Buffer generation settings.

FieldTypeDefaultDescription
auto_generateboolFalseAuto-generate proto files
output_dirstr"protos"Proto output directory
package_prefixstr"api"Package prefix

Example

proto=GRPCProtoConfig( auto_generate=True, output_dir="protos", package_prefix="api", ) # Generates: # protos/api/users.proto # protos/api/products.proto

🔒 TLSConfig

TLS/SSL configuration for secure gRPC connections. Supports server-side TLS, client TLS, and mutual TLS (mTLS).

from django_cfg.modules.django_grpc.configs import TLSConfig
FieldTypeDefaultDescription
enabledboolFalseEnable TLS/SSL
cert_pathstrNoneServer certificate path (.crt/.pem)
key_pathstrNoneServer private key path (.key/.pem)
ca_cert_pathstrNoneCA certificate for verification
client_cert_pathstrNoneClient certificate (mTLS)
client_key_pathstrNoneClient private key (mTLS)
require_client_certboolFalseRequire client certificate (server-side mTLS)
verify_serverboolTrueVerify server certificate (client-side)
min_versionstr"TLS1.2"Minimum TLS version

Server TLS Example

from django_cfg import GRPCConfig from django_cfg.modules.django_grpc.configs import TLSConfig grpc = GRPCConfig( enabled=True, tls=TLSConfig( enabled=True, cert_path="/etc/ssl/server.crt", key_path="/etc/ssl/server.key", ), # Or use flatten fields: # tls_enabled=True, # tls_cert_path="/etc/ssl/server.crt", # tls_key_path="/etc/ssl/server.key", )

Mutual TLS (mTLS) Example

# Server with client certificate verification tls = TLSConfig( enabled=True, cert_path="/etc/ssl/server.crt", key_path="/etc/ssl/server.key", ca_cert_path="/etc/ssl/ca.crt", # Verify client certs require_client_cert=True, # Require client auth )

📡 ClientChannelConfig

Configuration for gRPC client channels. Use this instead of hardcoded values.

from django_cfg.modules.django_grpc.configs import ClientChannelConfig
FieldTypeDefaultDescription
addressstrrequiredServer address (host:port)
use_tlsboolFalseUse TLS connection
connect_timeoutfloat3.0Connection timeout (seconds)
call_timeoutfloat5.0Default RPC timeout (seconds)
keepalive_time_msint30000Keepalive ping interval
keepalive_timeout_msint10000Keepalive timeout
max_retriesint3Max retry attempts
enable_retriesboolTrueEnable automatic retries
max_send_message_lengthint4MBMax outbound message size
max_receive_message_lengthint4MBMax inbound message size

Example

from django_cfg.modules.django_grpc.configs import ClientChannelConfig, TLSConfig from django_cfg.modules.django_grpc.services.client import DynamicGRPCClient # Create config config = ClientChannelConfig( address="grpc.example.com:443", use_tls=True, max_retries=5, call_timeout=30.0, ) # Create client with config client = DynamicGRPCClient(config=config)

🔁 Resilience Configuration

Production-grade retry, circuit breaker, and structured logging for gRPC operations.

RetryConfig

from django_cfg.modules.django_grpc.resilience import RetryConfig retry = RetryConfig( enabled=True, attempts=5, timeout=30.0, wait_initial=0.1, wait_max=10.0, wait_jitter=0.1, )
FieldTypeDefaultDescription
enabledboolTrueEnable automatic retry
attemptsint5Maximum retry attempts (1-20)
timeoutfloat30.0Total timeout in seconds (1-300)
wait_initialfloat0.1Initial backoff in seconds (0.01-10)
wait_maxfloat10.0Maximum backoff in seconds (1-60)
wait_jitterfloat0.1Jitter factor (0.0-1.0)

CircuitBreakerConfig

from django_cfg.modules.django_grpc.resilience import CircuitBreakerConfig circuit_breaker = CircuitBreakerConfig( enabled=True, fail_max=5, reset_timeout=60.0, success_threshold=2, )
FieldTypeDefaultDescription
enabledboolTrueEnable circuit breaker
fail_maxint5Failures before circuit opens (1-100)
reset_timeoutfloat60.0Seconds before half-open state (1-3600)
success_thresholdint2Successes required to close circuit (1-10)

LoggingConfig

from django_cfg.modules.django_grpc.resilience import LoggingConfig logging_config = LoggingConfig( enabled=True, json_output=True, log_level="INFO", )
FieldTypeDefaultDescription
enabledboolTrueEnable structured logging
json_outputboolTrueJSON format (False = console)
log_levelstr”INFO”Minimum log level

Combined ResilienceConfig

from django_cfg.modules.django_grpc.resilience import ResilienceConfig config = ResilienceConfig( retry=RetryConfig(attempts=5), circuit_breaker=CircuitBreakerConfig(fail_max=5), logging=LoggingConfig(json_output=True), )

Learn more: Resilience Patterns


🏊 Connection Pool Configuration

Efficient channel reuse for high-performance gRPC applications.

PoolConfig

from django_cfg.modules.django_grpc.services.client import PoolConfig pool_config = PoolConfig( max_size=20, idle_timeout=120.0, min_idle=2, max_age=3600.0, cleanup_interval=60.0, )
FieldTypeDefaultDescription
max_sizeint20Maximum channels in pool (1-100)
idle_timeoutfloat120.0Close idle channels after (10-3600s)
min_idleint2Keep minimum idle channels (0-10)
max_agefloat3600.0Maximum channel age (60-86400s)
cleanup_intervalfloat60.0Cleanup check interval (10-600s)

Using Pool with Resilient Client

from django_cfg.modules.django_grpc.services.client import ( AsyncResilientGRPCClient, PoolConfig, ) async with AsyncResilientGRPCClient( host="localhost", port=50051, use_pool=True, pool_config=PoolConfig(max_size=50), ) as client: result = await client.call_method(...)

Learn more: Connection Pooling


🎯 Environment-Specific Configs

Development

from django_cfg import GRPCKeepaliveConfig class DevelopmentConfig(DjangoConfig): DEBUG = True grpc: GRPCConfig = GRPCConfig( enabled=True, server=GRPCServerConfig( host="127.0.0.1", # Localhost only port=50051, enable_reflection=True, # Enable for testing enable_health_check=True, ), auth=GRPCAuthConfig( enabled=True, # Enable auth even in dev require_auth=False, api_key_header="x-api-key", accept_django_secret_key=True, # Allow SECRET_KEY for convenience ), enabled_apps=["apps.users"], # Limited apps )

Production

from django_cfg import GRPCKeepaliveConfig, GRPCConnectionLimitsConfig class ProductionConfig(DjangoConfig): DEBUG = False grpc: GRPCConfig = GRPCConfig( enabled=True, server=GRPCServerConfig( host="[::]", # All interfaces port=50051, enable_reflection=False, # Disable in production enable_health_check=True, # Keep health checks # Optimized keepalive for streaming keepalive=GRPCKeepaliveConfig.for_streaming(), connection_limits=GRPCConnectionLimitsConfig( max_connection_idle_ms=7200000, # 2 hours ), ), auth=GRPCAuthConfig( enabled=True, # Enable auth require_auth=True, # Require by default # API key configuration api_key_header="x-api-key", accept_django_secret_key=False, # Disable SECRET_KEY in production public_methods=[ "/grpc.health.v1.Health/Check", ], ), enabled_apps=[ "apps.users", "apps.products", "apps.orders", "apps.payments", ], )

Testing

class TestingConfig(DjangoConfig): TESTING = True grpc: GRPCConfig = GRPCConfig( enabled=True, server=GRPCServerConfig( host="127.0.0.1", port=50052, # Different port enable_reflection=True, enable_health_check=False, # Not needed in tests ), auth=GRPCAuthConfig( enabled=False, # Simplify testing ), )

🌍 Environment Variables

The gRPC configs package supports environment variables out of the box via configs/constants.py:

Core Network Settings

GRPC_HOST=localhost # Default gRPC host GRPC_PORT=50051 # Default gRPC port

Timeout Settings (seconds)

GRPC_RPC_CALL_TIMEOUT=5.0 # RPC call timeout GRPC_CONNECT_TIMEOUT=3.0 # Connection timeout GRPC_CHANNEL_READY_TIMEOUT=5.0 # Channel ready timeout GRPC_QUEUE_TIMEOUT=10.0 # Queue timeout GRPC_ROUTING_TIMEOUT=5.0 # Cross-process routing timeout

Keepalive Settings (milliseconds)

GRPC_KEEPALIVE_TIME_MS=30000 # Ping interval (30s) GRPC_KEEPALIVE_TIMEOUT_MS=10000 # Ping timeout (10s) GRPC_MAX_CONNECTION_IDLE_MS=7200000 # Max idle (2h)

Retry & Limits

GRPC_MAX_RETRIES=3 # Max retry attempts GRPC_MAX_MESSAGE_LENGTH=4194304 # 4MB message limit GRPC_QUEUE_SIZE=1000 # Command queue size

Circuit Breaker

GRPC_CB_THRESHOLD=5 # Error threshold GRPC_CB_TIMEOUT=60.0 # Recovery timeout

Legacy Config Override

You can still override in GRPCConfig:

import os grpc: GRPCConfig = GRPCConfig( enabled=os.getenv("GRPC_ENABLED", "true").lower() == "true", server=GRPCServerConfig( host=os.getenv("GRPC_HOST", "[::]"), port=int(os.getenv("GRPC_PORT", "50051")), enable_reflection=os.getenv("GRPC_ENABLE_REFLECTION", "true").lower() == "true", ), auth=GRPCAuthConfig( enabled=os.getenv("GRPC_AUTH_ENABLED", "false").lower() == "true", require_auth=os.getenv("GRPC_REQUIRE_AUTH", "false").lower() == "true", api_key_header=os.getenv("GRPC_API_KEY_HEADER", "x-api-key"), accept_django_secret_key=os.getenv("GRPC_ACCEPT_SECRET_KEY", "true").lower() == "true", ), )

📊 Service Discovery

Auto-Discovery Locations

Services are discovered from these locations (in order):

  1. app/grpc_services.py
  2. app/grpc_handlers.py
  3. app/services/grpc.py
  4. app/handlers/grpc.py
  5. app/api/grpc.py

Enabled Apps

grpc: GRPCConfig = GRPCConfig( auto_register_apps=True, enabled_apps=[ # Full app paths "apps.users", "apps.products", # Core Django apps (if they have gRPC services) "django.contrib.auth", # Third-party apps "mylib.grpc_app", ], )

Manual Registration

If auto-discovery doesn’t work, register manually:

# api/grpc_handlers.py def register_handlers(server): from apps.users.grpc_services import UserService from apps.users import user_pb2_grpc user_pb2_grpc.add_UserServiceServicer_to_server( UserService(), server )

Then in config:

grpc: GRPCConfig = GRPCConfig( handlers_hook="api.grpc_handlers.register_handlers", )

🚀 Command-Line Options

Override config when starting server:

# Custom host and port python manage.py rungrpc --host 0.0.0.0 --port 50052 # Verbose output python manage.py rungrpc --verbosity 3 # Combined python manage.py rungrpc \ --host 0.0.0.0 \ --port 50052 \ --verbosity 2

Streaming Configuration

For bidirectional streaming services, use BidirectionalStreamingConfig:

from django_cfg.modules.django_grpc.services.streaming.config import ( BidirectionalStreamingConfig, StreamingMode, PingStrategy, ) BotStreamingConfig = BidirectionalStreamingConfig( # Streaming mode streaming_mode=StreamingMode.ANEXT, # Recommended for long-running streams # Ping/keepalive for liveness detection ping_strategy=PingStrategy.INTERVAL, ping_interval=5.0, # Send PING every 5 seconds ping_timeout=180.0, # Disconnect if no PONG in 180 seconds # CRITICAL: Must be None! connection_timeout=None, # See warning below # Queue configuration max_queue_size=1000, # Async optimizations enable_sleep_zero=True, # Logging enable_logging=True, logger_name="grpc_streaming", # Centrifugo integration (optional) enable_centrifugo=True, centrifugo_channel_prefix="bot", centrifugo_auto_publish_messages=True, centrifugo_auto_publish_commands=True, )

Streaming Configuration Options

OptionTypeDefaultDescription
streaming_modeStreamingModeANEXTHow to read from input stream
ping_strategyPingStrategyINTERVALWhen to send ping messages
ping_intervalfloat5.0Seconds between pings
ping_timeoutfloat180.0Seconds to wait for pong before disconnect
connection_timeoutfloat | NoneNoneMust be None!
max_queue_sizeint1000Max pending commands in queue
enable_sleep_zeroboolTrueYield to event loop after messages
enable_loggingboolTrueEnable streaming debug logs
enable_centrifugoboolFalseAuto-publish to Centrifugo

Critical: Never set connection_timeout!

Setting connection_timeout causes premature StopAsyncIteration in grpcio 1.76.0+. Always use connection_timeout=None and rely on ping/keepalive for liveness detection.

See Troubleshooting for details.

Streaming Modes

ModeDescriptionUse Case
ANEXTUses await anext() with explicit controlLong-running clients, idle periods
ASYNC_FORUses async for iterationHigh-throughput short-lived streams

Ping Strategies

StrategyBehavior
DISABLEDNo pings (testing only)
INTERVALSend ping every N seconds
ON_IDLESend ping only when no messages for N seconds

Learn more: Streaming Patterns


Advanced Configuration

Custom Interceptors

Interceptor Order Matters!

Interceptors execute in the order listed. Authentication interceptors MUST come first to set context.user and context.api_key before logging interceptors use them.

Correct order:

  1. ApiKeyAuthInterceptor - Sets context.api_key and context.user
  2. RequestLoggerInterceptor - Logs request with api_key info
  3. LoggingInterceptor (dev mode)
  4. MetricsInterceptor (dev mode)
  5. Custom interceptors

Wrong order causes: API keys not tracked in logs, user info missing.

# In your config or settings GRPC_INTERCEPTORS = [ # 1. Auth FIRST (sets context.api_key and context.user) 'django_cfg.modules.django_grpc.auth.ApiKeyAuthInterceptor', # 2. Request logger (uses context.api_key from auth) 'django_cfg.modules.django_grpc.interceptors.RequestLoggerInterceptor', # 3. Your custom interceptors 'myapp.interceptors.CustomInterceptor', ]

Connection Timeouts

# Client-side (in proto definition or client config) # For long-running operations deadline = 300 # 5 minutes # Server-side (in service) context.set_deadline(time.time() + 300)

Request Size Limits

# In server options options = [ ('grpc.max_send_message_length', 50 * 1024 * 1024), # 50MB ('grpc.max_receive_message_length', 50 * 1024 * 1024), # 50MB ] server = grpc.server( futures.ThreadPoolExecutor(max_workers=10), interceptors=interceptors, options=options, )

📚 Configuration Checklist

Development ✅

  • enabled=True
  • host="127.0.0.1" (localhost)
  • enable_reflection=True (for grpcurl)
  • auth.enabled=False (easy testing)

Production ✅

  • enabled=True
  • host="[::]" (all interfaces)
  • enable_reflection=False (security)
  • auth.enabled=True (security)
  • auth.require_auth=True (strict)
  • keepalive=GRPCKeepaliveConfig.for_streaming() (streaming)
  • Environment variables for secrets
  • Health check enabled
  • Monitoring/logging enabled

DjangoGrpcModuleConfig — Top-Level Fields

The actual top-level configuration class is DjangoGrpcModuleConfig (defined in __cfg__.py). It is the single source of truth that composes all sub-configs.

from django_cfg.modules.django_grpc.__cfg__ import DjangoGrpcModuleConfig from django_cfg.modules.django_grpc.config.server import GrpcServerConfig from django_cfg.modules.django_grpc.config.auth import GrpcAuthConfig from django_cfg.modules.django_grpc.config.resilience import ResilienceConfig from django_cfg.modules.django_grpc.config.pool import GrpcPoolConfig from django_cfg.modules.django_grpc.config.metrics import MetricsConfig from django_cfg.modules.django_grpc.config.observability import ObservabilityConfig grpc_module = DjangoGrpcModuleConfig( enabled=True, public_url="grpc.example.com:443", server=GrpcServerConfig(host="[::]", port=50051), auth=GrpcAuthConfig(require_auth=True), resilience=ResilienceConfig(), pool=GrpcPoolConfig(), metrics=MetricsConfig(), observability=ObservabilityConfig(), )
FieldTypeDefaultDescription
enabledboolTrueEnable the gRPC module
serverGrpcServerConfigdefaultsServer bind and limits
public_urlstr | NoneNonePublic gRPC URL for external clients
internal_urlstr | NoneNoneInternal container-to-container URL
handlers_hookstr | list[str]""Import path(s) to a grpc_handlers function for manual service registration
enabled_appslist[str][]Django apps to expose via gRPC (auto-discovery)
package_prefixstr"api"Proto package prefix
authGrpcAuthConfigdefaultsAuthentication settings
resilienceResilienceConfigdefaultsRetry and circuit breaker
poolGrpcPoolConfigdefaultsConnection pool
persistenceGrpcPersistenceConfigdefaultsD1/database persistence
observabilityObservabilityConfigdefaultsCentrifugo publishing, Telegram alerts, OpenTelemetry
metricsMetricsConfigdefaultsIn-memory metrics and Prometheus export

GrpcServerConfig

FieldTypeDefaultDescription
hoststr"[::]"IPv4/IPv6 listen address
portint50051Listen port (1–65535)
max_workersint10Thread pool workers (1–256)
max_send_message_lengthint4194304Max outbound message bytes (4 MB)
max_receive_message_lengthint4194304Max inbound message bytes (4 MB)
enable_reflectionboolFalseEnable server reflection (grpcurl). Disable in production — exposes the full schema publicly.
enable_health_checkboolTrueEnable grpc.health.v1.Health service
shutdown_grace_secondsfloat5.0Graceful shutdown wait time (0–60 s)
keepaliveGrpcKeepaliveConfigdefaultsHTTP/2 keepalive and connection lifetime
tlsTLSConfig | NoneNoneServer TLS. When None, binds an insecure port.
reflection_require_authboolFalseGate reflection behind JWT auth
reflection_admin_keystr | NoneNoneBypass reflection auth via x-admin-key metadata (dev tooling)
enable_h3boolFalseHTTP/3 (QUIC) frontend via Hypercorn. Requires pip install django-cfg[grpc-h3].
h3_hoststr"0.0.0.0"HTTP/3 listen address (only when enable_h3=True)
h3_portint50052HTTP/3 listen port (only when enable_h3=True)

GrpcKeepaliveConfig

Controls HTTP/2 PING frames and connection lifetime on the server side.

FieldTypeDefaultDescription
time_msint30000Keepalive ping interval (ms)
timeout_msint10000Time to wait for a PING ACK before closing (ms)
permit_without_callsboolTrueAllow pings even with no active RPCs
max_pings_without_dataint0Max pings without data frames. 0 = unlimited
http2_min_ping_interval_msint5000Minimum time between HTTP/2 pings (ms)
max_connection_idle_msint600000Close idle connections after N ms. 0 = disabled (10 min default)
max_connection_age_msint3600000Maximum connection lifetime (ms). 0 = disabled (1 h default)
max_connection_age_grace_msint60000Grace period after max_connection_age_ms before forced close (1 min default)

GrpcPoolConfig

Unified connection pool (single source of truth, replacing older per-file PoolConfig classes).

from django_cfg.modules.django_grpc.config.pool import GrpcPoolConfig pool = GrpcPoolConfig( enabled=True, max_size=20, idle_timeout=120.0, min_idle=2, max_age=3600.0, cleanup_interval=60.0, health_check_interval=30.0, channel_ready_timeout=5.0, )
FieldTypeDefaultDescription
enabledboolTrueEnable connection pooling
max_sizeint20Maximum channels in pool (1–200)
idle_timeoutfloat120.0Seconds before an idle channel is closed (10–3600)
min_idleint2Minimum idle channels to maintain per address (0–20)
max_agefloat3600.0Maximum channel lifetime in seconds (60–86400)
cleanup_intervalfloat60.0Seconds between pool cleanup cycles (10–600)
health_check_intervalfloat30.0Seconds between idle channel health checks (5–600)
channel_ready_timeoutfloat5.0Seconds to wait for a channel to become ready (1–60)

See Connection Pooling for detailed usage.


MetricsConfig

Controls in-memory request metrics collection and optional Prometheus export.

from django_cfg.modules.django_grpc.config.metrics import MetricsConfig metrics = MetricsConfig( enabled=True, response_time_ttl=3600.0, prometheus_enabled=False, )
FieldTypeDefaultDescription
enabledboolTrueEnable in-memory metrics collection
response_time_ttlfloat3600.0TTL in seconds for in-memory response time history (60–86400). Prevents unbounded growth.
prometheus_enabledboolFalseExport metrics via prometheus_client (requires the prometheus_client package). When enabled, exposes standard gRPC Prometheus counters and histograms.

When prometheus_enabled=True and prometheus_client is installed, the following metrics are exported with labels {grpc_service, grpc_method, grpc_type}:

MetricTypeDescription
grpc_server_started_totalCounterTotal started RPCs
grpc_server_handled_totalCounterTotal finished RPCs (adds grpc_code label)
grpc_server_handling_secondsHistogramRPC latency
grpc_server_msg_received_totalCounterStreaming messages received
grpc_server_msg_sent_totalCounterStreaming messages sent

ObservabilityConfig

Controls Centrifugo real-time publishing, Telegram error notifications, and OpenTelemetry tracing.

from django_cfg.modules.django_grpc.config.observability import ObservabilityConfig observability = ObservabilityConfig( otel_enabled=False, )
FieldTypeDefaultDescription
centrifugoCentrifugoPublishConfigdefaultsCentrifugo event publishing settings
telegramTelegramNotifyConfigdefaultsTelegram notification settings
otel_enabledboolFalsePrepend OpenTelemetryServerInterceptor (requires opentelemetry-instrumentation-grpc). Interceptor order: OTel → ErrorHandling → Auth → Observability.

CentrifugoPublishConfig

FieldTypeDefaultDescription
enabledboolTrueEnable Centrifugo event publishing
publish_startboolFalsePublish rpc_start events (high volume — disabled by default)
publish_endboolTruePublish rpc_end events
publish_errorsboolTruePublish error events
publish_stream_messagesboolFalsePublish per-message stream events (very high volume — disabled by default)
channel_templatestr"grpc:{service}:{method}:meta"Centrifugo channel pattern for method events
error_channel_templatestr"grpc:{service}:{method}:errors"Centrifugo channel pattern for error events
max_retriesint3Publish retry attempts on transient failure (0–10)
max_concurrent_publishesint100Semaphore cap on concurrent fire-and-forget publish tasks (1–10000)

TelegramNotifyConfig

FieldTypeDefaultDescription
enabledboolFalseSend gRPC error/event notifications to Telegram
exclude_methodslist[str]Health/reflection pathsMethod paths excluded from notifications

Default excluded methods: /grpc.health.v1.Health/Check, /grpc.health.v1.Health/Watch, /grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo.



Configuration Tip: Start with defaults, measure performance, then tune based on actual traffic patterns. For streaming, always use connection_timeout=None.

Last updated on