# Path: sygnal/http.py
# class PushGatewayApiServer(object):
#     def __init__(self, sygnal: "Sygnal"):
#         """
#         Initialises the /_matrix/push/* (Push Gateway API) server.
#         Args:
#             sygnal (Sygnal): the Sygnal object
#         """
#         root = Resource()
#         matrix = Resource()
#         push = Resource()
#         v1 = Resource()
# 
#         # Note that using plain strings here will lead to silent failure
#         root.putChild(b"_matrix", matrix)
#         matrix.putChild(b"push", push)
#         push.putChild(b"v1", v1)
#         v1.putChild(b"notify", V1NotifyHandler(sygnal))
# 
#         # add health
#         root.putChild(b"health", HealthHandler())
# 
#         use_x_forwarded_for = sygnal.config["log"]["access"]["x_forwarded_for"]
# 
#         log_formatter = (
#             proxiedLogFormatter if use_x_forwarded_for else combinedLogFormatter
#         )
# 
#         self.site = SygnalLoggedSite(
#             root,
#             reactor=sygnal.reactor,
#             log_formatter=log_formatter,
#             requestFactory=SizeLimitingRequest,
#         )
# 
# Path: sygnal/notifications.py
# class Pushkin(abc.ABC):
#     def __init__(self, name: str, sygnal: "Sygnal", config: Dict[str, Any]):
#         self.name = name
#         self.appid_pattern = glob_to_regex(name, ignore_case=False)
#         self.cfg = config
#         self.sygnal = sygnal
# 
#     @overload
#     def get_config(self, key: str, type_: Type[T], default: T) -> T:
#         ...
# 
#     @overload
#     def get_config(self, key: str, type_: Type[T], default: None = None) -> Optional[T]:
#         ...
# 
#     def get_config(
#         self, key: str, type_: Type[T], default: Optional[T] = None
#     ) -> Optional[T]:
#         if key not in self.cfg:
#             return default
#         if not isinstance(self.cfg[key], type_):
#             raise PushkinSetupException(
#                 f"{key} is of incorrect type, please check that the entry for {key} is "
#                 f"formatted correctly in the config file. "
#             )
#         return self.cfg[key]
# 
#     def handles_appid(self, appid: str) -> bool:
#         """Checks whether the pushkin is responsible for the given app ID"""
#         return self.name == appid or self.appid_pattern.match(appid) is not None
# 
#     @abc.abstractmethod
#     async def dispatch_notification(
#         self, n: Notification, device: Device, context: "NotificationContext"
#     ) -> List[str]:
#         """
#         Args:
#             n: The notification to dispatch via this pushkin
#             device: The device to dispatch the notification for.
#             context: the request context
# 
#         Returns:
#             A list of rejected pushkeys, to be reported back to the homeserver
#         """
#         ...
# 
#     @classmethod
#     async def create(cls, name: str, sygnal: "Sygnal", config: Dict[str, Any]):
#         """
#         Override this if your pushkin needs to call async code in order to
#         be constructed. Otherwise, it defaults to just invoking the Python-standard
#         __init__ constructor.
# 
#         Returns:
#             an instance of this Pushkin
#         """
#         return cls(name, sygnal, config)


import copy
import importlib
import logging
import logging.config
import os
import sys
import opentracing
import prometheus_client
import yaml
            import sentry_sdk
                    import jaeger_client
from typing import Any, Dict, Set, cast
from opentracing import Tracer
from opentracing.scope_managers.asyncio import AsyncioScopeManager
from twisted.internet import asyncioreactor, defer
from twisted.internet.defer import ensureDeferred
from twisted.internet.interfaces import (
    IReactorCore,
    IReactorFDSet,
    IReactorPluggableNameResolver,
    IReactorTCP,
    IReactorTime,
)
from twisted.python import log as twisted_log
from twisted.python.failure import Failure
from zope.interface import Interface
from sygnal.http import PushGatewayApiServer
from sygnal.notifications import Pushkin

            prometheus_client.start_http_server(port=prom_port, addr=prom_addr or "")

        tracecfg = config["metrics"]["opentracing"]
        if tracecfg["enabled"] is True:
            if tracecfg["implementation"] == "jaeger":
                try:

                    jaeger_cfg = jaeger_client.Config(
                        config=tracecfg["jaeger"],
                        service_name=tracecfg["service_name"],
                        scope_manager=AsyncioScopeManager(),
                    )

                    jaeger_tracer = jaeger_cfg.initialize_tracer()
                    assert jaeger_tracer is not None
                    self.tracer = jaeger_tracer

                    logger.info("Enabled OpenTracing support with Jaeger")
                except ModuleNotFoundError:
                    logger.critical(
                        "You have asked for OpenTracing with Jaeger but do not have"
                        " the Python package 'jaeger_client' installed."
                    )
                    raise
            else:
                raise RuntimeError(
                    "Unknown OpenTracing implementation: %s.", tracecfg["impl"]
                )


