Перейти к содержанию

Include class

Warning

The current page still doesn't have a translation for this language.

But you can help translating it: Contributing.

This is the reference for the Include that contains all the parameters, attributes and functions.

How to import

from esmerald import Include

esmerald.Include

Include(path=None, app=None, name=None, routes=None, namespace=None, pattern=None, parent=None, dependencies=None, interceptors=None, permissions=None, exception_handlers=None, middleware=None, include_in_schema=True, deprecated=None, security=None, tags=None)

Bases: Include

Include object class that allows scalability and modularity to happen with elegance.

Read more about the Include to understand what can be done.

Include manages routes as a list or as a namespace but not both or a ImproperlyConfigured is raised.

PARAMETER DESCRIPTION
path

Relative path of the Include. The path can contain parameters in a dictionary like format and if the path is not provided, it will default to /.

Example

Include()

Example with parameters

Include(path="/{age: int}")

TYPE: Optional[str] DEFAULT: None

app

An application can be anything that is treated as an ASGI application. For example, it can be a ChildEsmerald, another Esmerald, a Router or even an external WSGI application (Django, Flask...)

The app is a parameter that makes the Include extremely powerful when it comes to integrate with ease with whatever Python stack you want and need.

Example

from esmerald import Esmerald, ChildEsmerald, Include

Esmerald(
    routes=[
        Include('/child', app=ChildEsmerald(...))
    ]
)

Example with a WSGI framework

from flask import Flask, escape, request

from esmerald import Esmerald, Gateway, Include, Request, get
from esmerald.middleware.wsgi import WSGIMiddleware

flask_app = Flask(__name__)


@flask_app.route("/")
def flask_main():
    name = request.args.get("name", "Esmerald")
    return f"Hello, {escape(name)} from your Flask integrated!"


@get("/home/{name:str}")
async def home(request: Request) -> dict:
    name = request.path_params["name"]
    return {"name": escape(name)}


app = Esmerald(
    routes=[
        Gateway(handler=home),
        Include("/flask", WSGIMiddleware(flask_app)),
    ]
)

TYPE: ASGIApp | str DEFAULT: None

name

The name for the Gateway. The name can be reversed by path_for().

TYPE: Optional[str] DEFAULT: None

routes

A global list of esmerald routes. Those routes may vary and those can be Gateway, WebSocketGateWay or even another Include.

This is also an entry-point for the routes of the Include but it does not rely on only one level.

Read more about how to use and leverage the Esmerald routing system.

Example

from esmerald import Esmerald, Gateway, Request, get, Include


@get()
async def homepage(request: Request) -> str:
    return "Hello, home!"


@get()
async def another(request: Request) -> str:
    return "Hello, another!"

app = Esmerald(
    routes=[
        Gateway(handler=homepage)
        Include("/nested", routes=[
            Gateway(handler=another)
        ])
    ]
)

Note

The Include is very powerful and this example is not enough to understand what more things you can do. Read in more detail about this.

TYPE: Optional[Sequence[Union[APIGateHandler, Include, HTTPHandler, WebSocketHandler]]] DEFAULT: None

namespace

A string with a qualified namespace from where the URLs should be loaded.

The namespace is an alternative to routes parameter. When a namespace is specified and a routes as well, an ImproperlyCOnfigured exception is raised as it can only be one or another.

The namespace can be extremely useful as it avoids the imports from the top of the file that can lead to partially imported errors.

When using a namespace, the Include will look for the default route_patterns list in the imported namespace (object) unless a different pattern is specified.

Example

Assuming there is a file with some routes located at myapp/auth/urls.py.

myapp/auth/urls.py
from esmerald import Gateway
from .view import welcome, create_user

route_patterns = [
    Gateway(handler=welcome, name="welcome"),
    Gateway(handler=create_user, name="create-user"),
]

Using the namespace to import the URLs.

from esmerald import Include

Include("/auth", namespace="myapp.auth.urls")

TYPE: Optional[str] DEFAULT: None

pattern

A string pattern information from where the urls shall be read from.

By default, the when using the namespace it will lookup for a route_patterns but somethimes you might want to opt for a different name and this is where the pattern comes along.

Example

Assuming there is a file with some routes located at myapp/auth/urls.py. The urls will be placed inside a urls list.

myapp/auth/urls.py
from esmerald import Gateway
from .view import welcome, create_user

urls = [
    Gateway(handler=welcome, name="welcome"),
    Gateway(handler=create_user, name="create-user"),
]

