示例#1
0
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
示例#2
0
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)
示例#3
0
def test_more_than_one_star_raises():
    router = Router()

    def home():
        ...

    with pytest.raises(RouteException):
        router.add_get("*/*", home)
示例#4
0
def test_more_than_one_star_raises():
    router = Router()

    def home():
        ...

    with pytest.raises(ValueError):
        router.add_get("*/*", home)
示例#5
0
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
示例#6
0
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
示例#7
0
    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
示例#8
0
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
示例#9
0
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
示例#10
0
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
示例#11
0
    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
示例#12
0
    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()
示例#13
0
    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
示例#14
0
    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)
示例#15
0
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())
示例#16
0
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
示例#17
0
    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
示例#18
0
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)
示例#19
0
    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
示例#20
0
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
示例#21
0
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
示例#22
0
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)
示例#23
0
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'
示例#24
0
    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
示例#25
0
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)
示例#26
0
    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)
示例#27
0
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"
示例#28
0
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"
示例#29
0
    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
示例#30
0
    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