Beispiel #1
0
    def make_api(self):
        self.before_hooks.extend(self.hooks.optional_request_hooks())
        self.after_hooks.extend(self.hooks.optional_response_hooks())

        api = API(before=self.before_hooks, after=self.after_hooks)

        # Set the default route to the NYI object
        api.add_sink(self.default_route or NYI(before=self.before_hooks,
                                               after=self.after_hooks))

        # Add Error Handlers - ordered generic to more specific
        built_in_handlers = [(Exception, handle_unexpected_errors),
                             (ResponseException, ResponseException.handle),
                             (InvalidTokenError, InvalidTokenError.handle)]

        for ex, handler in built_in_handlers + self._error_handlers:
            api.add_error_handler(ex,
                                  wrap_handler_with_hooks(handler,
                                                          self.after_hooks))

        # Add all the routes collected thus far
        for _, disp in self._dispatchers.items():
            for endpoint, handler in disp.get_routes():
                LOG.debug("Loading endpoint %s", endpoint)
                api.add_route(endpoint, handler)
                api.add_route('%s.json' % endpoint, handler)

        return api
Beispiel #2
0
def create_api(db: Database) -> API:
    """Create a new application instance.

    - For simplicity, CORS is enabled for all origins,
      all methods and all headers.
    - ``DoesNotExist`` exceptions are caught and converted
      to ``404 Not Found`` error responses.

    Parameters
    ----------
    db : Database
        An instance of the ``Database``.
    
    Returns
    -------
    api : API
    """
    # Middleware.
    cors = CORS(allow_all_origins=True,
                allow_all_methods=True,
                allow_all_headers=True)

    # Application instance.
    api = API(middleware=[cors.middleware])

    # Error handlers.
    api.add_error_handler(DoesNotExist, on_does_not_exist)

    # Resources.
    users = UserResource(db)
    user_songs = UserSongsResource(db)
    song = SongResource(db)
    token = TokenResource(db)

    # Routes.
    api.add_route("/users/", users)
    api.add_route("/users/{username}/songs", user_songs)
    api.add_route("/songs/{pk}", song)
    api.add_route("/songs/", song)
    api.add_route("/tokens/{token}", token)
    api.add_route("/tokens/", token)

    return api
Beispiel #3
0
def api(title, version):
    log = Log.get('api')

    middlewares = [Negotiation_Middleware()]

    if Arg_Reader.db.auth:
        log.notice('JWT authentication enabled')
        middlewares.append(
            Falcon_Auth_Middleware(
                JWT_Auth_Backend(
                    user_loader=lambda token: {'user': token},
                    secret_key=Arg_Reader.db.auth_secret_key,
                    auth_header_prefix=Arg_Reader.db.auth_header_prefix),
                exempt_routes=['/api/doc', '/api/doc/swagger.json']))
    else:
        log.notice('JWT authentication disabled')

    if Arg_Reader.db.https:
        log.notice('Force to use HTTPS instead of HTTP')
        middlewares.append(RequireHTTPS())
    else:
        log.notice('HTTPS not set')

    if Arg_Reader.db.apm_enabled:
        log.notice('Elastic APM enabled')
        middlewares.append(
            Elastic_Apm_Middleware(service_name='lcp-apm',
                                   server_url=Arg_Reader.db.apm_server))
    else:
        log.notice('Elastic APM disabled')

    instance = API(middleware=middlewares)

    media_handlers = {
        falcon.MEDIA_JSON:
        JSON_Handler(loads=loads,
                     dumps=partial(dumps, ensure_ascii=False, sort_keys=True)),
        falcon.MEDIA_MSGPACK:
        Message_Pack_Handler(),
        falcon.MEDIA_XML:
        XML_Handler(),
        falcon.MEDIA_YAML:
        YAML_Handler()
    }
    instance.req_options.media_handlers.update(media_handlers)
    instance.resp_options.media_handlers.update(media_handlers)

    instance.add_error_handler(*Bad_Request_Handler.get())
    instance.add_error_handler(*Internal_Server_Error_Handler.get())
    instance.add_error_handler(*Unsupported_Media_Type_Handler.get())

    api_spec = Spec(api=instance, title=title, version=version)
    routes(api=instance, spec=api_spec.get())
    falcon_api_doc(instance,
                   config_path='./swagger/schema.json',
                   url_prefix='/api/doc',
                   title='API doc')
    api_spec.write()

    return instance
