def __init__(
     self,
     app,
     excluded_urls=None,
     default_span_details=None,
     server_request_hook: _ServerRequestHookT = None,
     client_request_hook: _ClientRequestHookT = None,
     client_response_hook: _ClientResponseHookT = None,
     tracer_provider=None,
     meter_provider=None,
 ):
     self.app = guarantee_single_callable(app)
     self.tracer = trace.get_tracer(__name__, __version__, tracer_provider)
     self.meter = get_meter(__name__, __version__, meter_provider)
     self.duration_histogram = self.meter.create_histogram(
         name="http.server.duration",
         unit="ms",
         description="measures the duration of the inbound HTTP request",
     )
     self.active_requests_counter = self.meter.create_up_down_counter(
         name="http.server.active_requests",
         unit="requests",
         description="measures the number of concurrent HTTP requests that are currently in-flight",
     )
     self.excluded_urls = excluded_urls
     self.default_span_details = (
         default_span_details or get_default_span_details
     )
     self.server_request_hook = server_request_hook
     self.client_request_hook = client_request_hook
     self.client_response_hook = client_response_hook
 def __init__(self, app, excluded_urls=None, span_details_callback=None):
     self.app = guarantee_single_callable(app)
     self.tracer = trace.get_tracer(__name__, __version__)
     self.span_details_callback = (
         span_details_callback or get_default_span_details
     )
     self.excluded_urls = excluded_urls
示例#3
0
 async def __call__(self, scope, receive, send):
     if scope["type"] in self.application_mapping:
         application = guarantee_single_callable(
             self.application_mapping[scope["type"]])
         return await application(scope, receive, send)
     else:
         raise ValueError("No application configured for scope type %r" %
                          scope["type"])
示例#4
0
    def prepare_application(self, application: Any) -> Any:
        # Convert an WSGI-App to an ASGI-App if needed.
        signature = inspect.signature(application, follow_wrapped=True)
        if len(signature.parameters) == 2:
            application = WsgiContainer(application)

        # Convert an ASGI2-App to ASGI3
        from asgiref.compatibility import guarantee_single_callable
        application = guarantee_single_callable(application)

        return application
示例#5
0
 async def __call__(self, scope, receive, send):
     if "channel" not in scope:
         raise ValueError(
             "ChannelNameRouter got a scope without a 'channel' key. " +
             "Did you make sure it's only being used for 'channel' type messages?"
         )
     if scope["channel"] in self.application_mapping:
         application = guarantee_single_callable(
             self.application_mapping[scope["channel"]])
         return await application(scope, receive, send)
     else:
         raise ValueError("No application configured for channel name %r" %
                          scope["channel"])
 def __init__(
     self,
     app,
     excluded_urls=None,
     default_span_details=None,
     server_request_hook: _ServerRequestHookT = None,
     client_request_hook: _ClientRequestHookT = None,
     client_response_hook: _ClientResponseHookT = None,
     tracer_provider=None,
 ):
     self.app = guarantee_single_callable(app)
     self.tracer = trace.get_tracer(__name__, __version__, tracer_provider)
     self.excluded_urls = excluded_urls
     self.default_span_details = (default_span_details
                                  or get_default_span_details)
     self.server_request_hook = server_request_hook
     self.client_request_hook = client_request_hook
     self.client_response_hook = client_response_hook
示例#7
0
 async def __call__(self, scope, receive, send):
     # Get the path
     path = scope.get("path_remaining", scope.get("path", None))
     if path is None:
         raise ValueError(
             "No 'path' key in connection scope, cannot route URLs")
     # Remove leading / to match Django's handling
     path = path.lstrip("/")
     # Run through the routes we have until one matches
     for route in self.routes:
         try:
             match = route_pattern_match(route, path)
             if match:
                 new_path, args, kwargs = match
                 # Add args or kwargs into the scope
                 outer = scope.get("url_route", {})
                 application = guarantee_single_callable(route.callback)
                 return await application(
                     dict(
                         scope,
                         path_remaining=new_path,
                         url_route={
                             "args": outer.get("args", ()) + args,
                             "kwargs": {
                                 **outer.get("kwargs", {}),
                                 **kwargs
                             },
                         },
                     ),
                     receive,
                     send,
                 )
         except Resolver404:
             pass
     else:
         if "path_remaining" in scope:
             raise Resolver404("No route found for path %r." % path)
         # We are the outermost URLRouter
         raise ValueError("No route found for path %r." % path)
