def test_router_iterable(): router = Router() @router.get("/") def home(): ... @router.trace("/") def home_verbose(): ... @router.options("/") def home_options(): ... routes = list(router) assert len(routes) == 3 handlers = {home, home_verbose, home_options} for route in routes: assert route.handler in handlers def fallback(): ... router.fallback = fallback routes = list(router) assert len(routes) == 4 handlers = {home, home_verbose, home_options, fallback} for route in routes: assert route.handler in handlers
def serve_files_dynamic( router: Router, files_handler: FilesHandler, options: ServeFilesOptions ) -> None: """ Configures a route to serve files dynamically, using the given files handler and options. """ options.validate() handler = get_files_route_handler( files_handler, str(options.source_folder), options.discovery, options.cache_time, options.extensions, options.root_path, options.index_document, options.fallback_document, ) if options.allow_anonymous: handler = allow_anonymous()(handler) route = Route( get_static_files_route(options.root_path), handler, ) router.add_route("GET", route) router.add_route("HEAD", route)
def test_more_than_one_star_raises(): router = Router() def home(): ... with pytest.raises(RouteException): router.add_get("*/*", home)
def test_more_than_one_star_raises(): router = Router() def home(): ... with pytest.raises(ValueError): router.add_get("*/*", home)
def test_automatic_pattern_with_ellipsis_index_name(): router = Router() @router.get(...) def index(): ... match = router.get_match('GET', '/') assert match is not None assert match.handler is index
def test_router_match_with_trailing_slash(): router = Router() def get_foo(): ... def create_foo(): ... router.add_get("/foo", get_foo) router.add_post("/foo", create_foo) m = router.get_match(HttpMethod.GET, b"/foo/") assert m is not None assert m.handler is get_foo m = router.get_match(HttpMethod.POST, b"/foo/") assert m is not None assert m.handler is create_foo m = router.get_match(HttpMethod.POST, b"/foo//") assert m is None
def test_fallback_route(self): router = Router() def not_found_handler(): pass router.fallback = not_found_handler m = router.get_match(HttpMethod.POST, b'/') assert m is not None assert m.handler is not_found_handler
def test_sort_routes_path_pattern(pattern): router = Router() catch_all_route = Route(pattern, mock_handler) router.add_route("GET", catch_all_route) router.add_route("GET", Route("/cat/:cat_id", mock_handler)) router.add_route("GET", Route("/index", mock_handler)) router.add_route("GET", Route("/about", mock_handler)) assert router.routes[b"GET"][0] is catch_all_route router.sort_routes() assert router.routes[b"GET"][-1] is catch_all_route
def test_automatic_pattern_with_ellipsis_name_normalization(): router = Router() @router.get(...) def hello_world(): ... match = router.get_match('GET', '/hello_world') assert match is None match = router.get_match('GET', '/hello-world') assert match is not None assert match.handler is hello_world
def test_fallback_route(): router = Router() def not_found_handler(): pass router.fallback = not_found_handler assert isinstance(router.fallback, Route) assert router.fallback.handler is not_found_handler m = router.get_match(HttpMethod.POST, b"/") assert m is not None assert m.handler is not_found_handler
def __init__(self, router: Optional[Router] = None, middlewares: Optional[List[Callable]] = None, resources: Optional[Resources] = None, services: Optional[ServicesType] = None, debug: bool = False, show_error_details: bool = False): if router is None: router = Router() if services is None: services = Container() super().__init__(get_show_error_details(debug or show_error_details), router) if middlewares is None: middlewares = [] if resources is None: resources = Resources(get_resource_file_content('error.html')) self.services = services # type: ServicesType self.debug = debug self.middlewares = middlewares self.access_logger = None self.logger = None self._default_headers = None self._use_sync_logging = False self._middlewares_configured = False self.resources = resources self._serve_files = None self._authentication_strategy = None # type: Optional[AuthenticationStrategy] self._authorization_strategy = None # type: Optional[AuthorizationStrategy] self.on_start = ApplicationEvent(self) self.on_stop = ApplicationEvent(self) self.started = False self.controllers_router: RoutesRegistry = controllers_router
def __init__( self, *, router: Optional[Router] = None, resources: Optional[Resources] = None, services: Optional[Container] = None, debug: bool = False, show_error_details: bool = False, ): if router is None: router = Router() if services is None: services = Container() super().__init__(show_error_details, router) if resources is None: resources = Resources(get_resource_file_content("error.html")) self.services: Container = services self._service_provider: Optional[Services] = None self.debug = debug self.middlewares: List[Callable[..., Awaitable[Response]]] = [] self.access_logger = None self.logger = None self._default_headers: Optional[Tuple[Tuple[str, str], ...]] = None self._middlewares_configured = False self.resources = resources self._authentication_strategy: Optional[AuthenticationStrategy] = None self._authorization_strategy: Optional[AuthorizationStrategy] = None self.on_start = ApplicationEvent(self) self.after_start = ApplicationEvent(self) self.on_stop = ApplicationEvent(self) self.started = False self.controllers_router: RoutesRegistry = controllers_router self.files_handler = FilesHandler()
def __init__( self, *, router: Optional[Router] = None, services: Optional[Container] = None, debug: bool = False, show_error_details: Optional[bool] = None, ): if router is None: router = Router() if services is None: services = Container() if show_error_details is None: show_error_details = bool( os.environ.get("APP_SHOW_ERROR_DETAILS", False)) super().__init__(show_error_details, router) self.services: Container = services self._service_provider: Optional[Services] = None self.debug = debug self.middlewares: List[Callable[..., Awaitable[Response]]] = [] self._default_headers: Optional[Tuple[Tuple[str, str], ...]] = None self._middlewares_configured = False self._cors_strategy: Optional[CORSStrategy] = None self._authentication_strategy: Optional[AuthenticationStrategy] = None self._authorization_strategy: Optional[AuthorizationStrategy] = None self.on_start = ApplicationEvent(self) self.after_start = ApplicationEvent(self) self.on_stop = ApplicationEvent(self) self.started = False self.controllers_router: RoutesRegistry = controllers_router self.files_handler = FilesHandler() self.server_error_details_handler = ServerErrorDetailsHandler() self._session_middleware: Optional[SessionMiddleware] = None
def __init__(self, options: Optional[ServerOptions] = None, router: Optional[Router] = None, middlewares: Optional[List[Callable]] = None, resources: Optional[Resources] = None, services: Any = None, debug: bool = False): if not options: options = ServerOptions('', 8000) if router is None: router = Router() if services is None: services = {} super().__init__(options, router, services) if middlewares is None: middlewares = [] if resources is None: resources = Resources(get_resource_file_content('error.html')) self.debug = debug self.running = False self.middlewares = middlewares self.current_timestamp = get_current_timestamp() self.processes = [] self.access_logger = None self.logger = None self._default_headers = None self._use_sync_logging = False self._middlewares_configured = False self.resources = resources self._serve_files = None self._serve_static_files = None self.on_start = ApplicationEvent(self) self.on_stop = ApplicationEvent(self)
def test_cors_strategy_raises_for_duplicate_policy_name(): cors = CORSStrategy(CORSPolicy(), Router()) cors.add_policy("a", CORSPolicy()) with pytest.raises(CORSConfigurationError): cors.add_policy("a", CORSPolicy())
def test_cors_strategy_raises_for_missing_policy_name(): cors = CORSStrategy(CORSPolicy(), Router()) with pytest.raises(CORSConfigurationError): cors.add_policy("", CORSPolicy()) with pytest.raises(CORSConfigurationError): cors.add_policy(None, CORSPolicy()) # type: ignore
def test_router_decorator(self, decorator, pattern, url): router = Router() method = getattr(router, decorator) @method(pattern) def home(): return 'Hello, World' route = router.get_match(decorator.upper(), url) assert route is not None assert route.handler is home value = route.handler() assert value == 'Hello, World' route = router.get_match(FAKE, url) assert route is None
def serve_files_dynamic( router: Router, files_handler: FilesHandler, source_folder: str, *, discovery: bool, cache_time: int, extensions: Optional[Set[str]], root_path: str, index_document: Optional[str], fallback_document: Optional[str], anonymous_access: bool = True, ) -> None: """ Configures a route to serve files dynamically, using the given files handler and options. """ validate_source_path(source_folder) if not extensions: extensions = get_default_extensions() handler = get_files_route_handler( files_handler, str(source_folder), bool(discovery), int(cache_time), set(extensions), root_path, index_document, fallback_document, ) if anonymous_access: handler = allow_anonymous()(handler) route = Route( get_static_files_route(root_path), handler, ) router.add_route("GET", route) router.add_route("HEAD", route)
def test_router_add_shortcuts(self, method, pattern, url): router = Router() fn = getattr(router, f'add_{method}') def home(): return 'Hello, World' fn(pattern, home) route = router.get_match(method.upper(), url) assert route is not None assert route.handler is home value = route.handler() assert value == 'Hello, World' route = router.get_match(FAKE, url) assert route is None
def test_automatic_pattern_with_ellipsis(): router = Router() @router.get(...) def home(): ... @router.get(...) def another(): ... match = router.get_match('GET', '/') assert match is None match = router.get_match('GET', '/home') assert match is not None assert match.handler is home match = router.get_match('GET', '/another') assert match is not None assert match.handler is another
def test_router_add_method(method, pattern, url): router = Router() router.add(method, pattern, mock_handler) match = router.get_match(method, url) assert match is not None assert match.handler is mock_handler route = router.get_matching_route(method, url) assert route is not None match = router.get_match(FAKE, url) assert match is None route = router.get_matching_route(FAKE, url) assert route is None
def test_duplicate_pattern_raises(first_route, second_route): router = Router() def home(): ... def another(): ... router.add_get(first_route, home) with pytest.raises(RouteDuplicate): router.add_get(second_route, another)
def test_router_match_any_by_extension(): router = Router() def a(): ... def b(): ... router.add_get(b'/a/*.js', a) router.add_get(b'/b/*.css', b) m = router.get_match(HttpMethod.GET, b'/a/anything/really') assert m is None m = router.get_match(HttpMethod.GET, b'/a/anything/really.js') assert m is not None assert m.handler is a assert m.values.get('tail') == 'anything/really' m = router.get_match(HttpMethod.GET, b'/b/anything/really.css') assert m is not None assert m.handler is b assert m.values.get('tail') == 'anything/really'
def test_router_add_method(self, method, pattern, url): router = Router() router.add(method, pattern, mock_handler) route = router.get_match(method, url) assert route is not None assert route.handler is mock_handler route = router.get_match(FAKE, url) assert route is None
def test_duplicate_pattern_star_raises(): router = Router() def home(): ... def another(): ... router.add_get(b'*', home) with pytest.raises(RouteDuplicate): router.add_get(b'*', another)
def test_duplicate_pattern_raises(self): router = Router() def home(): pass def another(): pass router.add_get(b'/', home) with pytest.raises(RouteDuplicate): router.add_get(b'/', another)
def test_router_match_any_by_extension(): router = Router() def a(): ... def b(): ... router.add_get("/a/*.js", a) router.add_get("/b/*.css", b) m = router.get_match(HttpMethod.GET, b"/a/anything/really") assert m is None m = router.get_match(HttpMethod.GET, b"/a/anything/really.js") assert m is not None assert m.handler is a assert m.values.get("tail") == "anything/really" m = router.get_match(HttpMethod.GET, b"/b/anything/really.css") assert m is not None assert m.handler is b assert m.values.get("tail") == "anything/really"
def test_fallback_route_must_be_callable_or_route(): router = Router() def not_found_handler(): pass router.fallback = Route("*", not_found_handler) router.fallback = not_found_handler class Example: def __call__(self): pass router.fallback = Example() with pytest.raises(ValueError): router.fallback = False with pytest.raises(ValueError): router.fallback = "Something"
def test_router_match_among_many(self): router = Router() def home(): pass def get_foo(): pass def create_foo(): pass def delete_foo(): pass router.add_get(b'/', home) router.add_get(b'/foo', get_foo) router.add_post(b'/foo', create_foo) router.add_delete(b'/foo', delete_foo) m = router.get_match(HttpMethod.GET, b'/') assert m is not None assert m.handler is home m = router.get_match(HttpMethod.POST, b'/') assert m is None m = router.get_match(HttpMethod.GET, b'/foo') assert m is not None assert m.handler is get_foo m = router.get_match(HttpMethod.POST, b'/foo') assert m is not None assert m.handler is create_foo m = router.get_match(HttpMethod.DELETE, b'/foo') assert m is not None assert m.handler is delete_foo
def test_router_match_any_below(self): router = Router() def a(): pass def b(): pass def c(): pass def d(): pass router.add_get(b'/a/*', a) router.add_get(b'/b/*', b) router.add_get(b'/c/*', c) router.add_get(b'/d/*', d) m = router.get_match(HttpMethod.GET, b'/a') assert m is None m = router.get_match(HttpMethod.GET, b'/a/anything/really') assert m is not None assert m.handler is a assert m.values.get('tail') == 'anything/really' m = router.get_match(HttpMethod.GET, b'/b/anything/really') assert m is not None assert m.handler is b assert m.values.get('tail') == 'anything/really' m = router.get_match(HttpMethod.GET, b'/c/anything/really') assert m is not None assert m.handler is c assert m.values.get('tail') == 'anything/really' m = router.get_match(HttpMethod.GET, b'/d/anything/really') assert m is not None assert m.handler is d assert m.values.get('tail') == 'anything/really' m = router.get_match(HttpMethod.POST, b'/a/anything/really') assert m is None m = router.get_match(HttpMethod.POST, b'/b/anything/really') assert m is None m = router.get_match(HttpMethod.POST, b'/c/anything/really') assert m is None m = router.get_match(HttpMethod.POST, b'/d/anything/really') assert m is None