def api(title, version, dev_username, dev_password):
    instance = API(middleware=[
        Falcon_Auth_Middleware(
            Basic_Auth_Backend_Middleware(dev_username, dev_password),
            exempt_routes=['/api/doc', '/api/doc/swagger.json']),
        Negotiation_Middleware()  # ,
        # Elastic_Apm_Middleware(
        #     service_name='lcp-apm',
        #     server_url=Arg_Reader.db.apm_server
        # )
    ])

    media_handlers = {
        falcon.MEDIA_JSON:
        JSON_Handler(loads=loads,
                     dumps=partial(dumps, ensure_ascii=False, sort_keys=True)),
        falcon.MEDIA_MSGPACK:
        Message_Pack_Handler(),
        falcon.MEDIA_XML:
        XML_Handler(),
        falcon.MEDIA_YAML:
        YAML_Handler()
    }
    instance.req_options.media_handlers.update(media_handlers)
    instance.resp_options.media_handlers.update(media_handlers)

    instance.add_error_handler(*Bad_Request_Handler.get())
    instance.add_error_handler(*Unsupported_Media_Type_Handler.get())

    api_spec = Spec(api=instance, title=title, version=version)
    routes(api=instance, spec=api_spec.get())
    falcon_api_doc(instance,
                   config_path='./swagger/schema.json',
                   url_prefix='/api/doc',
                   title='API doc')
    api_spec.write()

    return instance
Beispiel #5
0
def create_app():
	# type: () -> API
	# Get configuration
	config = Configuration()

	logging_args = {
		'level': config.log_level
	}
	if config.log_output:
		logging_args['filename'] = config.log_output
	if config.log_format:
		logging_args['format'] = config.log_format
	if config.log_style:
		logging_args['style'] = config.log_style
	if config.log_dateformat:
		logging_args['datefmt'] = config.log_dateformat

	logging.basicConfig(**logging_args)
	logger = logging.getLogger(__name__)

	# Create SQLAlchemy engine
	basedir = os.path.abspath(os.path.dirname(__file__))
	database = '%s:///%s' % (config.db_type, os.path.join(basedir, config.db_name))
	engine = create_engine(database)
	sql_middleware = SqlAlchemy(engine)

	# Drop DB if required
	if config.drop_db:
		logger.debug('Dropping current DB...')
		drop_db(engine)
		logger.debug('Current DB dropped. Recreating new DB...')
	else:
		logger.debug('Creating DB if not present')

	# Create DB if needed
	create_db(engine)
	logger.debug('DB created (if needed). Initializing DB content if needed.')
	init_db(sql_middleware.new_session(), config.matches_txt_timezone)
	logger.debug('DB content initialized (if needed).')
	sql_middleware.delete_session()

	# Create TimeBase service
	timebase = TimeBase()
	# Create basic authenticator for use with all Auth backend
	authenticator = Authenticator(timebase, sql_middleware)

	# Create default Token Auth backend
	backend = TokenAuthBackend(authenticator)

	# Create Falcon API with proper middleware: Marshmallow (validation), SQLAlchemy (persistence)
	api = API(middleware=[LoggingMiddleware(), sql_middleware, FalconAuthMiddleware(backend), context_middleware, Marshmallow()])

	api.add_error_handler(Exception, ExceptionHandler(falcon.HTTP_INTERNAL_SERVER_ERROR, "Internal error"))
	api.add_error_handler(DBAPIError, ExceptionHandler(falcon.HTTP_INTERNAL_SERVER_ERROR, "Database error"))
	api.add_error_handler(IntegrityError, ExceptionHandler(falcon.HTTP_UNPROCESSABLE_ENTITY, "Integrity constraint error"))
	# We have to re-register the following handlers because although registered by default, 
	# they will never get called due to our Exception handler
	api.add_error_handler(falcon.HTTPError, api._http_error_handler)
	api.add_error_handler(falcon.HTTPStatus, api._http_status_handler)

	from .resources import Team, Teams, Venue, Venues, Match, Matches, Bets, User, Users, Token, Time, Profile

	if config.timebase_changes:
		api.add_route('/time', Time(timebase))
	api.add_route('/token', Token())
	api.add_route('/team', Teams())
	api.add_route('/team/{id:int}', Team())
	api.add_route('/venue', Venues())
	api.add_route('/venue/{id:int}', Venue())
	api.add_route('/match', Matches())
	api.add_route('/match/{id:int}', Match(timebase))
	api.add_route('/user', Users(timebase))
	api.add_route('/user/{id_or_name}', User())
	api.add_route('/bet', Bets(timebase))
	api.add_route('/profile', Profile(timebase))

	logger.info('API service started.')
	
	return api
Beispiel #6
0
def install_handler(api: falcon.API) -> None:
    api.add_error_handler(_StructuredError)