Using the namespace to import the URLs.

from esmerald import Include

Include("/auth", namespace="myapp.auth.urls", pattern="urls")

TYPE: Optional[str] DEFAULT: None

parent

Who owns the Gateway. If not specified, the application automatically it assign it.

This is directly related with the application levels.

TYPE: Optional[ParentType] DEFAULT: None

dependencies

A dictionary of string and Inject instances enable application level dependency injection.

TYPE: Optional[Dependencies] DEFAULT: None

interceptors

A list of interceptors to serve the application incoming requests (HTTP and Websockets).

TYPE: Optional[Sequence[Interceptor]] DEFAULT: None

permissions

A list of permissions to serve the application incoming requests (HTTP and Websockets).

TYPE: Optional[Sequence[Permission]] DEFAULT: None

exception_handlers

A dictionary of exception types (or custom exceptions) and the handler functions on an application top level. Exception handler callables should be of the form of handler(request, exc) -> response and may be be either standard functions, or async functions.

TYPE: Optional[ExceptionHandlerMap] DEFAULT: None

middleware

A list of middleware to run for every request. The middlewares of an Include will be checked from top-down or Lilya Middleware as they are both converted internally. Read more about Python Protocols.

TYPE: Optional[List[Middleware]] DEFAULT: None

include_in_schema

Boolean flag indicating if it should be added to the OpenAPI docs.

This will add all the routes of the Include even those nested (Include containing more Includes.)

TYPE: bool DEFAULT: True

deprecated

Boolean flag for indicating the deprecation of the Include and all of its routes and to display it in the OpenAPI documentation..

TYPE: Optional[bool] DEFAULT: None

security

Used by OpenAPI definition, the security must be compliant with the norms. Esmerald offers some out of the box solutions where this is implemented.

The Esmerald security is available to automatically used.

The security can be applied also on a level basis.

For custom security objects, you must subclass esmerald.openapi.security.base.HTTPBase object.

TYPE: Optional[Sequence[SecurityScheme]] DEFAULT: None

tags

A list of strings tags to be applied to the path operation.

It will be added to the generated OpenAPI documentation.

Note almost everything in Esmerald can be done in levels, which means these tags on a Esmerald instance, means it will be added to every route even if those routes also contain tags.

TYPE: Optional[Sequence[str]] DEFAULT: None

