# 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
                     'Port to which to bind the HTTP server to.')

_WebserverBindHostnameKey = NewType('_WebserverBindHostnameKey', str)
_WebserverBindPortKey = NewType('_WebserverBindPortKey', str)

log = logging.getLogger(__name__)
request_logger = logging.getLogger(__name__ + '.request')

framework_webserver_requests_z = Counter(
    'framework_webserver_requests',
    'Number of requests handled by the web server with the given status',
    ['status'])
framework_webserver_requests_z.labels(status=200)
framework_webserver_requests_z.labels(status=404)
framework_webserver_requests_z.labels(status=500)
framework_webserver_endpoint_requests_z = Counter(
    'framework_webserver_endpoint_requests',
    'Number of requests per rule and status', ['rule', 'method', 'status'])


def _get_status_code(status: str):
  if not status:
    return -1
  parts = status.split(' ')
  if len(parts) < 1:
    return -1
  status = parts[0]
  try:
    status = int(status)
  except ValueError:

# 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

                     'Port to which to bind the HTTP server to.')

_WebserverBindHostnameKey = NewType('_WebserverBindHostnameKey', str)
_WebserverBindPortKey = NewType('_WebserverBindPortKey', str)

log = logging.getLogger(__name__)
request_logger = logging.getLogger(__name__ + '.request')

framework_webserver_requests_z = Counter(
    'framework_webserver_requests',
    'Number of requests handled by the web server with the given status',
    ['status'])
framework_webserver_requests_z.labels(status=200)
framework_webserver_requests_z.labels(status=404)
framework_webserver_requests_z.labels(status=500)
framework_webserver_endpoint_requests_z = Counter(
    'framework_webserver_endpoint_requests',
    'Number of requests per rule and status', ['rule', 'method', 'status'])


def _get_status_code(status: str):
  if not status:
    return -1
  parts = status.split(' ')
  if len(parts) < 1:
    return -1
  status = parts[0]
  try:
    status = int(status)
  except ValueError:

    return -1