示例#8
0
 def __init__(self, app):
     self.app = guarantee_single_callable(app)
示例#9
0
    def run(self, args):
        """
        Pass in raw argument list and it will decode them
        and run the server.
        """
        # Decode args
        args = self.parser.parse_args(args)
        # Set up logging
        logging.basicConfig(
            level={
                0: logging.WARN,
                1: logging.INFO,
                2: logging.DEBUG,
                3: logging.DEBUG,  # Also turns on asyncio debug
            }[args.verbosity],
            format="%(asctime)-15s %(levelname)-8s %(message)s",
        )
        # If verbosity is 1 or greater, or they told us explicitly, set up access log
        access_log_stream = None
        if args.access_log:
            if args.access_log == "-":
                access_log_stream = sys.stdout
            else:
                access_log_stream = open(args.access_log, "a", 1)
        elif args.verbosity >= 1:
            access_log_stream = sys.stdout

        # Import application
        sys.path.insert(0, ".")
        application = import_by_path(args.application)
        application = guarantee_single_callable(application)

        # Set up port/host bindings
        if not any([
                args.host,
                args.port is not None,
                args.unix_socket,
                args.file_descriptor is not None,
                args.socket_strings,
        ]):
            # no advanced binding options passed, patch in defaults
            args.host = DEFAULT_HOST
            args.port = DEFAULT_PORT
        elif args.host and args.port is None:
            args.port = DEFAULT_PORT
        elif args.port is not None and not args.host:
            args.host = DEFAULT_HOST
        # Build endpoint description strings from (optional) cli arguments
        endpoints = build_endpoint_description_strings(
            host=args.host,
            port=args.port,
            unix_socket=args.unix_socket,
            file_descriptor=args.file_descriptor,
        )
        endpoints = sorted(args.socket_strings + endpoints)
        # Start the server
        logger.info("Starting server at {}".format(", ".join(endpoints)))
        self.server = self.server_class(
            application=application,
            endpoints=endpoints,
            http_timeout=args.http_timeout,
            ping_interval=args.ping_interval,
            ping_timeout=args.ping_timeout,
            websocket_timeout=args.websocket_timeout,
            websocket_connect_timeout=args.websocket_connect_timeout,
            websocket_handshake_timeout=args.websocket_connect_timeout,
            application_close_timeout=args.application_close_timeout,
            action_logger=AccessLogGenerator(access_log_stream)
            if access_log_stream else None,
            ws_protocols=args.ws_protocols,
            root_path=args.root_path,
            verbosity=args.verbosity,
            proxy_forwarded_address_header=self._get_forwarded_host(args=args),
            proxy_forwarded_port_header=self._get_forwarded_port(args=args),
            proxy_forwarded_proto_header="X-Forwarded-Proto"
            if args.proxy_headers else None,
            server_name=args.server_name,
        )
        self.server.run()
示例#10
0
        # Check if header has multiple values, and use the first one
        return client_ip.split(", ")[0]

    def log(self, scope: Scope, content_length: int, runtime: float, **kwargs):
        """Outpot access logs in a structured format"""
        host = self._get_ip(scope)
        query_string = ""
        if scope.get("query_string", b"") != b"":
            query_string = f"?{scope.get('query_string').decode()}"
        LOGGER.info(
            f"{scope.get('path', '')}{query_string}",
            host=host,
            method=scope.get("method", ""),
            scheme=scope.get("scheme", ""),
            status=self.status_code,
            size=content_length / 1000 if content_length > 0 else 0,
            runtime=runtime,
            **kwargs,
        )


application = ASGILogger(
    guarantee_single_callable(
        SentryAsgiMiddleware(
            ProtocolTypeRouter({
                "http":
                get_asgi_application(),
                "websocket":
                URLRouter(websocket.websocket_urlpatterns),
            }))))
示例#11
0
 def __init__(self, app, name_callback=None):
     self.app = guarantee_single_callable(app)
     self.tracer = trace.get_tracer(__name__, __version__)
     self.name_callback = name_callback or get_default_span_name