def _factory(options): multipart_handler = media.MultipartFormHandler() for key, value in options.items(): setattr(multipart_handler.parse_options, key, value) req_handlers = media.Handlers({ falcon.MEDIA_JSON: media.JSONHandler(), falcon.MEDIA_MULTIPART: multipart_handler, }) app = create_app(asgi) app.req_options.media_handlers = req_handlers app.resp_options.media_handlers = media.Handlers({ falcon.MEDIA_JSON: media.JSONHandler(), falcon.MEDIA_MSGPACK: media.MessagePackHandler(), }) resource = AsyncMultipartAnalyzer() if asgi else MultipartAnalyzer() app.add_route('/submit', resource) app.add_route('/media', resource, suffix='media') app.add_route('/mirror', resource, suffix='mirror') return testing.TestClient(app)
def test_serialization(func, body, expected): JH = media.JSONHandler(dumps=func) # NOTE(nZac) PyPy and CPython render the final string differently. One # includes spaces and the other doesn't. This replace will normalize that. assert JH.serialize(body, b'application/javacript').replace( b' ', b'') == expected # noqa
def test_deserialization(func, body, expected): JH = media.JSONHandler(loads=func) assert JH.deserialize( io.BytesIO(body), 'application/javacript', len(body) ) == expected
def test_exhausted_stream(media_type): client = create_client({ 'application/json': media.JSONHandler(), }) headers = {'Content-Type': media_type} client.simulate_post('/', body='', headers=headers) assert client.resource.captured_req.media is None
def __init__(self): handlers = media.Handlers({ 'application/json': media.JSONHandler() }) self.db_middleware = DatabaseMiddleware() self.config_middleware = ConfigMiddleware() self.validation_middleware = ValidationMiddleware() self.negotiation_middleware = NegotiationMiddleware() self.user_middleware = UserMiddleware() self.api = falcon.API(middleware=[ self.config_middleware, self.db_middleware, self.user_middleware, self.validation_middleware, self.negotiation_middleware ]) self.api.req_options.media_handlers = handlers self.api.req_options.auto_parse_form_urlencoded = True self.api.resp_options.media_handlers = handlers self.api.add_error_handler(Exception, error_handler) self.api.resp_options.secure_cookies_by_default = False # Routes dir_path = os.path.dirname(os.path.realpath(__file__)) # Home route self.api.add_route('/app/home', HomeResource()) # User routes self.api.add_route('/app/create', UserCreateResource()) self.api.add_route('/app/create_email_exists', UserCreateEmailExistsResource()) self.api.add_route('/app/login', UserLoginResource()) self.api.add_route('/app/login_failed', UserLoginFailedResource()) self.api.add_route('/app/session_expired', SessionExpiredResource()) self.api.add_route('/app/logout', UserLogoutResource()) self.api.add_route('/api/users', UserCollectionResource()) # Session routes self.api.add_route('/api/session', SessionResource()) # Pomodoro routes self.api.add_route('/app/pomodoro', PomodoroResource()) self.api.add_route('/app/pomodoro_set', PomodoroSetResource()) self.api.add_route('/app/pom_exists', PomodoroExistsErrorResource()) self.api.add_route('/app/pom_invalid', PomodoroValidationErrorResource()) self.api.add_route('/api/pom_validation', PomodoroValidationResource()) self.api.add_route('/api/poms/today', PomodoroCollectionTodayResource()) self.api.add_route('/api/poms', PomodoroCollectionResource()) self.api.add_route('/api/delete_poms', DeletePomsResource()) self.api.add_route('/api/flag_types', FlagTypesResource()) self.api.add_route('/api/pom_sheet_export', PomSheetExportResource()) self.api.add_route('/app/export_poms', ExportPomsResource()) # Settings route self.api.add_route('/app/settings', UserSettingsResource()) # Static directory routes self.api.add_static_route('/css', dir_path + '/css') self.api.add_static_route('/js', dir_path + '/js') self.api.add_static_route('/assets', dir_path + '/assets')
def test_empty_body(asgi, media_type): client = _create_client_invalid_media( asgi, errors.HTTPBadRequest, { 'application/msgpack': media.MessagePackHandler(), 'application/json': media.JSONHandler(), }) headers = {'Content-Type': media_type} assert client.simulate_post('/', headers=headers).status_code == 200 assert 'Could not parse an empty' in client.resource.captured_error.value.description assert isinstance(client.resource.captured_error.value, errors.MediaNotFoundError)
def test_serialization(asgi, func, body, expected): handler = media.JSONHandler(dumps=func) args = (body, b'application/javacript') if asgi: result = falcon.async_to_sync(handler.serialize_async, *args) else: result = handler.serialize(*args) # NOTE(nZac) PyPy and CPython render the final string differently. One # includes spaces and the other doesn't. This replace will normalize that. assert result.replace(b' ', b'') == expected # noqa
def _factory(options): multipart_handler = media.MultipartFormHandler() for key, value in options.items(): setattr(multipart_handler.parse_options, key, value) handlers = media.Handlers({ falcon.MEDIA_JSON: media.JSONHandler(), falcon.MEDIA_MULTIPART: multipart_handler, }) app = falcon.App() app.req_options.media_handlers = handlers app.add_route('/media', MultipartAnalyzer()) return testing.TestClient(app)
def client(): handlers = media.Handlers({ falcon.MEDIA_JSON: media.JSONHandler(), falcon.MEDIA_URLENCODED: media.URLEncodedFormHandler(), }) api = falcon.API() api.req_options.media_handlers = handlers api.resp_options.media_handlers = handlers api.add_route('/media', MediaMirror()) return testing.TestClient(api)
def define_custom_settings_for_application_layer(self): json_handler = media.JSONHandler( dumps=rapidjson.dumps, loads=rapidjson.loads, ) extra_handlers = { 'application/json': json_handler, } self.application_layer.req_options.media_handlers.update( extra_handlers) self.application_layer.resp_options.media_handlers.update( extra_handlers) return self
def test_fallback_not_for_error_body(asgi, exhaust_stream, body): js = media.JSONHandler() js.exhaust_stream = exhaust_stream client = create_client(asgi, resource=FallBackAsync() if asgi else FallBack(), handlers={ 'application/json': js, }) res = client.simulate_get('/', body=b'{' if body else '') if body: assert res.status_code == 400 assert 'Could not parse JSON body' in res.json['description'] else: assert res.status_code == 200
def create_app(inbox, token, name): app = falcon.asgi.App() json_handler = media.JSONHandler( loads=deserialize, ) extra_handlers = { 'application/json': json_handler, } app.req_options.media_handlers.update(extra_handlers) app.resp_options.media_handlers.update(extra_handlers) messaging = Messaging(inbox=inbox) app.add_route('/messaging', messaging) return app
def update_json_handlers(app): def _json_dumps(obj): if isinstance(obj, (dict, MappingProxyType)): return dict(obj) if isinstance(obj, set): return tuple(obj) return obj media_handlers = { 'application/json': media.JSONHandler( dumps=partial(json.dumps, default=_json_dumps), loads=json.loads, ), } app.req_options.media_handlers.update(media_handlers) app.resp_options.media_handlers.update(media_handlers)
def create_app(): app = falcon.API(middleware=[CrossDomain(), JSONTranslator()]) json_handler = media.JSONHandler( dumps=partial(rapidjson.dumps, ensure_ascii=False, sort_keys=True), loads=rapidjson.loads, ) extra_handlers = { "application/json": json_handler, } app.req_options.media_handlers.update(extra_handlers) app.resp_options.media_handlers.update(extra_handlers) app.add_error_handler(Exception, error_handler) setup_routes(app) return app
def test_deserialization(asgi, func, body, expected): handler = media.JSONHandler(loads=func) args = ['application/javacript', len(body)] if asgi: if not ASGI_SUPPORTED: pytest.skip('ASGI requires Python 3.6+') from falcon.asgi.stream import BoundedStream s = BoundedStream(testing.ASGIRequestEventEmitter(body)) args.insert(0, s) result = falcon.async_to_sync(handler.deserialize_async, *args) else: args.insert(0, io.BytesIO(body)) result = handler.deserialize(*args) assert result == expected
from elasticapm.conf import setup_logging from elasticapm.handlers.logging import LoggingHandler from falcon import DEFAULT_MEDIA_TYPE from falcon import media from falcon.request import Request from falcon.response import Response from webargs import falconparser from mcod import settings from mcod.core.api import middlewares from mcod.core.api.apm import get_client, get_data_from_request from mcod.lib.errors import error_serializer, error_handler, error_422_handler, error_500_handler logger = logging.getLogger("elasticapm.errors.client") extra_handlers = {'application/vnd.api+json': media.JSONHandler()} class ApiApp(falcon.API): def __init__(self, media_type=DEFAULT_MEDIA_TYPE, request_type=Request, response_type=Response, middleware=None, router=None, independent_middleware=False): self.apm_client = get_client() if self.apm_client: logging_level = getattr(settings, 'API_LOG_LEVEL', 'DEBUG') setup_logging(LoggingHandler(self.apm_client, level=logging_level))
#!/usr/bin/env python import orjson from falcon import media from app import wsgi # custom JSON handler JSONHandler = media.JSONHandler(dumps=orjson.dumps, loads=orjson.loads) extra_handlers = { "application/json": JSONHandler, "application/json; charset=UTF-8": JSONHandler } wsgi.req_options.media_handlers.update(extra_handlers) wsgi.resp_options.media_handlers.update(extra_handlers)
FalconIntegration(), ]) RECOMMENDATION_HANDLER = RecommendationHandler( sharedstate.spacy_instance, sharedstate.tf_session, sharedstate.tf_encodings, sharedstate.tf_input_placeholder, sharedstate.tf_sentence_piece_processor, ) DOCUMENT_PARSER = DocumentParser(sharedstate.spacy_instance) API = falcon.API() API.add_route('/analyze', AnalyzeResource( DOCUMENT_PARSER, RECOMMENDATION_HANDLER, )) #API.add_route('/analytics', AnalyticsResource()) JSON_HANDLER = media.JSONHandler( dumps=partial(json.dumps, cls=RecommendationJsonEncoder), loads=json.loads, ) EXTRA_HANDLERS = { 'application/json': JSON_HANDLER, } API.req_options.media_handlers.update(EXTRA_HANDLERS) API.resp_options.media_handlers.update(EXTRA_HANDLERS) print("Ready.")