# Path: rep0st/framework/decorator.py
# class DecoratorProcessor(ABC):
# 
#   @abstractmethod
#   def process(self, bindings: List[Any]) -> None:
#     pass
# 
#   def methods_by_decorated_name(
#       self, bindings: List[Any],
#       search_name: str) -> Iterator[Tuple[Type, T, Callable[[Any], Any]]]:
#     for binding in bindings:
#       interface = binding
#       for name, fun in inspect.getmembers(interface):
#         data = getattr(fun, '__' + search_name + '__', None)
#         if data is not None:
#           yield (interface, data, fun)
# 
#   @staticmethod
#   def wrap_function(instance: Any, fun: Callable,
#                     injector: Injector) -> Callable:
#     fun = types.MethodType(fun, instance)
# 
#     @functools.wraps(fun)
#     def wrapper(*args: Any, **kwargs: Any) -> Any:
#       return injector.call_with_injection(
#           callable=fun, args=args, kwargs=kwargs)
# 
#     return wrapper  # type: ignore
# 
# Path: rep0st/framework/execute.py
# def execute(order: float = 0) -> Any:
# 
#   def decorator(function: Any):
#     function.__execute__ = _ExecuteConfiguration(order)
#     return function
# 
#   return decorator
# 
# Path: rep0st/framework/signal_handler.py
# def on_shutdown() -> Any:
# 
#   def decorator(function: Any):
#     function.__on_shutdown__ = _OnShutdownConfiguration()
#     return function
# 
#   return decorator


import logging
import random
import threading
import time
from abc import ABC
from threading import Thread
from typing import Any, Callable, Collection, List, NamedTuple, NewType, Union
from absl import flags
from cheroot.wsgi import Server as WSGIServer
from injector import Binder, Injector, Module, inject, multiprovider, singleton
from prometheus_client.metrics import Counter, Gauge
from werkzeug import Request
from werkzeug.exceptions import HTTPException, InternalServerError
from werkzeug.middleware.dispatcher import DispatcherMiddleware
from werkzeug.routing import Map, Rule
from rep0st.framework.decorator import DecoratorProcessor
from rep0st.framework.execute import execute
from rep0st.framework.signal_handler import on_shutdown
  def _handler(self, environ, start_response):
    adapter = self.url_map.bind_to_environ(environ)
    try:
      rule, values = adapter.match(return_rule=True)
    except HTTPException as e:
      return e.get_response(environ)(environ, start_response)

    def custom_start_response(status_, response_headers_, exc_info_=None):
      framework_webserver_endpoint_requests_z.labels(
          rule=rule.rule,
          method=environ['REQUEST_METHOD'],
          status=_get_status_code(status_)).inc()
      return start_response(status_, response_headers_, exc_info_)

    try:
      return rule.endpoint(environ, custom_start_response, **values)
    except HTTPException as e:
      return e.get_response(environ)(environ, custom_start_response)
    except Exception as e:
      log.exception('Unknown error occurred processing request')
      return InternalServerError(
          description='Unknown error occurred',
          original_exception=e).get_response(environ)(environ,
                                                      custom_start_response)

  def _server_thread(self):
    log.info(f'Starting webserver on {self.bind_hostname}:{self.bind_port}')
    app = self._handler
    app = DispatcherMiddleware(app, self.mount_map)
    app = WSGILogger(app)

# Path: rep0st/framework/decorator.py
# class DecoratorProcessor(ABC):
# 
#   @abstractmethod
#   def process(self, bindings: List[Any]) -> None:
#     pass
# 
#   def methods_by_decorated_name(
#       self, bindings: List[Any],
#       search_name: str) -> Iterator[Tuple[Type, T, Callable[[Any], Any]]]:
#     for binding in bindings:
#       interface = binding
#       for name, fun in inspect.getmembers(interface):
#         data = getattr(fun, '__' + search_name + '__', None)
#         if data is not None:
#           yield (interface, data, fun)
# 
#   @staticmethod
#   def wrap_function(instance: Any, fun: Callable,
#                     injector: Injector) -> Callable:
#     fun = types.MethodType(fun, instance)
# 
#     @functools.wraps(fun)
#     def wrapper(*args: Any, **kwargs: Any) -> Any:
#       return injector.call_with_injection(
#           callable=fun, args=args, kwargs=kwargs)
# 
#     return wrapper  # type: ignore
# 
# Path: rep0st/framework/execute.py
# def execute(order: float = 0) -> Any:
# 
#   def decorator(function: Any):
#     function.__execute__ = _ExecuteConfiguration(order)
#     return function
# 
#   return decorator
# 
# Path: rep0st/framework/signal_handler.py
# def on_shutdown() -> Any:
# 
#   def decorator(function: Any):
#     function.__on_shutdown__ = _OnShutdownConfiguration()
#     return function
# 
#   return decorator


# Path: rep0st/framework/web.py
import logging
import random
import threading
import time
from abc import ABC
from threading import Thread
from typing import Any, Callable, Collection, List, NamedTuple, NewType, Union
from absl import flags
from cheroot.wsgi import Server as WSGIServer
from injector import Binder, Injector, Module, inject, multiprovider, singleton
from prometheus_client.metrics import Counter, Gauge
from werkzeug import Request
from werkzeug.exceptions import HTTPException, InternalServerError
from werkzeug.middleware.dispatcher import DispatcherMiddleware
from werkzeug.routing import Map, Rule
from rep0st.framework.decorator import DecoratorProcessor
from rep0st.framework.execute import execute
from rep0st.framework.signal_handler import on_shutdown

  def _handler(self, environ, start_response):
    adapter = self.url_map.bind_to_environ(environ)
    try:
      rule, values = adapter.match(return_rule=True)
    except HTTPException as e:
      return e.get_response(environ)(environ, start_response)

    def custom_start_response(status_, response_headers_, exc_info_=None):
      framework_webserver_endpoint_requests_z.labels(
          rule=rule.rule,
          method=environ['REQUEST_METHOD'],
          status=_get_status_code(status_)).inc()
      return start_response(status_, response_headers_, exc_info_)

    try:
      return rule.endpoint(environ, custom_start_response, **values)
    except HTTPException as e:
      return e.get_response(environ)(environ, custom_start_response)
    except Exception as e:
      log.exception('Unknown error occurred processing request')
      return InternalServerError(
          description='Unknown error occurred',
          original_exception=e).get_response(environ)(environ,
                                                      custom_start_response)

  def _server_thread(self):
    log.info(f'Starting webserver on {self.bind_hostname}:{self.bind_port}')
    app = self._handler
    app = DispatcherMiddleware(app, self.mount_map)
    app = WSGILogger(app)

    self.server = WSGIServer((self.bind_hostname, self.bind_port), app)