# Path: sygnal/http.py
# class PushGatewayApiServer(object):
#     def __init__(self, sygnal: "Sygnal"):
#         """
#         Initialises the /_matrix/push/* (Push Gateway API) server.
#         Args:
#             sygnal (Sygnal): the Sygnal object
#         """
#         root = Resource()
#         matrix = Resource()
#         push = Resource()
#         v1 = Resource()
# 
#         # Note that using plain strings here will lead to silent failure
#         root.putChild(b"_matrix", matrix)
#         matrix.putChild(b"push", push)
#         push.putChild(b"v1", v1)
#         v1.putChild(b"notify", V1NotifyHandler(sygnal))
# 
#         # add health
#         root.putChild(b"health", HealthHandler())
# 
#         use_x_forwarded_for = sygnal.config["log"]["access"]["x_forwarded_for"]
# 
#         log_formatter = (
#             proxiedLogFormatter if use_x_forwarded_for else combinedLogFormatter
#         )
# 
#         self.site = SygnalLoggedSite(
#             root,
#             reactor=sygnal.reactor,
#             log_formatter=log_formatter,
#             requestFactory=SizeLimitingRequest,
#         )
# 
# Path: sygnal/notifications.py
# class Pushkin(abc.ABC):
#     def __init__(self, name: str, sygnal: "Sygnal", config: Dict[str, Any]):
#         self.name = name
#         self.appid_pattern = glob_to_regex(name, ignore_case=False)
#         self.cfg = config
#         self.sygnal = sygnal
# 
#     @overload
#     def get_config(self, key: str, type_: Type[T], default: T) -> T:
#         ...
# 
#     @overload
#     def get_config(self, key: str, type_: Type[T], default: None = None) -> Optional[T]:
#         ...
# 
#     def get_config(
#         self, key: str, type_: Type[T], default: Optional[T] = None
#     ) -> Optional[T]:
#         if key not in self.cfg:
#             return default
#         if not isinstance(self.cfg[key], type_):
#             raise PushkinSetupException(
#                 f"{key} is of incorrect type, please check that the entry for {key} is "
#                 f"formatted correctly in the config file. "
#             )
#         return self.cfg[key]
# 
#     def handles_appid(self, appid: str) -> bool:
#         """Checks whether the pushkin is responsible for the given app ID"""
#         return self.name == appid or self.appid_pattern.match(appid) is not None
# 
#     @abc.abstractmethod
#     async def dispatch_notification(
#         self, n: Notification, device: Device, context: "NotificationContext"
#     ) -> List[str]:
#         """
#         Args:
#             n: The notification to dispatch via this pushkin
#             device: The device to dispatch the notification for.
#             context: the request context
# 
#         Returns:
#             A list of rejected pushkeys, to be reported back to the homeserver
#         """
#         ...
# 
#     @classmethod
#     async def create(cls, name: str, sygnal: "Sygnal", config: Dict[str, Any]):
#         """
#         Override this if your pushkin needs to call async code in order to
#         be constructed. Otherwise, it defaults to just invoking the Python-standard
#         __init__ constructor.
# 
#         Returns:
#             an instance of this Pushkin
#         """
#         return cls(name, sygnal, config)


# Path: sygnal/sygnal.py
import copy
import importlib
import logging
import logging.config
import os
import sys
import opentracing
import prometheus_client
import yaml
            import sentry_sdk
                    import jaeger_client
from typing import Any, Dict, Set, cast
from opentracing import Tracer
from opentracing.scope_managers.asyncio import AsyncioScopeManager
from twisted.internet import asyncioreactor, defer
from twisted.internet.defer import ensureDeferred
from twisted.internet.interfaces import (
    IReactorCore,
    IReactorFDSet,
    IReactorPluggableNameResolver,
    IReactorTCP,
    IReactorTime,
)
from twisted.python import log as twisted_log
from twisted.python.failure import Failure
from zope.interface import Interface
from sygnal.http import PushGatewayApiServer
from sygnal.notifications import Pushkin


            prometheus_client.start_http_server(port=prom_port, addr=prom_addr or "")

        tracecfg = config["metrics"]["opentracing"]
        if tracecfg["enabled"] is True:
            if tracecfg["implementation"] == "jaeger":
                try:

                    jaeger_cfg = jaeger_client.Config(
                        config=tracecfg["jaeger"],
                        service_name=tracecfg["service_name"],
                        scope_manager=AsyncioScopeManager(),
                    )

                    jaeger_tracer = jaeger_cfg.initialize_tracer()
                    assert jaeger_tracer is not None
                    self.tracer = jaeger_tracer

                    logger.info("Enabled OpenTracing support with Jaeger")
                except ModuleNotFoundError:
                    logger.critical(
                        "You have asked for OpenTracing with Jaeger but do not have"
                        " the Python package 'jaeger_client' installed."
                    )
                    raise
            else:
                raise RuntimeError(
                    "Unknown OpenTracing implementation: %s.", tracecfg["impl"]
                )


    async def _make_pushkin(self, app_name: str, app_config: Dict[str, Any]) -> Pushkin: