# Path: autopush/base.py
# class BaseHandler(cyclone.web.RequestHandler):
#     """Base cyclone RequestHandler for autopush"""
# 
#     log = Logger()
# 
#     def initialize(self):
#         """Initialize info from the client"""
#         self._client_info = self._init_info()
# 
#     @property
#     def conf(self):
#         # type: () -> AutopushConfig
#         return self.application.conf
# 
#     @property
#     def db(self):
#         # type: () -> DatabaseManager
#         return self.application.db
# 
#     @property
#     def metrics(self):
#         # type: () -> IMetrics
#         return self.db.metrics
# 
#     def _init_info(self):
#         return dict(
#             ami_id=self.conf.ami_id,
#             request_id=str(uuid.uuid4()),
#             user_agent=self.request.headers.get('user-agent', ""),
#             remote_ip=self.request.headers.get('x-forwarded-for',
#                                                self.request.remote_ip),
#             authorization=self.request.headers.get('authorization', ""),
#             message_ttl=self.request.headers.get('ttl', None),
#             uri=self.request.uri,
#             python_version=sys.version,
#         )
# 
#     def write_error(self, code, **kwargs):
#         """Write the error (otherwise unhandled exception when dealing with
#         unknown method specifications.)
# 
#         This is a Cyclone API Override method used by endpoint and
#         websocket.
# 
#         """
#         try:
#             self.set_status(code)
#             if 'exc_info' in kwargs:
#                 self.log.failure(
#                     format=kwargs.get('format', "Exception"),
#                     failure=failure.Failure(*kwargs['exc_info']),
#                     client_info=self._client_info)
#             else:
#                 self.log.error("Error in handler: %s" % code,
#                                client_info=self._client_info)
#             self.finish()
#         except Exception as ex:
#             self.log.failure(
#                 "error in write_error: {}:{} while printing {};{}".format(
#                     code, ex, kwargs, self._client_info))
# 
#     def authenticate_peer_cert(self):
#         """Authenticate the client per the configured client_certs.
# 
#         Aborts the request w/ a 401 on failure.
# 
#         """
#         cert = self.request.connection.transport.getPeerCertificate()
#         if cert:
#             cert_signature = cert.digest('sha256')
#             cn = cert.get_subject().CN
#             auth = self.conf.client_certs.get(cert_signature)
#             if auth is not None:
#                 # TLS authenticated
#                 self._client_info.update(tls_auth=auth,
#                                          tls_auth_sha256=cert_signature,
#                                          tls_auth_cn=cn)
#                 return
# 
#             self._client_info.update(tls_failed_sha256=cert_signature,
#                                      tls_failed_cn=cn)
# 
#         self.log.warn("Failed TLS auth", client_info=self._client_info)
#         self.set_status(401)
#         # "Transport mode" isn't standard, inspired by:
#         # http://www6.ietf.org/mail-archive/web/tls/current/msg05589.html
#         self.set_header('WWW-Authenticate',
#                         'Transport mode="tls-client-certificate"')
#         self.finish()
# 
# Path: autopush/exceptions.py
# class InvalidRequest(AutopushException):
#     """Invalid request exception, may include custom status_code and message
#     to write for the error"""
#     def __init__(self, message, status_code=400, errno=None, headers=None):
#         super(AutopushException, self).__init__(message)
#         self.status_code = status_code
#         self.errno = errno
#         self.headers = {} if headers is None else headers
# 
# class RouterException(AutopushException):
#     """Exception if routing has failed, may include a custom status_code and
#     body to write to the response.
# 
#     """
#     def __init__(self, message, status_code=500, response_body="",
#                  router_data=None, headers=None, log_exception=True,
#                  errno=None, logged_status=None, **kwargs):
#         """Create a new RouterException"""
#         super(AutopushException, self).__init__(message)
#         self.status_code = status_code
#         self.headers = {} if headers is None else headers
#         self.log_exception = log_exception
#         self.response_body = response_body or message
#         self.errno = errno
#         self.logged_status = logged_status
#         self.extra = kwargs


