@@ -258,6 +258,50 @@ def setup_metric_interceptor(config: BaseConfig, interceptors: list) -> None:
258258 logging .exception ("Failed to initialize Metric Interceptor" )
259259
260260
261+ class GrpcAPIUtils :
262+ """grpc api utilities."""
263+
264+ @staticmethod
265+ def setup_trace_interceptor (config : BaseConfig , interceptors : list ) -> None :
266+ """Configures trace interceptor for gRPC server if tracing is enabled.
267+
268+ Args:
269+ config (BaseConfig): The configuration object containing tracing settings.
270+ interceptors (List): List of gRPC interceptors to add the trace interceptor to.
271+ """
272+ if not config .ELASTIC_APM .IS_ENABLED and not config .SENTRY .IS_ENABLED :
273+ return
274+
275+ try :
276+ from archipy .helpers .interceptors .grpc .trace .server_interceptor import GrpcServerTraceInterceptor
277+
278+ interceptors .append (GrpcServerTraceInterceptor ())
279+ except Exception :
280+ logging .exception ("Failed to initialize Trace Interceptor" )
281+
282+ @staticmethod
283+ def setup_metric_interceptor (config : BaseConfig , interceptors : list ) -> None :
284+ """Configures metric interceptor for gRPC server if Prometheus is enabled.
285+
286+ Args:
287+ config (BaseConfig): The configuration object containing Prometheus settings.
288+ interceptors (List): List of gRPC interceptors to add the metric interceptor to.
289+ """
290+ if not config .PROMETHEUS .IS_ENABLED :
291+ return
292+
293+ try :
294+ from prometheus_client import start_http_server
295+
296+ from archipy .helpers .interceptors .grpc .metric .server_interceptor import GrpcServerMetricInterceptor
297+
298+ start_http_server (config .PROMETHEUS .SERVER_PORT )
299+ interceptors .append (GrpcServerMetricInterceptor ())
300+
301+ except Exception :
302+ logging .exception ("Failed to initialize Metric Interceptor" )
303+
304+
261305class AppUtils :
262306 """Utility class for creating and configuring FastAPI applications."""
263307
@@ -313,15 +357,15 @@ def create_fastapi_app(
313357 def create_async_grpc_app (
314358 cls ,
315359 config : BaseConfig ,
316- interceptors : set [Any ] | None = None ,
360+ customized_interceptors : set [Any ] | None = None ,
317361 compression : grpc .Compression | None = None ,
318362 ) -> server :
319363 """Create and configure an async gRPC application."""
320364 from archipy .helpers .interceptors .grpc .exception import AsyncGrpcServerExceptionInterceptor
321365
322366 async_interceptors = [AsyncGrpcServerExceptionInterceptor ()]
323- if interceptors :
324- async_interceptors .extend (interceptors )
367+ if customized_interceptors :
368+ async_interceptors .extend (customized_interceptors )
325369 AsyncGrpcAPIUtils .setup_trace_interceptor (config , async_interceptors )
326370 AsyncGrpcAPIUtils .setup_metric_interceptor (config , async_interceptors )
327371
@@ -334,3 +378,29 @@ def create_async_grpc_app(
334378 )
335379
336380 return app
381+
382+ @classmethod
383+ def create_grpc_app (
384+ cls ,
385+ config : BaseConfig ,
386+ customized_interceptors : set [Any ] | None = None ,
387+ compression : grpc .Compression | None = None ,
388+ ) -> grpc .Server :
389+ """Create and configure an async gRPC application."""
390+ from archipy .helpers .interceptors .grpc .exception import GrpcServerExceptionInterceptor
391+
392+ interceptors = [GrpcServerExceptionInterceptor ()]
393+ if customized_interceptors :
394+ interceptors .extend (customized_interceptors )
395+ GrpcAPIUtils .setup_trace_interceptor (config , interceptors )
396+ GrpcAPIUtils .setup_metric_interceptor (config , interceptors )
397+
398+ app = grpc .server (
399+ futures .ThreadPoolExecutor (max_workers = config .GRPC .THREAD_WORKER_COUNT ),
400+ interceptors = interceptors , # type: ignore
401+ compression = compression ,
402+ options = config .GRPC .SERVER_OPTIONS_CONFIG_LIST ,
403+ maximum_concurrent_rpcs = config .GRPC .MAX_CONCURRENT_RPCS ,
404+ )
405+
406+ return app
0 commit comments