Source code in esmerald/routing/router.py
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
def __init__(
    self,
    path: Annotated[
        Optional[str],
        Doc(
            """
            Relative path of the `Include`.
            The path can contain parameters in a dictionary like format
            and if the path is not provided, it will default to `/`.

            **Example**

            ```python
            Include()
            ```

            **Example with parameters**

            ```python
            Include(path="/{age: int}")
            ```
            """
        ),
    ] = None,
    app: Annotated[
        ASGIApp | str,
        Doc(
            """
            An application can be anything that is treated as an ASGI application.
            For example, it can be a [ChildEsmerald](https://esmerald.dev/routing/router/#child-esmerald-application), another `Esmerald`, a [Router](https://esmerald.dev/routing/router/#router-class) or even an external [WSGI application](https://esmerald.dev/wsgi/) (Django, Flask...)

            The app is a parameter that makes the Include extremely powerful when it comes
            to integrate with ease with whatever Python stack you want and need.

            **Example**

            ```python
            from esmerald import Esmerald, ChildEsmerald, Include

            Esmerald(
                routes=[
                    Include('/child', app=ChildEsmerald(...))
                ]
            )
            ```

            **Example with a WSGI framework**

            ```python
            from flask import Flask, escape, request

            from esmerald import Esmerald, Gateway, Include, Request, get
            from esmerald.middleware.wsgi import WSGIMiddleware

            flask_app = Flask(__name__)


            @flask_app.route("/")
            def flask_main():
                name = request.args.get("name", "Esmerald")
                return f"Hello, {escape(name)} from your Flask integrated!"


            @get("/home/{name:str}")
            async def home(request: Request) -> dict:
                name = request.path_params["name"]
                return {"name": escape(name)}


            app = Esmerald(
                routes=[
                    Gateway(handler=home),
                    Include("/flask", WSGIMiddleware(flask_app)),
                ]
            )
            ```

            """
        ),
    ] = None,
    name: Annotated[
        Optional[str],
        Doc(
            """
            The name for the Gateway. The name can be reversed by `path_for()`.
            """
        ),
    ] = None,
    routes: Annotated[
        Optional[Sequence[Union[APIGateHandler, Include, HTTPHandler, WebSocketHandler]]],
        Doc(
            """
            A global `list` of esmerald routes. Those routes may vary and those can
            be `Gateway`, `WebSocketGateWay` or even another `Include`.

            This is also an entry-point for the routes of the Include
            but it **does not rely on only one [level](https://esmerald.dev/application/levels/)**.

            Read more about how to use and leverage
            the [Esmerald routing system](https://esmerald.dev/routing/routes/).

            **Example**

            ```python
            from esmerald import Esmerald, Gateway, Request, get, Include


            @get()
            async def homepage(request: Request) -> str:
                return "Hello, home!"


            @get()
            async def another(request: Request) -> str:
                return "Hello, another!"

            app = Esmerald(
                routes=[
                    Gateway(handler=homepage)
                    Include("/nested", routes=[
                        Gateway(handler=another)
                    ])
                ]
            )
            ```

            !!! Note
                The Include is very powerful and this example
                is not enough to understand what more things you can do.
                Read in [more detail](https://esmerald.dev/routing/routes/#include) about this.
            """
        ),
    ] = None,
    namespace: Annotated[
        Optional[str],
        Doc(
            """
            A string with a qualified namespace from where the URLs should be loaded.

            The namespace is an alternative to `routes` parameter. When a `namespace` is
            specified and a routes as well, an `ImproperlyCOnfigured` exception is raised as
            it can only be one or another.

            The `namespace` can be extremely useful as it avoids the imports from the top
            of the file that can lead to `partially imported` errors.

            When using a `namespace`, the `Include` will look for the default `route_patterns` list in the imported namespace (object) unless a different `pattern` is specified.

            **Example**

            Assuming there is a file with some routes located at `myapp/auth/urls.py`.

            ```python title="myapp/auth/urls.py"
            from esmerald import Gateway
            from .view import welcome, create_user

            route_patterns = [
                Gateway(handler=welcome, name="welcome"),
                Gateway(handler=create_user, name="create-user"),
            ]
            ```

            Using the `namespace` to import the URLs.

            ```python
            from esmerald import Include

            Include("/auth", namespace="myapp.auth.urls")
            ```
            """
        ),
    ] = None,
    pattern: Annotated[
        Optional[str],
        Doc(
            """
            A string `pattern` information from where the urls shall be read from.

            By default, the when using the `namespace` it will lookup for a `route_patterns`
            but somethimes you might want to opt for a different name and this is where the
            `pattern` comes along.

            **Example**

            Assuming there is a file with some routes located at `myapp/auth/urls.py`.
            The urls will be placed inside a `urls` list.

            ```python title="myapp/auth/urls.py"
            from esmerald import Gateway
            from .view import welcome, create_user

            urls = [
                Gateway(handler=welcome, name="welcome"),
                Gateway(handler=create_user, name="create-user"),
            ]
            ```

            Using the `namespace` to import the URLs.

            ```python
            from esmerald import Include

            Include("/auth", namespace="myapp.auth.urls", pattern="urls")
            ```
            """
        ),
    ] = None,
    parent: Annotated[
        Optional[ParentType],
        Doc(
            """
            Who owns the Gateway. If not specified, the application automatically it assign it.

            This is directly related with the [application levels](https://esmerald.dev/application/levels/).
            """
        ),
    ] = None,
    dependencies: Annotated[
        Optional[Dependencies],
        Doc(
            """
            A dictionary of string and [Inject](https://esmerald.dev/dependencies/) instances enable application level dependency injection.
            """
        ),
    ] = None,
    interceptors: Annotated[
        Optional[Sequence[Interceptor]],
        Doc(
            """
            A list of [interceptors](https://esmerald.dev/interceptors/) to serve the application incoming requests (HTTP and Websockets).
            """
        ),
    ] = None,
    permissions: Annotated[
        Optional[Sequence[Permission]],
        Doc(
            """
            A list of [permissions](https://esmerald.dev/permissions/) to serve the application incoming requests (HTTP and Websockets).
            """
        ),
    ] = None,
    exception_handlers: Annotated[
        Optional[ExceptionHandlerMap],
        Doc(
            """
            A dictionary of [exception types](https://esmerald.dev/exceptions/) (or custom exceptions) and the handler functions on an application top level. Exception handler callables should be of the form of `handler(request, exc) -> response` and may be be either standard functions, or async functions.
            """
        ),
    ] = None,
    middleware: Annotated[
        Optional[List[Middleware]],
        Doc(
            """
            A list of middleware to run for every request. The middlewares of an Include will be checked from top-down or [Lilya Middleware](https://www.lilya.dev/middleware/) as they are both converted internally. Read more about [Python Protocols](https://peps.python.org/pep-0544/).
            """
        ),
    ] = None,
    include_in_schema: Annotated[
        bool,
        Doc(
            """
            Boolean flag indicating if it should be added to the OpenAPI docs.

            This will add all the routes of the Include even those nested (Include containing more Includes.)
            """
        ),
    ] = True,
    deprecated: Annotated[
        Optional[bool],
        Doc(
            """
            Boolean flag for indicating the deprecation of the Include and all of its routes and to display it in the OpenAPI documentation..
            """
        ),
    ] = None,
    security: Annotated[
        Optional[Sequence[SecurityScheme]],
        Doc(
            """
            Used by OpenAPI definition, the security must be compliant with the norms.
            Esmerald offers some out of the box solutions where this is implemented.

            The [Esmerald security](https://esmerald.dev/openapi/) is available to automatically used.

            The security can be applied also on a [level basis](https://esmerald.dev/application/levels/).

            For custom security objects, you **must** subclass
            `esmerald.openapi.security.base.HTTPBase` object.
            """
        ),
    ] = None,
    tags: Annotated[
        Optional[Sequence[str]],
        Doc(
            """
            A list of strings tags to be applied to the *path operation*.

            It will be added to the generated OpenAPI documentation.

            **Note** almost everything in Esmerald can be done in [levels](https://esmerald.dev/application/levels/), which means
            these tags on a Esmerald instance, means it will be added to every route even
            if those routes also contain tags.
            """
        ),
    ] = None,
) -> None:
    self.path = path
    if not path:
        self.path = "/"

    if namespace and routes:
        raise ImproperlyConfigured("It can only be namespace or routes, not both.")

    if namespace and not isinstance(namespace, str):
        raise ImproperlyConfigured("Namespace must be a string. Example: 'myapp.routes'.")

    if pattern and not isinstance(pattern, str):
        raise ImproperlyConfigured("Pattern must be a string. Example: 'route_patterns'.")

    if pattern and routes:
        raise ImproperlyConfigured("Pattern must be used only with namespace.")

    if namespace:
        routes = include(namespace, pattern)

    # Add the middleware to the include
    self.middleware = middleware or []
    include_middleware: Sequence[Middleware] = []

    for _middleware in self.middleware:
        if isinstance(_middleware, DefineMiddleware):  # pragma: no cover
            include_middleware.append(_middleware)
        else:
            include_middleware.append(  # type: ignore
                DefineMiddleware(cast("Type[DefineMiddleware]", _middleware))
            )

    if isinstance(app, str):
        app = import_string(app)

    self.app = self.resolve_app_parent(app=app)

    self.dependencies = dependencies or {}
    self.interceptors: Sequence[Interceptor] = interceptors or []
    self.permissions: Sequence[Permission] = permissions or []  # type: ignore
    self.response_class = None
    self.response_cookies = None
    self.response_headers = None
    self.parent = parent
    self.security = security or []
    self.tags = tags or []

    if namespace:
        routes = include(namespace, pattern)

    if routes:
        routes = self.resolve_route_path_handler(routes)

    super().__init__(
        path=self.path,
        app=self.app,
        routes=routes,
        name=name,
        middleware=include_middleware,
        exception_handlers=exception_handlers,
        deprecated=deprecated,
        include_in_schema=include_in_schema,
    )

path instance-attribute

path = path

app instance-attribute

app = resolve_app_parent(app=app)

name instance-attribute

name = name

routes property

routes

Returns a list of declared path objects.

parent instance-attribute

parent = parent

dependencies instance-attribute

dependencies = dependencies or {}

exception_handlers instance-attribute

exception_handlers = {} if exception_handlers is None else dict(exception_handlers)

interceptors instance-attribute

interceptors = interceptors or []

permissions instance-attribute

permissions = permissions or []

middleware instance-attribute

middleware = middleware or []

include_in_schema instance-attribute

include_in_schema = include_in_schema

deprecated instance-attribute

deprecated = deprecated

security instance-attribute

security = security or []

tags instance-attribute

tags = tags or []