import json
import time
from functools import wraps
from botocore.exceptions import ClientError
from marshmallow.schema import UnmarshalResult  # noqa
from typing import (  # noqa
    Any,
    Callable,
    Sequence
)
from twisted.internet.threads import deferToThread
from twisted.logger import Logger
from autopush.base import BaseHandler
from autopush.exceptions import InvalidRequest, RouterException
        from twisted.internet.error import ConnectionDone

            class MyHandler(cyclone.web.RequestHandler):
                @threaded_validate(MySchema())
                def post(self, uaid=None):
                    ...

        """
        return cls(schema)._decorator


# Alias to the validation classmethod decorator
threaded_validate = ThreadedValidate.validate


class NotFoundHandler(BaseHandler):
    def get(self, *args, **kwargs):
        status_code = 404
        error = "Page not found"
        self.set_status(status_code, reason=error)
        error_data = dict(
            code=status_code,
            error=error or status_codes.get(status_code, ""),
        )
        self.write(json.dumps(error_data))
        self.set_header("Content-Type", "application/json")
        self.set_header("Strict-Transport-Security", "max-age=31536000")
        self.finish()
    put = post = delete = get



# Path: autopush/base.py
# class BaseHandler(cyclone.web.RequestHandler):
#     """Base cyclone RequestHandler for autopush"""
# 
#     log = Logger()
# 
#     def initialize(self):
#         """Initialize info from the client"""
#         self._client_info = self._init_info()
# 
#     @property
#     def conf(self):
#         # type: () -> AutopushConfig
#         return self.application.conf
# 
#     @property
#     def db(self):
#         # type: () -> DatabaseManager
#         return self.application.db
# 
#     @property
#     def metrics(self):
#         # type: () -> IMetrics
#         return self.db.metrics
# 
#     def _init_info(self):
#         return dict(
#             ami_id=self.conf.ami_id,
#             request_id=str(uuid.uuid4()),
#             user_agent=self.request.headers.get('user-agent', ""),
#             remote_ip=self.request.headers.get('x-forwarded-for',
#                                                self.request.remote_ip),
#             authorization=self.request.headers.get('authorization', ""),
#             message_ttl=self.request.headers.get('ttl', None),
#             uri=self.request.uri,
#             python_version=sys.version,
#         )
# 
#     def write_error(self, code, **kwargs):
#         """Write the error (otherwise unhandled exception when dealing with
#         unknown method specifications.)
# 
#         This is a Cyclone API Override method used by endpoint and
#         websocket.
# 
#         """
#         try:
#             self.set_status(code)
#             if 'exc_info' in kwargs:
#                 self.log.failure(
#                     format=kwargs.get('format', "Exception"),
#                     failure=failure.Failure(*kwargs['exc_info']),
#                     client_info=self._client_info)
#             else:
#                 self.log.error("Error in handler: %s" % code,
#                                client_info=self._client_info)
#             self.finish()
#         except Exception as ex:
#             self.log.failure(
#                 "error in write_error: {}:{} while printing {};{}".format(
#                     code, ex, kwargs, self._client_info))
# 
#     def authenticate_peer_cert(self):
#         """Authenticate the client per the configured client_certs.
# 
#         Aborts the request w/ a 401 on failure.
# 
#         """
#         cert = self.request.connection.transport.getPeerCertificate()
#         if cert:
#             cert_signature = cert.digest('sha256')
#             cn = cert.get_subject().CN
#             auth = self.conf.client_certs.get(cert_signature)
#             if auth is not None:
#                 # TLS authenticated
#                 self._client_info.update(tls_auth=auth,
#                                          tls_auth_sha256=cert_signature,
#                                          tls_auth_cn=cn)
#                 return
# 
#             self._client_info.update(tls_failed_sha256=cert_signature,
#                                      tls_failed_cn=cn)
# 
#         self.log.warn("Failed TLS auth", client_info=self._client_info)
#         self.set_status(401)
#         # "Transport mode" isn't standard, inspired by:
#         # http://www6.ietf.org/mail-archive/web/tls/current/msg05589.html
#         self.set_header('WWW-Authenticate',
#                         'Transport mode="tls-client-certificate"')
#         self.finish()
# 
# Path: autopush/exceptions.py
# class InvalidRequest(AutopushException):
#     """Invalid request exception, may include custom status_code and message
#     to write for the error"""
#     def __init__(self, message, status_code=400, errno=None, headers=None):
#         super(AutopushException, self).__init__(message)
#         self.status_code = status_code
#         self.errno = errno
#         self.headers = {} if headers is None else headers
# 
# class RouterException(AutopushException):
#     """Exception if routing has failed, may include a custom status_code and
#     body to write to the response.
# 
#     """
#     def __init__(self, message, status_code=500, response_body="",
#                  router_data=None, headers=None, log_exception=True,
#                  errno=None, logged_status=None, **kwargs):
#         """Create a new RouterException"""
#         super(AutopushException, self).__init__(message)
#         self.status_code = status_code
#         self.headers = {} if headers is None else headers
#         self.log_exception = log_exception
#         self.response_body = response_body or message
#         self.errno = errno
#         self.logged_status = logged_status
#         self.extra = kwargs


# Path: autopush/web/base.py
import json
import time
from functools import wraps
from botocore.exceptions import ClientError
from marshmallow.schema import UnmarshalResult  # noqa
from typing import (  # noqa
    Any,
    Callable,
    Sequence
)
from twisted.internet.threads import deferToThread
from twisted.logger import Logger
from autopush.base import BaseHandler
from autopush.exceptions import InvalidRequest, RouterException
        from twisted.internet.error import ConnectionDone


            class MyHandler(cyclone.web.RequestHandler):
                @threaded_validate(MySchema())
                def post(self, uaid=None):
                    ...

        """
        return cls(schema)._decorator


# Alias to the validation classmethod decorator
threaded_validate = ThreadedValidate.validate


class NotFoundHandler(BaseHandler):
    def get(self, *args, **kwargs):
        status_code = 404
        error = "Page not found"
        self.set_status(status_code, reason=error)
        error_data = dict(
            code=status_code,
            error=error or status_codes.get(status_code, ""),
        )
        self.write(json.dumps(error_data))
        self.set_header("Content-Type", "application/json")
        self.set_header("Strict-Transport-Security", "max-age=31536000")
        self.finish()
    put = post = delete = get



class BaseWebHandler(BaseHandler):