Skip to content

Esmerald class

This is the reference for the main object Esmerald that contains all the parameters, attributes and functions.

How to import

from esmerald import Esmerald

esmerald.Esmerald

Esmerald(*, settings_module=None, debug=None, app_name=None, title=None, version=None, summary=None, description=None, contact=None, terms_of_service=None, license=None, security=None, servers=None, secret_key=None, allowed_hosts=None, allow_origins=None, permissions=None, interceptors=None, dependencies=None, csrf_config=None, openapi_config=None, openapi_version=None, cors_config=None, static_files_config=None, template_config=None, session_config=None, response_class=None, response_cookies=None, response_headers=None, scheduler_class=None, scheduler_tasks=None, scheduler_configurations=None, enable_scheduler=None, timezone=None, routes=None, root_path=None, middleware=None, exception_handlers=None, on_startup=None, on_shutdown=None, lifespan=None, tags=None, include_in_schema=None, deprecated=None, enable_openapi=None, redirect_slashes=None, pluggables=None, parent=None, root_path_in_servers=None, webhooks=None, openapi_url=None)

Bases: Lilya

Esmerald application object. The main entry-point for any application/API with Esmerald.

This object is complex and very powerful. Read more in detail about how to start and spin-up an application in minutes.

Tip

All the parameters available in the object have defaults being loaded by the settings system if nothing is provided.

Note: More details about the defaults in the settings reference.

Example

from esmerald import Esmerald.

app = Esmerald()
PARAMETER DESCRIPTION
settings_module

Alternative settings parameter. This parameter is an alternative to ESMERALD_SETTINGS_MODULE way of loading your settings into an Esmerald application.

When the settings_module is provided, it will make sure it takes priority over any other settings provided for the instance.

Read more about the settings module and how you can leverage it in your application.

Tip

The settings module can be very useful if you want to have, for example, a ChildEsmerald that needs completely different settings from the main app.

Example: A ChildEsmerald that takes care of the authentication into a cloud provider such as AWS and handles the boto3 module.

TYPE: Optional[SettingsType] DEFAULT: None

debug

Boolean indicating if the application should return the debug tracebacks on server errors, in other words, if you want to have debug errors being displayed.

Read more about this in the official Lilya documentation.

Tip

Do not use this in production.

Example

from esmerald import Esmerald

app = Esmerald(debug=True)

TYPE: Optional[bool] DEFAULT: None

app_name

The name of the Esmerald application/API. This name is displayed when the OpenAPI documentation is used.

Example

from esmerald import Esmerald

app = Esmerald(app_name="Esmerald")

TYPE: Optional[str] DEFAULT: None

title

The title of the Esmerald application/API. This title is displayed when the OpenAPI documentation is used.

Example

from esmerald import Esmerald

app = Esmerald(title="My awesome Esmerald application")

TYPE: Optional[str] DEFAULT: None

version

The version of the Esmerald application/API. This version is displayed when the OpenAPI documentation is used.

Note: This is the version of your application/API and not th version of the OpenAPI specification being used by Esmerald.

Example

from esmerald import Esmerald

app = Esmerald(version="0.1.0")

TYPE: Optional[str] DEFAULT: None

summary

The summary of the Esmerald application/API. This short summary is displayed when the OpenAPI documentation is used.

Example

from esmerald import Esmerald

app = Esmerald(summary="Black Window joins The Pretenders.")

TYPE: Optional[str] DEFAULT: None

description

The description of the Esmerald application/API. This description is displayed when the OpenAPI documentation is used.

Example

from esmerald import Esmerald

app = Esmerald(
    description='''
                Black Window joins The Pretenders.

                ## Powers

                You can **activate_powers**

                ## Skills

                * **read_skill**
                * **use_skill**
                '''
)

TYPE: Optional[str] DEFAULT: None

contact

A dictionary or an object of type openapi_schemas_pydantic.v3_1_0.Contact containing the contact information of the application/API.

Both dictionary and object contain several fields.

  • name - String name of the contact.
  • url - String URL of the contact. It must be in the format of a URL.
  • email - String email address of the contact. It must be in the format of an email address.

Example with object

from esmerald import Esmerald
from openapi_schemas_pydantic.v3_1_0 import Contact

contact = Contact(
    name="Black Window",
    url="https://thepretenders.com/open-for-business",
    email="black.window@thepretenders.com,
)

app = Esmerald(contact=contact)

Example with dictionary

from esmerald import Esmerald

app = Esmerald(contact={
    "name": "Black Window",
    "url": "https://thepretenders.com/open-for-business",
    "email": "black.window@thepretenders.com,
})

TYPE: Optional[Contact] DEFAULT: None

terms_of_service

A URL pointing to the Terms of Service of the application. This description is displayed when the OpenAPI documentation is used.

Example

from esmerald import Esmerald

app = Esmerald(terms_of_service="https://example.com/terms-of-service")

TYPE: Optional[AnyUrl] DEFAULT: None

license

A dictionary or an object of type openapi_schemas_pydantic.v3_1_0.License containing the license information of the application/API.

Both dictionary and object contain several fields.

  • name - String name of the license.
  • identifier - An SPDX license expression.
  • url - String URL of the contact. It must be in the format of a URL.

Example with object

from esmerald import Esmerald
from openapi_schemas_pydantic.v3_1_0 import License

license = License(
    name="MIT",
    url="https://opensource.org/license/mit/",
)

app = Esmerald(license=license)

Example with dictionary

from esmerald import Esmerald

app = Esmerald(license={
    "name": "MIT",
    "url": "https://opensource.org/license/mit/",
})

TYPE: Optional[License] 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.

Example

from esmerald import Esmerald
from esmerald.openapi.security.http import Bearer

app = Esmerald(security=[Bearer()])

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

servers

A list of python dictionaries with the information regarding the connectivity to the target.

This can be useful, for example, if your application is served from different domains and you want a shared OpenAPI documentation to test it all.

Esmerald automatically handles the OpenAPI documentation generation for you but sometimes you might want to add an extra custom domain to it.

For example, when using ChildEsmerald modules, since the object itself subclasses Esmerald, that also means you can have independent documentation directly in the ChildEsmerald or access the top level documentation (the application itself) where you can select the server to test it.

If the servers list is not provided or an is an empty list, the default value will be a dict with the url pointing to /.

Each dict of the list follows the following format for the parameters:

  • url - A URL string to the target host/domain. The URL may support server variables and it may be also a relative server (for example, the domain/path of a ChildEsmerald).
  • description - An optional string description of the host/domain.
  • variables - A dictionary between the variable and its value. The value is used for substitution in the servers URL template. E.g.: /my-domain/{age: int}.

You can read more about how the OpenAPI documentation is used.

Example

from esmerald import Esmerald

app = Esmerald(
    servers=[
        {"url": "https://testing.example.com", "description": "Testing environment"},
        {"url": "https://uat.example.com", "description": "UAT environment"},
        {"url": "https://live.example.com", "description": "Production environment"},
    ]
)

TYPE: Optional[List[Dict[str, Union[str, Any]]]] DEFAULT: None

secret_key

A unique string value used for the cryptography. This value is also used internally by Esmerald with the JWT as well the CSRFConfig.

Tip

Make sure you do not reuse the same secret key across environments as this can lead to security issues that you can easily avoid.

Example

from esmerald import Esmerald

aop = Esmerald(
    secret_key="p7!3cq1rapxd!@l=gz-&&k*h8sk_n8#1#+n6&q@cb&r!^z^2!g"
)

TYPE: Union[Optional[str], Optional[Secret]] DEFAULT: None

allowed_hosts

A list of allowed hosts for the application. The allowed hosts when not specified defaults to ["*"] but when specified.

The allowed hosts are also what controls the TrustedHostMiddleware and you can read more about how to use it.

Example

from esmerald import Esmerald

app = Esmerald(
    allowed_hosts=["*.example.com", "www.foobar.com"]
)

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

allow_origins

A list of allowed origins hosts for the application.

The allowed origins is used by the CORSConfig and controls the CORSMiddleware.

Example

from esmerald import Esmerald

app = Esmerald(allow_origins=["*"])

Tip

If you create your own CORSConfig, this setting is ignored and your custom config takes priority.

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

permissions

A list of global permissions from objects inheriting from esmerald.permissions.BasePermission.

Read more about how to implement the Permissions in Esmerald and to leverage them.

Note almost everything in Esmerald can be done in levels, which means these permissions on a Esmerald instance, means the whole application.

Example

from esmerald import Esmerald, BasePermission, Request
from esmerald.types import APIGateHandler


class IsAdmin(BasePermission):
    '''
    Permissions for admin
    '''
    async def has_permission(self, request: "Request", apiview: "APIGateHandler"):
        is_admin = request.headers.get("admin", False)
        return bool(is_admin)


app = Esmerald(permissions=[IsAdmin])

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

interceptors

A list of global interceptors from objects inheriting from esmerald.interceptors.interceptor.EsmeraldInterceptor.

Read more about how to implement the Interceptors in Esmerald and to leverage them.

Note almost everything in Esmerald can be done in levels, which means these interceptors on a Esmerald instance, means the whole application.

Example

from loguru import logger
from lilya.types import Receive, Scope, Send

from esmerald import Esmerald
from esmerald import EsmeraldInterceptor


class LoggingInterceptor(EsmeraldInterceptor):
    async def intercept(self, scope: "Scope", receive: "Receive", send: "Send") -> None:
        # Log a message here
        logger.info("This is my interceptor being called before reaching the handler.")


app = Esmerald(interceptors=[LoggingInterceptor])

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

dependencies

A dictionary of global dependencies. These dependencies will be applied to each path of the application.

Read more about Dependencies.

Example

from esmerald import Esmerald, Inject

def is_valid(number: int) -> bool:
    return number >= 5

app = Esmerald(
    dependencies={
        "is_valid": Inject(is_valid)
    }
)

TYPE: Optional[Dependencies] DEFAULT: None

csrf_config

An instance of CRSFConfig.

This configuration is passed to the CSRFMiddleware and enables the middleware.

Tip

You can creatye your own CRSFMiddleware version and pass your own configurations. You don't need to use the built-in version although it is recommended to do it so.

Example

from esmerald import Esmerald
from esmerald.config import CSRFConfig

csrf_config = CSRFConfig(secret="your-long-unique-secret")

app = Esmerald(csrf_config=csrf_config)

TYPE: Optional[CSRFConfig] DEFAULT: None

openapi_config

An instance of OpenAPIConfig.

This object is then used by Esmerald to create the OpenAPI documentation.

Note: Here is where the defaults for Esmerald OpenAPI are overriden and if this object is passed, then the previous defaults of the settings are ignored.

Tip

This is the way you could override the defaults all in one go instead of doing attribute by attribute.

Example

from esmerald import OpenAPIConfig

openapi_config = OpenAPIConfig(
    title="Black Window",
    openapi_url="/openapi.json",
    docs_url="/docs/swagger",
    redoc_url="/docs/redoc",
)

app = Esmerald(openapi_config=openapi_config)

TYPE: Optional[OpenAPIConfig] DEFAULT: None

openapi_version

The string version of the OpenAPI.

Esmerald will generate the OpenAPI 3.1.0 by default and will output that as the OpenAPI version.

If you need to somehow trick some of the tools you are using by setting a different version of the OpenAPI, this is the field you can use to do it so.

Example

from esmerald import Esmerald

app = Esmerald(openapi_version="3.1.0")

TYPE: Optional[str] DEFAULT: None

cors_config

An instance of CORSConfig.

This configuration is passed to the CORSMiddleware and enables the middleware.

Example

from esmerald import Esmerald
from esmerald.config import CSRFConfig

cors_config = CORSConfig(allow_origins=["*"])

app = Esmerald(cors_config=cors_config)

TYPE: Optional[CORSConfig] DEFAULT: None

static_files_config

An instance of StaticFilesConfig.

This configuration is used to enable and serve static files via Esmerald application.

Example

from esmerald import Esmerald
from esmerald.config import StaticFilesConfig

static_files_config = StaticFilesConfig(
    path="/static", directory=Path("static")
)

app = Esmerald(static_files_config=static_files_config)

TYPE: Optional[StaticFilesConfig] DEFAULT: None

template_config

An instance of TemplateConfig.

This configuration is a simple set of configurations that when passed enables the template engine.

Note

You might need to install the template engine before using this. You can always run pip install esmerald[templates] to help you out.

Example

from esmerald import Esmerald
from esmerald.config.template import TemplateConfig
from esmerald.template.jinja import JinjaTemplateEngine

template_config = TemplateConfig(
    directory=Path("templates"),
    engine=JinjaTemplateEngine,
)

app = Esmerald(template_config=template_config)

TYPE: Optional[TemplateConfig] DEFAULT: None

session_config

An instance of SessionConfig.

This configuration is passed to the SessionMiddleware and enables the middleware.

Example

from esmerald import Esmerald
from esmerald.config import SessionConfig

session_config = SessionConfig(
    secret_key=settings.secret_key,
    session_cookie="session",
)

app = Esmerald(session_config=session_config)

TYPE: Optional[SessionConfig] DEFAULT: None

response_class

Global default response class to be used within the Esmerald application.

Read more about the Responses and how to use them.

Example

from esmerald import Esmerald, JSONResponse

app = Esmerald(response_class=JSONResponse)

TYPE: Optional[ResponseType] DEFAULT: None

response_cookies

A global sequence of esmerald.datastructures.Cookie objects.

Read more about the Cookies.

Example

from esmerald import Esmerald
from esmerald.datastructures import Cookie

response_cookies=[
    Cookie(
        key="csrf",
        value="CIwNZNlR4XbisJF39I8yWnWX9wX4WFoz",
        max_age=3000,
        httponly=True,
    )
]

app = Esmerald(response_cookies=response_cookies)

TYPE: Optional[ResponseCookies] DEFAULT: None

response_headers

A global mapping of esmerald.datastructures.ResponseHeader objects.

Read more about the ResponseHeader.

Example

from esmerald import Esmerald
from esmerald.datastructures import ResponseHeader

response_headers={
    "authorize": ResponseHeader(value="granted")
}

app = Esmerald(response_headers=response_headers)

TYPE: Optional[ResponseHeaders] DEFAULT: None

scheduler_class

Esmerald integrates out of the box with Asyncz and the scheduler class is nothing more than the AsyncIOScheduler provided by the library.

Read more about the scheduler and how to use.

Tip

You can create your own scheduler class and use it with Esmerald. For that you must read the Asyncz documentation and how to make it happen.

Note - To enable the scheduler, you must set the enable_scheduler=True.

Example

from esmerald import Esmerald
from asyncz.schedulers import AsyncIOScheduler

app = Esmerald(scheduler_class=AsyncIOScheduler)

TYPE: Optional[SchedulerType] DEFAULT: None

scheduler_tasks

Mapping in the format <task-name>: <location> indicating the tasks to be run by the scheduler.

Read more about the scheduler and how to use.

Note - To enable the scheduler, you must set the enable_scheduler=True.

Example

from esmerald import Esmerald

app = Esmerald(
    enable_scheduler=True,
    scheduler_tasks={
        "collect_market_data": "accounts.tasks",
        "send_email_newsletter": "accounts.tasks",
    },
)

TYPE: Optional[Dict[str, str]] DEFAULT: None

scheduler_configurations

Mapping of extra configuratioms being passed to the scheduler. These are Asyncz Configurations.

Example

from esmerald import Esmerald

configurations = {
    "asyncz.stores.mongo": {"type": "mongodb"},
    "asyncz.stores.default": {"type": "redis", "database": "0"},
    "asyncz.executors.threadpool": {
        "max_workers": "20",
        "class": "asyncz.executors.threadpool:ThreadPoolExecutor",
    },
    "asyncz.executors.default": {"class": "asyncz.executors.asyncio::AsyncIOExecutor"},
    "asyncz.task_defaults.coalesce": "false",
    "asyncz.task_defaults.max_instances": "3",
    "asyncz.task_defaults.timezone": "UTC",
}

app = Esmerald(
    scheduler_configurations=configurations
)

TYPE: Optional[Dict[str, Union[str, Dict[str, str]]]] DEFAULT: None

enable_scheduler

Boolean flag indicating if the internal scheduler should be enabled or not.

Example

from esmerald import Esmerald

app = Esmerald(enable_scheduler=True)

TYPE: Optional[bool] DEFAULT: None

timezone

Object of time datetime.timezone or string indicating the timezone for the application.

Note - The timezone is internally used for the supported scheduler.

Example

from esmerald import Esmerald

app = Esmerald(timezone="UTC")

TYPE: Optional[Union[timezone, str]] DEFAULT: None

routes

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

This is also the entry-point for the routes of the application itself 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 routing system 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]]] DEFAULT: None

root_path

A path prefix that is handled by a proxy not seen in the application but seen by external libraries.

This affects the tools like the OpenAPI documentation.

**Example^^

from esmerald import Esmerald

app = Esmerald(root_path="/api/v3")

TYPE: Optional[str] DEFAULT: None

middleware

A global sequence of Lilya middlewares or esmerald.middlewares that are used by the application.

Read more about the Middleware.

Example

from esmerald import Esmerald
from esmerald.middleware import HTTPSRedirectMiddleware, TrustedHostMiddleware

app = Esmerald(
    routes=[...],
    middleware=[
        DefineMiddleware(TrustedHostMiddleware, allowed_hosts=["example.com", "*.example.com"]),
        DefineMiddleware(HTTPSRedirectMiddleware),
    ],
)

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

exception_handlers

A global dictionary with handlers for exceptions.

Note almost everything in Esmerald can be done in levels, which means these exception handlers on a Esmerald instance, means the whole application.

Read more about the Exception handlers.

Example

from pydantic.error_wrappers import ValidationError
from esmerald import (
    Esmerald,
    JSONResponse,
    Request,
    ValidationErrorException,
)

async def validation_error_exception_handler(
    request: Request, exc: ValidationError
) -> JSONResponse:
    extra = getattr(exc, "extra", None)
    if extra:
        return JSONResponse(
            {"detail": exc.detail, "errors": exc.extra.get("extra", {})},
            status_code=status.HTTP_400_BAD_REQUEST,
        )
    else:
        return JSONResponse(
            {"detail": exc.detail},
            status_code=status.HTTP_400_BAD_REQUEST,
        )

app = Esmerald(
    exception_handlers={
            ValidationErrorException: validation_error_exception_handler,
        },
)

TYPE: Optional[ExceptionHandlerMap] DEFAULT: None

on_startup

A list of events that are trigger upon the application starts.

Read more about the events.

Example

from pydantic import BaseModel
from saffier import Database, Registry

from esmerald import Esmerald, Gateway, post

database = Database("postgresql+asyncpg://user:password@host:port/database")
registry = Registry(database=database)


class User(BaseModel):
    name: str
    email: str
    password: str
    retype_password: str


@post("/create", tags=["user"], description="Creates a new user in the database")
async def create_user(data: User) -> None:
    # Logic to create the user
    ...


app = Esmerald(
    routes=[Gateway(handler=create_user)],
    on_startup=[database.connect],
)

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

on_shutdown

A list of events that are trigger upon the application shuts down.

Read more about the events.

Example

from pydantic import BaseModel
from saffier import Database, Registry

from esmerald import Esmerald, Gateway, post

database = Database("postgresql+asyncpg://user:password@host:port/database")
registry = Registry(database=database)


class User(BaseModel):
    name: str
    email: str
    password: str
    retype_password: str


@post("/create", tags=["user"], description="Creates a new user in the database")
async def create_user(data: User) -> None:
    # Logic to create the user
    ...


app = Esmerald(
    routes=[Gateway(handler=create_user)],
    on_shutdown=[database.disconnect],
)

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

lifespan

A lifespan context manager handler. This is an alternative to on_startup and on_shutdown and you cannot used all combined.

Read more about the lifespan.

TYPE: Optional[Lifespan[AppType]] 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.

Example

from esmerald import Esmerald

app = Esmerald(tags=["application"])

Example with nested routes

When tags are added on a level bases, those are concatenated into the final handler.

from esmerald import Esmerald, Gateway, get

@get("/home", tags=["home"])
async def home() -> Dict[str, str]:
    return {"hello": "world"}


app = Esmerald(
    routes=[Gateway(handler=home)],
    tags=["application"]
)

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

include_in_schema

Boolean flag indicating if all the routes of the application should be included in the OpenAPI documentation.

Note almost everything in Esmerald can be done in levels, which means when the application level is set to include_in_schema=False, no schemas will be displayed in the OpenAPI documentation.

Tip

This can be particularly useful if you have, for example, a ChildEsmerald and you don't want to include in the schema the routes of the said ChildEsmerald. This way there is no reason to do it route by route and instead you can simply do it directly in the application level.

Example

from esmerald import Esmerald

app = Esmerald(include_in_schema=False)

Example applied to ChildEsmerald

from esmerald import Esmerald, ChildEsmerald, Include

app = Esmerald(routes=[
    Include("/child", app=ChildEsmerald(
        include_in_schema=False
    ))
])

TYPE: Optional[bool] DEFAULT: None

deprecated

Boolean flag indicating if all the routes of the application should be deprecated in the OpenAPI documentation.

Tip

This can be particularly useful if you have, for example, a ChildEsmerald and you want to deprecate in favour of a new one being implemented.

Example

from esmerald import Esmerald

app = Esmerald(deprecated=True)

Example with a ChildEsmerald

from esmerald import Esmerald, ChildEsmerald, Include

app = Esmerald(routes=[
    Include("/child", app=ChildEsmerald(
        deprecated=True
    ))
])

TYPE: Optional[bool] DEFAULT: None

enable_openapi

Boolean flag indicating if the OpenAPI documentation should be generated or not.

When False, no OpenAPI documentation is accessible.

Tip

Disable this option if you run in production and no one should access the documentation unless behind an authentication.

```

TYPE: Optional[bool] DEFAULT: None

redirect_slashes

Boolean flag indicating if the redirect slashes are enabled for the routes or not.

TYPE: Optional[bool] DEFAULT: None

pluggables

A list of global pluggables from objects inheriting from esmerald.interceptors.interceptor.EsmeraldInterceptor.

Read more about how to implement the Plugables in Esmerald and to leverage them.

Example

from typing import Optional

from loguru import logger
from pydantic import BaseModel

from esmerald import Esmerald, Extension, Pluggable
from esmerald.types import DictAny


class PluggableConfig(BaseModel):
    name: str


class MyExtension(Extension):
    def __init__(
        self, app: Optional["Esmerald"] = None, config: PluggableConfig = None, **kwargs: "DictAny"
    ):
        super().__init__(app, **kwargs)
        self.app = app

    def extend(self, config: PluggableConfig) -> None:
        logger.success(f"Successfully passed a config {config.name}")


my_config = PluggableConfig(name="my extension")
pluggable = Pluggable(MyExtension, config=my_config)


app = Esmerald(
    routes=[], pluggables={"my-extension": pluggable}
)

TYPE: Optional[Dict[str, Pluggable]] DEFAULT: None

parent

Used internally by Esmerald to recognise and build the application levels.

Tip

Unless you know what are you doing, it is advisable not to touch this.

TYPE: Optional[Union[ParentType, Esmerald, ChildEsmerald]] DEFAULT: None

root_path_in_servers

Boolean flag use to disable the automatic URL generation in the servers field in the OpenAPI documentation.

Examples

from esmerald import Esmerald

app = Esmerald(root_path_in_servers=False)

TYPE: bool DEFAULT: None

webhooks

This is the same principle of the routes but for OpenAPI webhooks.

Read more about webhooks.

When a webhook is added, it will automatically add them into the OpenAPI documentation.

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

openapi_url

The URL where the OpenAPI schema will be served from. The default is /openapi.json.

Example

from esmerald import Esmerald

app = Esmerald(openapi_url="/api/v1/openapi.json")

TYPE: Optional[str] DEFAULT: None

Source code in esmerald/applications.py
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
def __init__(
    self: AppType,
    *,
    settings_module: Annotated[
        Optional["SettingsType"],
        Doc(
            """
            Alternative settings parameter. This parameter is an alternative to
            `ESMERALD_SETTINGS_MODULE` way of loading your settings into an Esmerald application.

            When the `settings_module` is provided, it will make sure it takes priority over
            any other settings provided for the instance.

            Read more about the [settings module](https://esmerald.dev/application/settings/)
            and how you can leverage it in your application.

            !!! Tip
                The settings module can be very useful if you want to have, for example, a
                [ChildEsmerald](https://esmerald.dev/routing/router/?h=childe#child-esmerald-application) that needs completely different settings
                from the main app.

                Example: A `ChildEsmerald` that takes care of the authentication into a cloud
                provider such as AWS and handles the `boto3` module.
            """
        ),
    ] = None,
    debug: Annotated[
        Optional[bool],
        Doc(
            """
            Boolean indicating if the application should return the debug tracebacks on
            server errors, in other words, if you want to have debug errors being displayed.

            Read more about this in the official [Lilya documentation](https://www.lilya.dev/applications/#applications).

            !!! Tip
                Do not use this in production.

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(debug=True)
            ```
            """
        ),
    ] = None,
    app_name: Annotated[
        Optional[str],
        Doc(
            """
            The name of the Esmerald application/API. This name is displayed when the
            [OpenAPI](https://esmerald.dev/openapi/) documentation is used.

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(app_name="Esmerald")
            ```
            """
        ),
    ] = None,
    title: Annotated[
        Optional[str],
        Doc(
            """
            The title of the Esmerald application/API. This title is displayed when the
            [OpenAPI](https://esmerald.dev/openapi/) documentation is used.

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(title="My awesome Esmerald application")
            ```
            """
        ),
    ] = None,
    version: Annotated[
        Optional[str],
        Doc(
            """
            The version of the Esmerald application/API. This version is displayed when the
            [OpenAPI](https://esmerald.dev/openapi/) documentation is used.

            **Note**: This is the version of your application/API and not th version of the
            OpenAPI specification being used by Esmerald.

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(version="0.1.0")
            ```
            """
        ),
    ] = None,
    summary: Annotated[
        Optional[str],
        Doc(
            """
            The summary of the Esmerald application/API. This short summary is displayed when the [OpenAPI](https://esmerald.dev/openapi/) documentation is used.

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(summary="Black Window joins The Pretenders.")
            ```
            """
        ),
    ] = None,
    description: Annotated[
        Optional[str],
        Doc(
            """
            The description of the Esmerald application/API. This description is displayed when the [OpenAPI](https://esmerald.dev/openapi/) documentation is used.

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(
                description='''
                            Black Window joins The Pretenders.

                            ## Powers

                            You can **activate_powers**

                            ## Skills

                            * **read_skill**
                            * **use_skill**
                            '''
            )
            ```
            """
        ),
    ] = None,
    contact: Annotated[
        Optional[Contact],
        Doc(
            """
            A dictionary or an object of type `openapi_schemas_pydantic.v3_1_0.Contact` containing the contact information of the application/API.

            Both dictionary and object contain several fields.

            * **name** - String name of the contact.
            * **url** - String URL of the contact. It **must** be in the format of a URL.
            * **email** - String email address of the contact. It **must** be in the format
            of an email address.

            **Example with object**

            ```python
            from esmerald import Esmerald
            from openapi_schemas_pydantic.v3_1_0 import Contact

            contact = Contact(
                name="Black Window",
                url="https://thepretenders.com/open-for-business",
                email="black.window@thepretenders.com,
            )

            app = Esmerald(contact=contact)
            ```

            **Example with dictionary**

            ```python
            from esmerald import Esmerald

            app = Esmerald(contact={
                "name": "Black Window",
                "url": "https://thepretenders.com/open-for-business",
                "email": "black.window@thepretenders.com,
            })
            ```
            """
        ),
    ] = None,
    terms_of_service: Annotated[
        Optional[AnyUrl],
        Doc(
            """
            A URL pointing to the Terms of Service of the application.
            This description is displayed when the [OpenAPI](https://esmerald.dev/openapi/) documentation is used.

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(terms_of_service="https://example.com/terms-of-service")
            ```
            """
        ),
    ] = None,
    license: Annotated[
        Optional[License],
        Doc(
            """
            A dictionary or an object of type `openapi_schemas_pydantic.v3_1_0.License` containing the license information of the application/API.

            Both dictionary and object contain several fields.

            * **name** - String name of the license.
            * **identifier** - An [SPDX](https://spdx.dev/) license expression.
            * **url** - String URL of the contact. It **must** be in the format of a URL.

            **Example with object**

            ```python
            from esmerald import Esmerald
            from openapi_schemas_pydantic.v3_1_0 import License

            license = License(
                name="MIT",
                url="https://opensource.org/license/mit/",
            )

            app = Esmerald(license=license)
            ```

            **Example with dictionary**

            ```python
            from esmerald import Esmerald

            app = Esmerald(license={
                "name": "MIT",
                "url": "https://opensource.org/license/mit/",
            })
            ```
            """
        ),
    ] = None,
    security: Annotated[
        Optional[List[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.

            **Example**

            ```python
            from esmerald import Esmerald
            from esmerald.openapi.security.http import Bearer

            app = Esmerald(security=[Bearer()])
            ```
            """
        ),
    ] = None,
    servers: Annotated[
        Optional[List[Dict[str, Union[str, Any]]]],
        Doc(
            """
            A `list` of python dictionaries with the information regarding the connectivity
            to the target.

            This can be useful, for example, if your application is served from different domains and you want a shared OpenAPI documentation to test it all.

            Esmerald automatically handles the OpenAPI documentation generation for you but
            sometimes you might want to add an extra custom domain to it.

            For example, when using `ChildEsmerald` modules, since the object itself subclasses
            Esmerald, that also means you can have independent documentation directly in the
            ChildEsmerald or access the [top level](https://esmerald.dev/application/levels/)
            documentation (the application itself) where you can select the server to test it.

            If the servers `list` is not provided or an is an empty `list`, the default value
            will be a `dict` with the `url` pointing to `/`.

            Each `dict` of the `list` follows the following format for the parameters:

            * **url** - A URL string to the target host/domain. The URL may support server
            variables and it may be also a relative server (for example, the domain/path of a `ChildEsmerald`).
            * **description** - An optional string description of the host/domain.
            * **variables** - A dictionary between the variable and its value. The value
            is used for substitution in the servers URL template. E.g.: `/my-domain/{age: int}`.

            You can read more about how the [OpenAPI](https://esmerald.dev/openapi/) documentation is used.

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(
                servers=[
                    {"url": "https://testing.example.com", "description": "Testing environment"},
                    {"url": "https://uat.example.com", "description": "UAT environment"},
                    {"url": "https://live.example.com", "description": "Production environment"},
                ]
            )
            ```
            """
        ),
    ] = None,
    secret_key: Annotated[
        Union[Optional[str], Optional["Secret"]],
        Doc(
            """
            A unique string value used for the cryptography. This value is also
            used internally by Esmerald with the JWT as well the
            [CSRFConfig](https://esmerald.dev/configurations/csrf/).

            !!! Tip
                Make sure you do not reuse the same secret key across environments as
                this can lead to security issues that you can easily avoid.

            **Example**

            ```python
            from esmerald import Esmerald

            aop = Esmerald(
                secret_key="p7!3cq1rapxd!@l=gz-&&k*h8sk_n8#1#+n6&q@cb&r!^z^2!g"
            )
            ```
            """
        ),
    ] = None,
    allowed_hosts: Annotated[
        Optional[List[str]],
        Doc(
            """
            A `list` of allowed hosts for the application. The allowed hosts when not specified
            defaults to `["*"]` but when specified.

            The allowed hosts are also what controls the
            [TrustedHostMiddleware](https://esmerald.dev/middleware/middleware/#trustedhostmiddleware) and you can read more about how to use it.

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(
                allowed_hosts=["*.example.com", "www.foobar.com"]
            )
            ```
            """
        ),
    ] = None,
    allow_origins: Annotated[
        Optional[List[str]],
        Doc(
            """
            A `list` of allowed origins hosts for the application.

            The allowed origins is used by the [CORSConfig](https://esmerald.dev/configurations/cors/) and controls the [CORSMiddleware](https://esmerald.dev/middleware/middleware/#corsmiddleware).

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(allow_origins=["*"])
            ```

            !!! Tip
                If you create your own [CORSConfig](https://esmerald.dev/configurations/cors/),
                this setting **is ignored** and your custom config takes priority.
            """
        ),
    ] = None,
    permissions: Annotated[
        Optional[Sequence["Permission"]],
        Doc(
            """
            A `list` of global permissions from objects inheriting from
            `esmerald.permissions.BasePermission`.

            Read more about how to implement the [Permissions](https://esmerald.dev/permissions/#basepermission-and-custom-permissions) in Esmerald and to leverage them.

            **Note** almost everything in Esmerald can be done in [levels](https://esmerald.dev/application/levels/), which means
            these permissions on a Esmerald instance, means **the whole application**.

            **Example**

            ```python
            from esmerald import Esmerald, BasePermission, Request
            from esmerald.types import APIGateHandler


            class IsAdmin(BasePermission):
                '''
                Permissions for admin
                '''
                async def has_permission(self, request: "Request", apiview: "APIGateHandler"):
                    is_admin = request.headers.get("admin", False)
                    return bool(is_admin)


            app = Esmerald(permissions=[IsAdmin])
            ```
            """
        ),
    ] = None,
    interceptors: Annotated[
        Optional[Sequence["Interceptor"]],
        Doc(
            """
            A `list` of global interceptors from objects inheriting from
            `esmerald.interceptors.interceptor.EsmeraldInterceptor`.

            Read more about how to implement the [Interceptors](https://esmerald.dev/interceptors/) in Esmerald and to leverage them.

            **Note** almost everything in Esmerald can be done in [levels](https://esmerald.dev/application/levels/), which means
            these interceptors on a Esmerald instance, means **the whole application**.

            **Example**

            ```python
            from loguru import logger
            from lilya.types import Receive, Scope, Send

            from esmerald import Esmerald
            from esmerald import EsmeraldInterceptor


            class LoggingInterceptor(EsmeraldInterceptor):
                async def intercept(self, scope: "Scope", receive: "Receive", send: "Send") -> None:
                    # Log a message here
                    logger.info("This is my interceptor being called before reaching the handler.")


            app = Esmerald(interceptors=[LoggingInterceptor])
            ```
            """
        ),
    ] = None,
    dependencies: Annotated[
        Optional["Dependencies"],
        Doc(
            """
            A dictionary of global dependencies. These dependencies will be
            applied to each **path** of the application.

            Read more about [Dependencies](https://esmerald.dev/dependencies/).

            **Example**

            ```python
            from esmerald import Esmerald, Inject

            def is_valid(number: int) -> bool:
                return number >= 5

            app = Esmerald(
                dependencies={
                    "is_valid": Inject(is_valid)
                }
            )
            ```
            """
        ),
    ] = None,
    csrf_config: Annotated[
        Optional["CSRFConfig"],
        Doc(
            """
            An instance of [CRSFConfig](https://esmerald.dev/configurations/csrf/).

            This configuration is passed to the [CSRFMiddleware](https://esmerald.dev/middleware/middleware/#csrfmiddleware) and enables the middleware.

            !!! Tip
                You can creatye your own `CRSFMiddleware` version and pass your own
                configurations. You don't need to use the built-in version although it
                is recommended to do it so.

            **Example**

            ```python
            from esmerald import Esmerald
            from esmerald.config import CSRFConfig

            csrf_config = CSRFConfig(secret="your-long-unique-secret")

            app = Esmerald(csrf_config=csrf_config)
            ```
            """
        ),
    ] = None,
    openapi_config: Annotated[
        Optional["OpenAPIConfig"],
        Doc(
            """
            An instance of [OpenAPIConfig](https://esmerald.dev/configurations/openapi/config/).

            This object is then used by Esmerald to create the [OpenAPI](https://esmerald.dev/openapi/) documentation.

            **Note**: Here is where the defaults for Esmerald OpenAPI are overriden and if
            this object is passed, then the previous defaults of the settings are ignored.

            !!! Tip
                This is the way you could override the defaults all in one go
                instead of doing attribute by attribute.

            **Example**

            ```python
            from esmerald import OpenAPIConfig

            openapi_config = OpenAPIConfig(
                title="Black Window",
                openapi_url="/openapi.json",
                docs_url="/docs/swagger",
                redoc_url="/docs/redoc",
            )

            app = Esmerald(openapi_config=openapi_config)
            ```
            """
        ),
    ] = None,
    openapi_version: Annotated[
        Optional[str],
        Doc(
            """
            The string version of the OpenAPI.

            Esmerald will generate the OpenAPI 3.1.0 by default and will
            output that as the OpenAPI version.

            If you need to somehow trick some of the tools you are using
            by setting a different version of the OpenAPI, this is the
            field you can use to do it so.

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(openapi_version="3.1.0")
            ```
            """
        ),
    ] = None,
    cors_config: Annotated[
        Optional["CORSConfig"],
        Doc(
            """
            An instance of [CORSConfig](https://esmerald.dev/configurations/cors/).

            This configuration is passed to the [CORSMiddleware](https://esmerald.dev/middleware/middleware/#corsmiddleware) and enables the middleware.

            **Example**

            ```python
            from esmerald import Esmerald
            from esmerald.config import CSRFConfig

            cors_config = CORSConfig(allow_origins=["*"])

            app = Esmerald(cors_config=cors_config)
            ```
            """
        ),
    ] = None,
    static_files_config: Annotated[
        Optional["StaticFilesConfig"],
        Doc(
            """
            An instance of [StaticFilesConfig](https://esmerald.dev/configurations/staticfiles/).

            This configuration is used to enable and serve static files via
            Esmerald application.

            **Example**

            ```python
            from esmerald import Esmerald
            from esmerald.config import StaticFilesConfig

            static_files_config = StaticFilesConfig(
                path="/static", directory=Path("static")
            )

            app = Esmerald(static_files_config=static_files_config)
            ```
            """
        ),
    ] = None,
    template_config: Annotated[
        Optional["TemplateConfig"],
        Doc(
            """
            An instance of [TemplateConfig](https://esmerald.dev/configurations/template/).

            This configuration is a simple set of configurations that when passed enables the template engine.

            !!! Note
                You might need to install the template engine before
                using this. You can always run
                `pip install esmerald[templates]` to help you out.

            **Example**

            ```python
            from esmerald import Esmerald
            from esmerald.config.template import TemplateConfig
            from esmerald.template.jinja import JinjaTemplateEngine

            template_config = TemplateConfig(
                directory=Path("templates"),
                engine=JinjaTemplateEngine,
            )

            app = Esmerald(template_config=template_config)
            ```
            """
        ),
    ] = None,
    session_config: Annotated[
        Optional["SessionConfig"],
        Doc(
            """
            An instance of [SessionConfig](https://esmerald.dev/configurations/session/).

            This configuration is passed to the [SessionMiddleware](https://esmerald.dev/middleware/middleware/#sessionmiddleware) and enables the middleware.

            **Example**

            ```python
            from esmerald import Esmerald
            from esmerald.config import SessionConfig

            session_config = SessionConfig(
                secret_key=settings.secret_key,
                session_cookie="session",
            )

            app = Esmerald(session_config=session_config)
            ```
            """
        ),
    ] = None,
    response_class: Annotated[
        Optional["ResponseType"],
        Doc(
            """
            Global default response class to be used within the
            Esmerald application.

            Read more about the [Responses](https://esmerald.dev/responses/) and how
            to use them.

            **Example**

            ```python
            from esmerald import Esmerald, JSONResponse

            app = Esmerald(response_class=JSONResponse)
            ```
            """
        ),
    ] = None,
    response_cookies: Annotated[
        Optional["ResponseCookies"],
        Doc(
            """
            A global sequence of `esmerald.datastructures.Cookie` objects.

            Read more about the [Cookies](https://esmerald.dev/extras/cookie-fields/?h=responsecook#cookie-from-response-cookies).

            **Example**

            ```python
            from esmerald import Esmerald
            from esmerald.datastructures import Cookie

            response_cookies=[
                Cookie(
                    key="csrf",
                    value="CIwNZNlR4XbisJF39I8yWnWX9wX4WFoz",
                    max_age=3000,
                    httponly=True,
                )
            ]

            app = Esmerald(response_cookies=response_cookies)
            ```
            """
        ),
    ] = None,
    response_headers: Annotated[
        Optional["ResponseHeaders"],
        Doc(
            """
            A global mapping of `esmerald.datastructures.ResponseHeader` objects.

            Read more about the [ResponseHeader](https://esmerald.dev/extras/header-fields/#response-headers).

            **Example**

            ```python
            from esmerald import Esmerald
            from esmerald.datastructures import ResponseHeader

            response_headers={
                "authorize": ResponseHeader(value="granted")
            }

            app = Esmerald(response_headers=response_headers)
            ```
            """
        ),
    ] = None,
    scheduler_class: Annotated[
        Optional["SchedulerType"],
        Doc(
            """
            Esmerald integrates out of the box with [Asyncz](https://asyncz.tarsild.io/)
            and the scheduler class is nothing more than the `AsyncIOScheduler` provided
            by the library.

            Read more about the [scheduler](https://esmerald.dev/scheduler/scheduler/?h=scheduler_class#esmeraldscheduler) and how to use.

            !!! Tip
                You can create your own scheduler class and use it with Esmerald.
                For that you must read the [Asyncz](https://asyncz.tarsild.io/schedulers/)
                documentation and how to make it happen.

            **Note** - To enable the scheduler, you **must** set the `enable_scheduler=True`.

            **Example**

            ```python
            from esmerald import Esmerald
            from asyncz.schedulers import AsyncIOScheduler

            app = Esmerald(scheduler_class=AsyncIOScheduler)
            ```
            """
        ),
    ] = None,
    scheduler_tasks: Annotated[
        Optional[Dict[str, str]],
        Doc(
            """
            Mapping in the format `<task-name>: <location>` indicating the tasks to
            be run by the scheduler.

            Read more about the [scheduler](https://esmerald.dev/scheduler/scheduler/?h=scheduler_class#esmeraldscheduler) and how to use.

            **Note** - To enable the scheduler, you **must** set the `enable_scheduler=True`.

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(
                enable_scheduler=True,
                scheduler_tasks={
                    "collect_market_data": "accounts.tasks",
                    "send_email_newsletter": "accounts.tasks",
                },
            )
            ```
            """
        ),
    ] = None,
    scheduler_configurations: Annotated[
        Optional[Dict[str, Union[str, Dict[str, str]]]],
        Doc(
            """
            Mapping of extra configuratioms being passed to the scheduler.
            These are [Asyncz Configurations](https://asyncz.tarsild.io/schedulers/?h=confi#example-configuration).

            **Example**

            ```python
            from esmerald import Esmerald

            configurations = {
                "asyncz.stores.mongo": {"type": "mongodb"},
                "asyncz.stores.default": {"type": "redis", "database": "0"},
                "asyncz.executors.threadpool": {
                    "max_workers": "20",
                    "class": "asyncz.executors.threadpool:ThreadPoolExecutor",
                },
                "asyncz.executors.default": {"class": "asyncz.executors.asyncio::AsyncIOExecutor"},
                "asyncz.task_defaults.coalesce": "false",
                "asyncz.task_defaults.max_instances": "3",
                "asyncz.task_defaults.timezone": "UTC",
            }

            app = Esmerald(
                scheduler_configurations=configurations
            )
            ```
            """
        ),
    ] = None,
    enable_scheduler: Annotated[
        Optional[bool],
        Doc(
            """
            Boolean flag indicating if the internal scheduler should be enabled
            or not.

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(enable_scheduler=True)
            ```
            """
        ),
    ] = None,
    timezone: Annotated[
        Optional[Union[dtimezone, str]],
        Doc(
            """
            Object of time `datetime.timezone` or string indicating the
            timezone for the application.

            **Note** - The timezone is internally used for the supported
            scheduler.

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(timezone="UTC")
            ```
            """
        ),
    ] = None,
    routes: Annotated[
        Optional[Sequence[Union["APIGateHandler", "Include"]]],
        Doc(
            """
            A global `list` of esmerald routes. Those routes may vary and those can
            be `Gateway`, `WebSocketGateWay` or even `Include`.

            This is also the entry-point for the routes of the application itself
            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 routing system 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/) about this.
            """
        ),
    ] = None,
    root_path: Annotated[
        Optional[str],
        Doc(
            """
            A path prefix that is handled by a proxy not seen in the
            application but seen by external libraries.

            This affects the tools like the OpenAPI documentation.

            **Example^^

            ```python
            from esmerald import Esmerald

            app = Esmerald(root_path="/api/v3")
            ```
            """
        ),
    ] = None,
    middleware: Annotated[
        Optional[Sequence["Middleware"]],
        Doc(
            """
            A global sequence of Lilya middlewares or `esmerald.middlewares` that are
            used by the application.

            Read more about the [Middleware](https://esmerald.dev/middleware/middleware/).

            **Example**

            ```python
            from esmerald import Esmerald
            from esmerald.middleware import HTTPSRedirectMiddleware, TrustedHostMiddleware

            app = Esmerald(
                routes=[...],
                middleware=[
                    DefineMiddleware(TrustedHostMiddleware, allowed_hosts=["example.com", "*.example.com"]),
                    DefineMiddleware(HTTPSRedirectMiddleware),
                ],
            )
            ```
            """
        ),
    ] = None,
    exception_handlers: Annotated[
        Optional["ExceptionHandlerMap"],
        Doc(
            """
            A global dictionary with handlers for exceptions.

            **Note** almost everything in Esmerald can be done in [levels](https://esmerald.dev/application/levels/), which means
            these exception handlers on a Esmerald instance, means **the whole application**.

            Read more about the [Exception handlers](https://esmerald.dev/exception-handlers/).

            **Example**

            ```python
            from pydantic.error_wrappers import ValidationError
            from esmerald import (
                Esmerald,
                JSONResponse,
                Request,
                ValidationErrorException,
            )

            async def validation_error_exception_handler(
                request: Request, exc: ValidationError
            ) -> JSONResponse:
                extra = getattr(exc, "extra", None)
                if extra:
                    return JSONResponse(
                        {"detail": exc.detail, "errors": exc.extra.get("extra", {})},
                        status_code=status.HTTP_400_BAD_REQUEST,
                    )
                else:
                    return JSONResponse(
                        {"detail": exc.detail},
                        status_code=status.HTTP_400_BAD_REQUEST,
                    )

            app = Esmerald(
                exception_handlers={
                        ValidationErrorException: validation_error_exception_handler,
                    },
            )
            ```
            """
        ),
    ] = None,
    on_startup: Annotated[
        Optional[List["LifeSpanHandler"]],
        Doc(
            """
            A `list` of events that are trigger upon the application
            starts.

            Read more about the [events](https://esmerald.dev/lifespan-events/).

            **Example**

            ```python
            from pydantic import BaseModel
            from saffier import Database, Registry

            from esmerald import Esmerald, Gateway, post

            database = Database("postgresql+asyncpg://user:password@host:port/database")
            registry = Registry(database=database)


            class User(BaseModel):
                name: str
                email: str
                password: str
                retype_password: str


            @post("/create", tags=["user"], description="Creates a new user in the database")
            async def create_user(data: User) -> None:
                # Logic to create the user
                ...


            app = Esmerald(
                routes=[Gateway(handler=create_user)],
                on_startup=[database.connect],
            )
            ```
            """
        ),
    ] = None,
    on_shutdown: Annotated[
        Optional[List["LifeSpanHandler"]],
        Doc(
            """
            A `list` of events that are trigger upon the application
            shuts down.

            Read more about the [events](https://esmerald.dev/lifespan-events/).

            **Example**

            ```python
            from pydantic import BaseModel
            from saffier import Database, Registry

            from esmerald import Esmerald, Gateway, post

            database = Database("postgresql+asyncpg://user:password@host:port/database")
            registry = Registry(database=database)


            class User(BaseModel):
                name: str
                email: str
                password: str
                retype_password: str


            @post("/create", tags=["user"], description="Creates a new user in the database")
            async def create_user(data: User) -> None:
                # Logic to create the user
                ...


            app = Esmerald(
                routes=[Gateway(handler=create_user)],
                on_shutdown=[database.disconnect],
            )
            ```
            """
        ),
    ] = None,
    lifespan: Annotated[
        Optional[Lifespan[AppType]],
        Doc(
            """
            A `lifespan` context manager handler. This is an alternative
            to `on_startup` and `on_shutdown` and you **cannot used all combined**.

            Read more about the [lifespan](https://esmerald.dev/lifespan-events/).
            """
        ),
    ] = None,
    tags: Annotated[
        Optional[List[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.

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(tags=["application"])
            ```

            **Example with nested routes**

            When tags are added on a level bases, those are concatenated into the
            final handler.

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

            @get("/home", tags=["home"])
            async def home() -> Dict[str, str]:
                return {"hello": "world"}


            app = Esmerald(
                routes=[Gateway(handler=home)],
                tags=["application"]
            )
            ```
            """
        ),
    ] = None,
    include_in_schema: Annotated[
        Optional[bool],
        Doc(
            """
            Boolean flag indicating if all the routes of the application
            should be included in the OpenAPI documentation.

            **Note** almost everything in Esmerald can be done in [levels](https://esmerald.dev/application/levels/), which means when the application
            level is set to `include_in_schema=False`, no schemas will be
            displayed in the OpenAPI documentation.

            !!! Tip
                This can be particularly useful if you have, for example, a `ChildEsmerald` and
                you don't want to include in the schema the routes of the said `ChildEsmerald`.
                This way there is no reason to do it route by route and instead you can
                simply do it directly in the application [level](https://esmerald.dev/application/levels/).

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(include_in_schema=False)
            ```

             **Example applied to ChildEsmerald**

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

            app = Esmerald(routes=[
                Include("/child", app=ChildEsmerald(
                    include_in_schema=False
                ))
            ])
            ```
            """
        ),
    ] = None,
    deprecated: Annotated[
        Optional[bool],
        Doc(
            """
            Boolean flag indicating if all the routes of the application
            should be deprecated in the OpenAPI documentation.

            !!! Tip
                This can be particularly useful if you have, for example, a `ChildEsmerald` and
                you  want to deprecate in favour of a new one being implemented.

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(deprecated=True)
            ```

            **Example with a ChildEsmerald**

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

            app = Esmerald(routes=[
                Include("/child", app=ChildEsmerald(
                    deprecated=True
                ))
            ])
            ```
            """
        ),
    ] = None,
    enable_openapi: Annotated[
        Optional[bool],
        Doc(
            """
            Boolean flag indicating if the OpenAPI documentation should
            be generated or not.

            When `False`, no OpenAPI documentation is accessible.

            !!! Tip
                Disable this option if you run in production and no one should access the
                documentation unless behind an authentication.
            ```
            """
        ),
    ] = None,
    redirect_slashes: Annotated[
        Optional[bool],
        Doc(
            """
            Boolean flag indicating if the redirect slashes are enabled for the
            routes or not.
            """
        ),
    ] = None,
    pluggables: Annotated[
        Optional[Dict[str, Pluggable]],
        Doc(
            """
            A `list` of global pluggables from objects inheriting from
            `esmerald.interceptors.interceptor.EsmeraldInterceptor`.

            Read more about how to implement the [Plugables](https://esmerald.dev/pluggables/) in Esmerald and to leverage them.

            **Example**

            ```python
            from typing import Optional

            from loguru import logger
            from pydantic import BaseModel

            from esmerald import Esmerald, Extension, Pluggable
            from esmerald.types import DictAny


            class PluggableConfig(BaseModel):
                name: str


            class MyExtension(Extension):
                def __init__(
                    self, app: Optional["Esmerald"] = None, config: PluggableConfig = None, **kwargs: "DictAny"
                ):
                    super().__init__(app, **kwargs)
                    self.app = app

                def extend(self, config: PluggableConfig) -> None:
                    logger.success(f"Successfully passed a config {config.name}")


            my_config = PluggableConfig(name="my extension")
            pluggable = Pluggable(MyExtension, config=my_config)


            app = Esmerald(
                routes=[], pluggables={"my-extension": pluggable}
            )
            ```
            """
        ),
    ] = None,
    parent: Annotated[
        Optional[Union["ParentType", "Esmerald", "ChildEsmerald"]],
        Doc(
            """
            Used internally by Esmerald to recognise and build the [application levels](https://esmerald.dev/application/levels/).

            !!! Tip
                Unless you know what are you doing, it is advisable not to touch this.
            """
        ),
    ] = None,
    root_path_in_servers: Annotated[
        bool,
        Doc(
            """
            Boolean flag use to disable the automatic URL generation in the `servers` field
            in the OpenAPI documentation.

            **Examples**

            ```python
            from esmerald import Esmerald

            app = Esmerald(root_path_in_servers=False)
            ```
            """
        ),
    ] = None,
    webhooks: Annotated[
        Optional[Sequence["gateways.WebhookGateway"]],
        Doc(
            """
            This is the same principle of the `routes` but for OpenAPI webhooks.

            Read more [about webhooks](https://esmerald.dev/routing/webhooks).

            When a webhook is added, it will automatically add them into the
            OpenAPI documentation.
            """
        ),
    ] = None,
    openapi_url: Annotated[
        Optional[str],
        Doc(
            """
            The URL where the OpenAPI schema will be served from.
            The default is `/openapi.json`.

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(openapi_url="/api/v1/openapi.json")
            ```
            """
        ),
    ] = None,
) -> None:
    self.settings_module = None
    if settings_module is not None:
        if not isinstance(settings_module, EsmeraldAPISettings) and not is_class_and_subclass(
            settings_module, EsmeraldAPISettings
        ):
            raise ImproperlyConfigured(
                "settings_module must be a subclass of EsmeraldSettings"
            )
        elif isinstance(settings_module, EsmeraldAPISettings):
            self.settings_module = settings_module  # type: ignore
        elif is_class_and_subclass(settings_module, EsmeraldAPISettings):
            self.settings_module = settings_module()  # type: ignore

    assert lifespan is None or (
        on_startup is None and on_shutdown is None
    ), "Use either 'lifespan' or 'on_startup'/'on_shutdown', not both."

    if allow_origins and cors_config:
        raise ImproperlyConfigured("It can be only allow_origins or cors_config but not both.")

    self.parent = parent

    self._debug = self.load_settings_value("debug", debug, is_boolean=True)
    self.debug = self._debug

    self.title = self.load_settings_value("title", title)
    self.app_name = self.load_settings_value("app_name", app_name)
    self.description = self.load_settings_value("description", description)
    self.version = self.load_settings_value("version", version)
    self.openapi_version = self.load_settings_value("openapi_version", openapi_version)
    self.summary = self.load_settings_value("summary", summary)
    self.contact = self.load_settings_value("contact", contact)
    self.terms_of_service = self.load_settings_value("terms_of_service", terms_of_service)
    self.license = self.load_settings_value("license", license)
    self.servers = self.load_settings_value("servers", servers)
    self.secret_key = self.load_settings_value("secret_key", secret_key)
    self.allowed_hosts = self.load_settings_value("allowed_hosts", allowed_hosts)
    self.allow_origins = self.load_settings_value("allow_origins", allow_origins)
    self.permissions = self.load_settings_value("permissions", permissions) or []
    self.interceptors = self.load_settings_value("interceptors", interceptors) or []
    self.dependencies = self.load_settings_value("dependencies", dependencies) or {}
    self.csrf_config = self.load_settings_value("csrf_config", csrf_config)
    self.cors_config = self.load_settings_value("cors_config", cors_config)
    self.openapi_config = self.load_settings_value("openapi_config", openapi_config)
    self.template_config = self.load_settings_value("template_config", template_config)
    self.static_files_config = self.load_settings_value(
        "static_files_config", static_files_config
    )
    self.session_config = self.load_settings_value("session_config", session_config)
    self.response_class = self.load_settings_value("response_class", response_class)
    self.response_cookies = self.load_settings_value("response_cookies", response_cookies)
    self.response_headers = self.load_settings_value("response_headers", response_headers)
    self.scheduler_class = self.load_settings_value("scheduler_class", scheduler_class)
    self.scheduler_tasks = self.load_settings_value("scheduler_tasks", scheduler_tasks) or {}
    self.scheduler_configurations = (
        self.load_settings_value("scheduler_configurations", scheduler_configurations) or {}
    )
    self.enable_scheduler = self.load_settings_value(
        "enable_scheduler", enable_scheduler, is_boolean=True
    )
    self.timezone = self.load_settings_value("timezone", timezone)
    self.root_path = self.load_settings_value("root_path", root_path)
    self._middleware = self.load_settings_value("middleware", middleware) or []
    _exception_handlers = self.load_settings_value("exception_handlers", exception_handlers)
    self.exception_handlers = {} if _exception_handlers is None else dict(_exception_handlers)
    self.on_startup = self.load_settings_value("on_startup", on_startup)
    self.on_shutdown = self.load_settings_value("on_shutdown", on_shutdown)
    self.lifespan = self.load_settings_value("lifespan", lifespan)
    self.tags = self.load_settings_value("tags", security)
    self.include_in_schema = self.load_settings_value(
        "include_in_schema", include_in_schema, is_boolean=True
    )
    self.security = self.load_settings_value("security", security)
    self.enable_openapi = self.load_settings_value(
        "enable_openapi", enable_openapi, is_boolean=True
    )
    self.redirect_slashes = self.load_settings_value(
        "redirect_slashes", redirect_slashes, is_boolean=True
    )
    self.pluggables = self.load_settings_value("pluggables", pluggables)

    # OpenAPI Related
    self.root_path_in_servers = self.load_settings_value(
        "root_path_in_servers", root_path_in_servers, is_boolean=True
    )

    if not self.include_in_schema or not self.enable_openapi:
        self.root_path_in_servers = False

    self.webhooks = self.load_settings_value("webhooks", webhooks) or []
    self.openapi_url = self.load_settings_value("openapi_url", openapi_url)
    self.tags = self.load_settings_value("tags", tags)

    self.openapi_schema: Optional["OpenAPI"] = None
    self.state: Annotated[
        State,
        Doc(
            """
            The state object for the application. This is always the
            same object across the whole application.

            This can be defined as the application state and not request state
            which means that it does not change each request.

            Learn more in the [Lilya documentation](https://www.lilya.dev/applications/#storing-state-on-the-app-instance).
            """
        ),
    ] = State()
    self.async_exit_config = esmerald_settings.async_exit_config

    self.router: "Router" = Router(
        on_shutdown=self.on_shutdown,
        on_startup=self.on_startup,
        routes=routes,
        app=self,
        lifespan=self.lifespan,
        deprecated=deprecated,
        security=security,
        redirect_slashes=self.redirect_slashes,
    )

    self.get_default_exception_handlers()
    self.user_middleware = self.build_user_middleware_stack()
    self.middleware_stack = self.build_middleware_stack()
    self.pluggable_stack = self.build_pluggable_stack()
    self.template_engine = self.get_template_engine(self.template_config)

    self._configure()

state instance-attribute

state = State()

The state object for the application. This is always the same object across the whole application.

This can be defined as the application state and not request state which means that it does not change each request.

Learn more in the Lilya documentation.

settings property

settings

Returns the Esmerald settings object for easy access.

This settings are the ones being used by the application upon initialisation.

Example

from esmerald import Esmerald

app = Esmerald()
app.settings

get_template_engine

get_template_engine(template_config)

Returns the template engine for the application based on the TemplateConfig provided.

Example

from esmerald import Esmerald
from esmerald.config.template import TemplateConfig
from esmerald.template.jinja import JinjaTemplateEngine

template_config = TemplateConfig(
    directory=Path("templates"),
    engine=JinjaTemplateEngine,
)

app = Esmerald()
engine = app.get_template_engine(template_config=)
PARAMETER DESCRIPTION
template_config

An instance of TemplateConfig.

This configuration is a simple set of configurations that when passed enables the template engine.

Note

You might need to install the template engine before using this. You can always run pip install esmerald[templates] to help you out.

Example

from esmerald import Esmerald
from esmerald.config.template import TemplateConfig
from esmerald.template.jinja import JinjaTemplateEngine

template_config = TemplateConfig(
    directory=Path("templates"),
    engine=JinjaTemplateEngine,
)

app = Esmerald(template_config=template_config)

TYPE: TemplateConfig

Source code in esmerald/applications.py
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
def get_template_engine(
    self,
    template_config: Annotated[
        "TemplateConfig",
        Doc(
            """
            An instance of [TemplateConfig](https://esmerald.dev/configurations/template/).

            This configuration is a simple set of configurations that when passed enables the template engine.

            !!! Note
                You might need to install the template engine before
                using this. You can always run
                `pip install esmerald[templates]` to help you out.

            **Example**

            ```python
            from esmerald import Esmerald
            from esmerald.config.template import TemplateConfig
            from esmerald.template.jinja import JinjaTemplateEngine

            template_config = TemplateConfig(
                directory=Path("templates"),
                engine=JinjaTemplateEngine,
            )

            app = Esmerald(template_config=template_config)
            ```
            """
        ),
    ],
) -> Optional["TemplateEngineProtocol"]:
    """
    Returns the template engine for the application based on
    the `TemplateConfig` provided.

    **Example**

    ```python
    from esmerald import Esmerald
    from esmerald.config.template import TemplateConfig
    from esmerald.template.jinja import JinjaTemplateEngine

    template_config = TemplateConfig(
        directory=Path("templates"),
        engine=JinjaTemplateEngine,
    )

    app = Esmerald()
    engine = app.get_template_engine(template_config=)
    ```
    """
    if not template_config:
        return None

    engine: "TemplateEngineProtocol" = template_config.engine(template_config.directory)
    return engine

add_apiview

add_apiview(value)

Adds an APIView or related to the application routing.

Example

from esmerald import Esmerald, APIView, Gateway, get

class View(APIView):
    path = "/"

    @get(status_code=status_code)
    async def hello(self) -> str:
        return "Hello, World!"

gateway = Gateway(handler=View)

app = Esmerald()
app.add_apiview(value=gateway)
PARAMETER DESCRIPTION
value

The APIView or similar to be added.

TYPE: Union[Gateway, WebSocketGateway]

Source code in esmerald/applications.py
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
def add_apiview(
    self,
    value: Annotated[
        Union["gateways.Gateway", "gateways.WebSocketGateway"],
        Doc(
            """
            The `APIView` or similar to be added.
            """
        ),
    ],
) -> None:
    """
    Adds an [APIView](https://esmerald.dev/routing/apiview/) or related
    to the application routing.

    **Example**

    ```python
    from esmerald import Esmerald, APIView, Gateway, get

    class View(APIView):
        path = "/"

        @get(status_code=status_code)
        async def hello(self) -> str:
            return "Hello, World!"

    gateway = Gateway(handler=View)

    app = Esmerald()
    app.add_apiview(value=gateway)
    ```
    """
    self.router.add_apiview(value=value)

add_route

add_route(path, handler, router=None, dependencies=None, interceptors=None, permissions=None, exception_handlers=None, middleware=None, name=None, include_in_schema=True, deprecated=None, activate_openapi=True)

Adds a Route to the application routing.

This is a dynamic way of adding routes on the fly.

Example

from esmerald import Esmerald, get

@get(status_code=status_code)
async def hello() -> str:
    return "Hello, World!"

app = Esmerald()
app.add_route(path="/hello", handler=hello)
PARAMETER DESCRIPTION
path

Relative path of the Gateway. The path can contain parameters in a dictionary like format.

TYPE: str

handler

An instance of handler.

TYPE: HTTPHandler

router

A esmerald.Router instance to where the route will be added to.

TYPE: Optional[Router] 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

name

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

TYPE: Optional[str] DEFAULT: None

include_in_schema

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

TYPE: bool DEFAULT: True

deprecated

Boolean flag for indicating the deprecation of the Gateway and to display it in the OpenAPI documentation..

TYPE: Optional[bool] DEFAULT: None

activate_openapi

Boolean flag indicating if after adding the route to the application routing system, if it should also be added to the OpenAPI documentation.

TYPE: bool DEFAULT: True

Source code in esmerald/applications.py
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
def add_route(
    self,
    path: Annotated[
        str,
        Doc(
            """
            Relative path of the `Gateway`.
            The path can contain parameters in a dictionary like format.
            """
        ),
    ],
    handler: Annotated[
        "HTTPHandler",
        Doc(
            """
            An instance of [handler](https://esmerald.dev/routing/handlers/#http-handlers).
            """
        ),
    ],
    router: Annotated[
        Optional["Router"],
        Doc(
            """
        A `esmerald.Router` instance to where the route will be added to.
        """
        ),
    ] = 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,
    name: Annotated[
        Optional[str],
        Doc(
            """
            The name for the Gateway. The name can be reversed by `path_for()`.
            """
        ),
    ] = None,
    include_in_schema: Annotated[
        bool,
        Doc(
            """
            Boolean flag indicating if it should be added to the OpenAPI docs.
            """
        ),
    ] = True,
    deprecated: Annotated[
        Optional[bool],
        Doc(
            """
            Boolean flag for indicating the deprecation of the Gateway and to display it
            in the OpenAPI documentation..
            """
        ),
    ] = None,
    activate_openapi: Annotated[
        bool,
        Doc(
            """
            Boolean flag indicating if after adding the route
            to the application routing system, if it should
            also be added to the OpenAPI documentation.
            """
        ),
    ] = True,
) -> None:
    """
    Adds a [Route](https://esmerald.dev/routing/routes/)
    to the application routing.

    This is a dynamic way of adding routes on the fly.

    **Example**

    ```python
    from esmerald import Esmerald, get

    @get(status_code=status_code)
    async def hello() -> str:
        return "Hello, World!"

    app = Esmerald()
    app.add_route(path="/hello", handler=hello)
    ```
    """
    router = router or self.router
    router.add_route(
        path=path,
        handler=handler,
        dependencies=dependencies,
        exception_handlers=exception_handlers,
        interceptors=interceptors,
        permissions=permissions,
        middleware=middleware,
        name=name,
        include_in_schema=include_in_schema,
        deprecated=deprecated,
    )

    if activate_openapi:
        self.activate_openapi()

add_websocket_route

add_websocket_route(path, handler, router=None, name=None, dependencies=None, interceptors=None, permissions=None, exception_handlers=None, middleware=None)

Adds a websocket Route to the application routing.

This is a dynamic way of adding routes on the fly.

Example

from esmerald import Esmerald, websocket

@websocket()
async def websocket_route(socket: WebSocket) -> None:
    await socket.accept()
    data = await socket.receive_json()

    assert data
    await socket.send_json({"data": "esmerald"})
    await socket.close()

app = Esmerald()
app.add_websocket_route(path="/ws", handler=websocket_route)
PARAMETER DESCRIPTION
path

Relative path of the Gateway. The path can contain parameters in a dictionary like format.

TYPE: str

handler

An instance of websocket handler.

TYPE: WebSocketHandler

router

A esmerald.Router instance to where the route will be added to.

TYPE: Optional[Router] DEFAULT: None

name

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

TYPE: Optional[str] 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

Source code in esmerald/applications.py
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
def add_websocket_route(
    self,
    path: Annotated[
        str,
        Doc(
            """
            Relative path of the `Gateway`.
            The path can contain parameters in a dictionary like format.
            """
        ),
    ],
    handler: Annotated[
        "WebSocketHandler",
        Doc(
            """
            An instance of [websocket handler](https://esmerald.dev/routing/handlers/#websocket-handler).
            """
        ),
    ],
    router: Annotated[
        Optional["Router"],
        Doc(
            """
        A `esmerald.Router` instance to where the route will be added to.
        """
        ),
    ] = None,
    name: Annotated[
        Optional[str],
        Doc(
            """
            The name for the WebSocketGateway. The name can be reversed by `path_for()`.
            """
        ),
    ] = 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,
) -> None:
    """
    Adds a websocket [Route](https://esmerald.dev/routing/routes/)
    to the application routing.

    This is a dynamic way of adding routes on the fly.

    **Example**

    ```python
    from esmerald import Esmerald, websocket

    @websocket()
    async def websocket_route(socket: WebSocket) -> None:
        await socket.accept()
        data = await socket.receive_json()

        assert data
        await socket.send_json({"data": "esmerald"})
        await socket.close()

    app = Esmerald()
    app.add_websocket_route(path="/ws", handler=websocket_route)
    ```
    """
    router = router or self.router
    return router.add_websocket_route(
        path=path,
        handler=handler,
        dependencies=dependencies,
        exception_handlers=exception_handlers,
        interceptors=interceptors,
        permissions=permissions,
        middleware=middleware,
        name=name,
    )

add_include

add_include(include)

Adds an Include directly to the active application router and creates the proper signature models.

Example

from esmerald import get, Include

@get(status_code=status_code)
async def hello(self) -> str:
    return "Hello, World!"

include = Include("/child", routes=[Gateway(handler=hello)])

app = Esmerald()
app.add_include(include=include)
PARAMETER DESCRIPTION
include

The Include instance to be added.

TYPE: Include

Source code in esmerald/applications.py
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
def add_include(
    self,
    include: Annotated[
        Include,
        Doc(
            """
            The [Include](https://esmerald.dev/routing/routes/#include) instance
            to be added.
            """
        ),
    ],
) -> None:
    """
    Adds an [Include](https://esmerald.dev/routing/routes/#include) directly to the active application router
    and creates the proper signature models.

    **Example**

    ```python
    from esmerald import get, Include

    @get(status_code=status_code)
    async def hello(self) -> str:
        return "Hello, World!"

    include = Include("/child", routes=[Gateway(handler=hello)])

    app = Esmerald()
    app.add_include(include=include)
    ```
    """
    self.router.routes.append(include)

    for route in include.routes:
        self.router.create_signature_models(route)

    self.activate_openapi()

add_child_esmerald

add_child_esmerald(path, child, name=None, middleware=None, dependencies=None, exception_handlers=None, interceptors=None, permissions=None, include_in_schema=True, deprecated=None, security=None)

Adds a ChildEsmerald directly to the active application router.

Example

from esmerald import get, Include, ChildEsmerald, Esmerald

@get(status_code=status_code)
async def hello(self) -> str:
    return "Hello, World!"

child = ChildEsmerald(routes=[Gateway(handler=hello)])

app = Esmerald()
app.add_child_esmerald(path"/child", child=child)
PARAMETER DESCRIPTION
path

TYPE: str

child

The ChildEsmerald instance to be added.

TYPE: ChildEsmerald

name

TYPE: Optional[str] DEFAULT: None

middleware

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

dependencies

TYPE: Optional[Dependencies] DEFAULT: None

exception_handlers

TYPE: Optional[ExceptionHandlerMap] DEFAULT: None

interceptors

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

permissions

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

include_in_schema

TYPE: Optional[bool] DEFAULT: True

deprecated

TYPE: Optional[bool] DEFAULT: None

security

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

Source code in esmerald/applications.py
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
def add_child_esmerald(
    self,
    path: str,
    child: Annotated[
        "ChildEsmerald",
        Doc(
            """
            The [ChildEsmerald](https://esmerald.dev/routing/router/#child-esmerald-application) instance
            to be added.
            """
        ),
    ],
    name: Optional[str] = None,
    middleware: Optional[Sequence["Middleware"]] = None,
    dependencies: Optional["Dependencies"] = None,
    exception_handlers: Optional["ExceptionHandlerMap"] = None,
    interceptors: Optional[List["Interceptor"]] = None,
    permissions: Optional[List["Permission"]] = None,
    include_in_schema: Optional[bool] = True,
    deprecated: Optional[bool] = None,
    security: Optional[List["SecurityScheme"]] = None,
) -> None:
    """
    Adds a [ChildEsmerald](https://esmerald.dev/routing/router/#child-esmerald-application) directly to the active application router.

    **Example**

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

    @get(status_code=status_code)
    async def hello(self) -> str:
        return "Hello, World!"

    child = ChildEsmerald(routes=[Gateway(handler=hello)])

    app = Esmerald()
    app.add_child_esmerald(path"/child", child=child)
    ```
    """
    if not isinstance(child, ChildEsmerald):
        raise ImproperlyConfigured("The child must be an instance of a ChildEsmerald.")

    self.router.routes.append(
        Include(
            path=path,
            name=name,
            app=child,
            parent=self.router,
            dependencies=dependencies,
            middleware=cast("List[Middleware]", middleware),
            exception_handlers=exception_handlers,
            interceptors=interceptors,
            permissions=permissions,
            include_in_schema=include_in_schema,
            deprecated=deprecated,
            security=security,
        )
    )
    self.activate_openapi()

add_router

add_router(router)

Adds a Router directly to the active application router.

Example

from esmerald import get
from esmerald.routing.router import Router

@get(status_code=status_code)
async def hello(self) -> str:
    return "Hello, World!"

router = Router(path="/aditional", routes=[Gateway(handler=hello)])

app = Esmerald()
app.add_router(router=router)
PARAMETER DESCRIPTION
router

The Router instance to be added.

TYPE: Router

Source code in esmerald/applications.py
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
def add_router(
    self,
    router: Annotated[
        "Router",
        Doc(
            """
            The [Router](https://esmerald.dev/routing/router/) instance to be
            added.
            """
        ),
    ],
) -> None:
    """
    Adds a [Router](https://esmerald.dev/routing/router/) directly to the active application router.

    **Example**

    ```python
    from esmerald import get
    from esmerald.routing.router import Router

    @get(status_code=status_code)
    async def hello(self) -> str:
        return "Hello, World!"

    router = Router(path="/aditional", routes=[Gateway(handler=hello)])

    app = Esmerald()
    app.add_router(router=router)
    ```
    """
    for route in router.routes:
        if isinstance(route, Include):
            self.router.routes.append(
                Include(
                    path=route.path,
                    app=route.app,
                    dependencies=route.dependencies,
                    exception_handlers=route.exception_handlers,
                    name=route.name,
                    middleware=cast("List[Middleware]", route.middleware),
                    interceptors=route.interceptors,
                    permissions=route.permissions,
                    routes=cast("Sequence[Union[APIGateHandler, Include]]", route.routes),
                    parent=self.router,
                    security=route.security,
                )
            )
            continue

        gateway = (
            gateways.Gateway
            if not isinstance(route.handler, WebSocketHandler)
            else gateways.WebSocketGateway
        )

        if self.on_startup:
            self.on_startup.extend(router.on_startup)
        if self.on_shutdown:
            self.on_shutdown.extend(router.on_shutdown)

        self.router.routes.append(
            gateway(
                path=route.path,
                dependencies=route.dependencies,
                exception_handlers=route.exception_handlers,
                name=route.name,
                middleware=route.middleware,
                interceptors=route.interceptors,
                permissions=route.permissions,
                handler=route.handler,
                parent=self.router,
                is_from_router=True,
            )
        )

    self.activate_openapi()

add_pluggable

add_pluggable(name, extension)

Adds a Pluggable directly to the active application router.

Example

from loguru import logger
from esmerald import Esmerald, Extension, Pluggable

from pydantic import BaseModel

class Config(BaseModel):
    name: Optional[str]

class CustomExtension(Extension):
    def __init__(self, app: Optional["Esmerald"] = None, **kwargs: DictAny):
        super().__init__(app, **kwargs)
        self.app = app

    def extend(self, config) -> None:
        logger.success(f"Started standalone plugging with the name: {config.name}")

        self.app.add_pluggable("manual", self)

app = Esmerald(routes=[])
config = Config(name="manual")
extension = CustomExtension(app=app)
extension.extend(config=config)
PARAMETER DESCRIPTION
name

TYPE: str

extension

TYPE: Extension

Source code in esmerald/applications.py
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
def add_pluggable(self, name: str, extension: "Extension") -> None:
    """
    Adds a [Pluggable](https://esmerald.dev/pluggables/) directly to the active application router.

    **Example**

    ```python
    from loguru import logger
    from esmerald import Esmerald, Extension, Pluggable

    from pydantic import BaseModel

    class Config(BaseModel):
        name: Optional[str]

    class CustomExtension(Extension):
        def __init__(self, app: Optional["Esmerald"] = None, **kwargs: DictAny):
            super().__init__(app, **kwargs)
            self.app = app

        def extend(self, config) -> None:
            logger.success(f"Started standalone plugging with the name: {config.name}")

            self.app.add_pluggable("manual", self)

    app = Esmerald(routes=[])
    config = Config(name="manual")
    extension = CustomExtension(app=app)
    extension.extend(config=config)
    ```
    """
    self.pluggables[name] = extension

esmerald.ChildEsmerald

ChildEsmerald(*, settings_module=None, debug=None, app_name=None, title=None, version=None, summary=None, description=None, contact=None, terms_of_service=None, license=None, security=None, servers=None, secret_key=None, allowed_hosts=None, allow_origins=None, permissions=None, interceptors=None, dependencies=None, csrf_config=None, openapi_config=None, openapi_version=None, cors_config=None, static_files_config=None, template_config=None, session_config=None, response_class=None, response_cookies=None, response_headers=None, scheduler_class=None, scheduler_tasks=None, scheduler_configurations=None, enable_scheduler=None, timezone=None, routes=None, root_path=None, middleware=None, exception_handlers=None, on_startup=None, on_shutdown=None, lifespan=None, tags=None, include_in_schema=None, deprecated=None, enable_openapi=None, redirect_slashes=None, pluggables=None, parent=None, root_path_in_servers=None, webhooks=None, openapi_url=None)

Bases: Esmerald

ChildEsmerald application object. The main entry-point for a modular application/API with Esmerald.

The ChildEsmerald inherits directly from the Esmerald object which means all the same parameters, attributes and functions of Esmerald ara also available in the ChildEsmerald.

This object is complex and very powerful. Read more in detail about how to use and spin-up an application in minutes with ChildEsmerald.

Tip

All the parameters available in the object have defaults being loaded by the settings system if nothing is provided.

Example

from esmerald import Esmerald, ChildEsmerald, Include

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

Alternative settings parameter. This parameter is an alternative to ESMERALD_SETTINGS_MODULE way of loading your settings into an Esmerald application.

When the settings_module is provided, it will make sure it takes priority over any other settings provided for the instance.

Read more about the settings module and how you can leverage it in your application.

Tip

The settings module can be very useful if you want to have, for example, a ChildEsmerald that needs completely different settings from the main app.

Example: A ChildEsmerald that takes care of the authentication into a cloud provider such as AWS and handles the boto3 module.

TYPE: Optional[SettingsType] DEFAULT: None

debug

Boolean indicating if the application should return the debug tracebacks on server errors, in other words, if you want to have debug errors being displayed.

Read more about this in the official Lilya documentation.

Tip

Do not use this in production.

Example

from esmerald import Esmerald

app = Esmerald(debug=True)

TYPE: Optional[bool] DEFAULT: None

app_name

The name of the Esmerald application/API. This name is displayed when the OpenAPI documentation is used.

Example

from esmerald import Esmerald

app = Esmerald(app_name="Esmerald")

TYPE: Optional[str] DEFAULT: None

title

The title of the Esmerald application/API. This title is displayed when the OpenAPI documentation is used.

Example

from esmerald import Esmerald

app = Esmerald(title="My awesome Esmerald application")

TYPE: Optional[str] DEFAULT: None

version

The version of the Esmerald application/API. This version is displayed when the OpenAPI documentation is used.

Note: This is the version of your application/API and not th version of the OpenAPI specification being used by Esmerald.

Example

from esmerald import Esmerald

app = Esmerald(version="0.1.0")

TYPE: Optional[str] DEFAULT: None

summary

The summary of the Esmerald application/API. This short summary is displayed when the OpenAPI documentation is used.

Example

from esmerald import Esmerald

app = Esmerald(summary="Black Window joins The Pretenders.")

TYPE: Optional[str] DEFAULT: None

description

The description of the Esmerald application/API. This description is displayed when the OpenAPI documentation is used.

Example

from esmerald import Esmerald

app = Esmerald(
    description='''
                Black Window joins The Pretenders.

                ## Powers

                You can **activate_powers**

                ## Skills

                * **read_skill**
                * **use_skill**
                '''
)

TYPE: Optional[str] DEFAULT: None

contact

A dictionary or an object of type openapi_schemas_pydantic.v3_1_0.Contact containing the contact information of the application/API.

Both dictionary and object contain several fields.

  • name - String name of the contact.
  • url - String URL of the contact. It must be in the format of a URL.
  • email - String email address of the contact. It must be in the format of an email address.

Example with object

from esmerald import Esmerald
from openapi_schemas_pydantic.v3_1_0 import Contact

contact = Contact(
    name="Black Window",
    url="https://thepretenders.com/open-for-business",
    email="black.window@thepretenders.com,
)

app = Esmerald(contact=contact)

Example with dictionary

from esmerald import Esmerald

app = Esmerald(contact={
    "name": "Black Window",
    "url": "https://thepretenders.com/open-for-business",
    "email": "black.window@thepretenders.com,
})

TYPE: Optional[Contact] DEFAULT: None

terms_of_service

A URL pointing to the Terms of Service of the application. This description is displayed when the OpenAPI documentation is used.

Example

from esmerald import Esmerald

app = Esmerald(terms_of_service="https://example.com/terms-of-service")

TYPE: Optional[AnyUrl] DEFAULT: None

license

A dictionary or an object of type openapi_schemas_pydantic.v3_1_0.License containing the license information of the application/API.

Both dictionary and object contain several fields.

  • name - String name of the license.
  • identifier - An SPDX license expression.
  • url - String URL of the contact. It must be in the format of a URL.

Example with object

from esmerald import Esmerald
from openapi_schemas_pydantic.v3_1_0 import License

license = License(
    name="MIT",
    url="https://opensource.org/license/mit/",
)

app = Esmerald(license=license)

Example with dictionary

from esmerald import Esmerald

app = Esmerald(license={
    "name": "MIT",
    "url": "https://opensource.org/license/mit/",
})

TYPE: Optional[License] 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.

Example

from esmerald import Esmerald
from esmerald.openapi.security.http import Bearer

app = Esmerald(security=[Bearer()])

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

servers

A list of python dictionaries with the information regarding the connectivity to the target.

This can be useful, for example, if your application is served from different domains and you want a shared OpenAPI documentation to test it all.

Esmerald automatically handles the OpenAPI documentation generation for you but sometimes you might want to add an extra custom domain to it.

For example, when using ChildEsmerald modules, since the object itself subclasses Esmerald, that also means you can have independent documentation directly in the ChildEsmerald or access the top level documentation (the application itself) where you can select the server to test it.

If the servers list is not provided or an is an empty list, the default value will be a dict with the url pointing to /.

Each dict of the list follows the following format for the parameters:

  • url - A URL string to the target host/domain. The URL may support server variables and it may be also a relative server (for example, the domain/path of a ChildEsmerald).
  • description - An optional string description of the host/domain.
  • variables - A dictionary between the variable and its value. The value is used for substitution in the servers URL template. E.g.: /my-domain/{age: int}.

You can read more about how the OpenAPI documentation is used.

Example

from esmerald import Esmerald

app = Esmerald(
    servers=[
        {"url": "https://testing.example.com", "description": "Testing environment"},
        {"url": "https://uat.example.com", "description": "UAT environment"},
        {"url": "https://live.example.com", "description": "Production environment"},
    ]
)

TYPE: Optional[List[Dict[str, Union[str, Any]]]] DEFAULT: None

secret_key

A unique string value used for the cryptography. This value is also used internally by Esmerald with the JWT as well the CSRFConfig.

Tip

Make sure you do not reuse the same secret key across environments as this can lead to security issues that you can easily avoid.

Example

from esmerald import Esmerald

aop = Esmerald(
    secret_key="p7!3cq1rapxd!@l=gz-&&k*h8sk_n8#1#+n6&q@cb&r!^z^2!g"
)

TYPE: Union[Optional[str], Optional[Secret]] DEFAULT: None

allowed_hosts

A list of allowed hosts for the application. The allowed hosts when not specified defaults to ["*"] but when specified.

The allowed hosts are also what controls the TrustedHostMiddleware and you can read more about how to use it.

Example

from esmerald import Esmerald

app = Esmerald(
    allowed_hosts=["*.example.com", "www.foobar.com"]
)

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

allow_origins

A list of allowed origins hosts for the application.

The allowed origins is used by the CORSConfig and controls the CORSMiddleware.

Example

from esmerald import Esmerald

app = Esmerald(allow_origins=["*"])

Tip

If you create your own CORSConfig, this setting is ignored and your custom config takes priority.

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

permissions

A list of global permissions from objects inheriting from esmerald.permissions.BasePermission.

Read more about how to implement the Permissions in Esmerald and to leverage them.

Note almost everything in Esmerald can be done in levels, which means these permissions on a Esmerald instance, means the whole application.

Example

from esmerald import Esmerald, BasePermission, Request
from esmerald.types import APIGateHandler


class IsAdmin(BasePermission):
    '''
    Permissions for admin
    '''
    async def has_permission(self, request: "Request", apiview: "APIGateHandler"):
        is_admin = request.headers.get("admin", False)
        return bool(is_admin)


app = Esmerald(permissions=[IsAdmin])

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

interceptors

A list of global interceptors from objects inheriting from esmerald.interceptors.interceptor.EsmeraldInterceptor.

Read more about how to implement the Interceptors in Esmerald and to leverage them.

Note almost everything in Esmerald can be done in levels, which means these interceptors on a Esmerald instance, means the whole application.

Example

from loguru import logger
from lilya.types import Receive, Scope, Send

from esmerald import Esmerald
from esmerald import EsmeraldInterceptor


class LoggingInterceptor(EsmeraldInterceptor):
    async def intercept(self, scope: "Scope", receive: "Receive", send: "Send") -> None:
        # Log a message here
        logger.info("This is my interceptor being called before reaching the handler.")


app = Esmerald(interceptors=[LoggingInterceptor])

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

dependencies

A dictionary of global dependencies. These dependencies will be applied to each path of the application.

Read more about Dependencies.

Example

from esmerald import Esmerald, Inject

def is_valid(number: int) -> bool:
    return number >= 5

app = Esmerald(
    dependencies={
        "is_valid": Inject(is_valid)
    }
)

TYPE: Optional[Dependencies] DEFAULT: None

csrf_config

An instance of CRSFConfig.

This configuration is passed to the CSRFMiddleware and enables the middleware.

Tip

You can creatye your own CRSFMiddleware version and pass your own configurations. You don't need to use the built-in version although it is recommended to do it so.

Example

from esmerald import Esmerald
from esmerald.config import CSRFConfig

csrf_config = CSRFConfig(secret="your-long-unique-secret")

app = Esmerald(csrf_config=csrf_config)

TYPE: Optional[CSRFConfig] DEFAULT: None

openapi_config

An instance of OpenAPIConfig.

This object is then used by Esmerald to create the OpenAPI documentation.

Note: Here is where the defaults for Esmerald OpenAPI are overriden and if this object is passed, then the previous defaults of the settings are ignored.

Tip

This is the way you could override the defaults all in one go instead of doing attribute by attribute.

Example

from esmerald import OpenAPIConfig

openapi_config = OpenAPIConfig(
    title="Black Window",
    openapi_url="/openapi.json",
    docs_url="/docs/swagger",
    redoc_url="/docs/redoc",
)

app = Esmerald(openapi_config=openapi_config)

TYPE: Optional[OpenAPIConfig] DEFAULT: None

openapi_version

The string version of the OpenAPI.

Esmerald will generate the OpenAPI 3.1.0 by default and will output that as the OpenAPI version.

If you need to somehow trick some of the tools you are using by setting a different version of the OpenAPI, this is the field you can use to do it so.

Example

from esmerald import Esmerald

app = Esmerald(openapi_version="3.1.0")

TYPE: Optional[str] DEFAULT: None

cors_config

An instance of CORSConfig.

This configuration is passed to the CORSMiddleware and enables the middleware.

Example

from esmerald import Esmerald
from esmerald.config import CSRFConfig

cors_config = CORSConfig(allow_origins=["*"])

app = Esmerald(cors_config=cors_config)

TYPE: Optional[CORSConfig] DEFAULT: None

static_files_config

An instance of StaticFilesConfig.

This configuration is used to enable and serve static files via Esmerald application.

Example

from esmerald import Esmerald
from esmerald.config import StaticFilesConfig

static_files_config = StaticFilesConfig(
    path="/static", directory=Path("static")
)

app = Esmerald(static_files_config=static_files_config)

TYPE: Optional[StaticFilesConfig] DEFAULT: None

template_config

An instance of TemplateConfig.

This configuration is a simple set of configurations that when passed enables the template engine.

Note

You might need to install the template engine before using this. You can always run pip install esmerald[templates] to help you out.

Example

from esmerald import Esmerald
from esmerald.config.template import TemplateConfig
from esmerald.template.jinja import JinjaTemplateEngine

template_config = TemplateConfig(
    directory=Path("templates"),
    engine=JinjaTemplateEngine,
)

app = Esmerald(template_config=template_config)

TYPE: Optional[TemplateConfig] DEFAULT: None

session_config

An instance of SessionConfig.

This configuration is passed to the SessionMiddleware and enables the middleware.

Example

from esmerald import Esmerald
from esmerald.config import SessionConfig

session_config = SessionConfig(
    secret_key=settings.secret_key,
    session_cookie="session",
)

app = Esmerald(session_config=session_config)

TYPE: Optional[SessionConfig] DEFAULT: None

response_class

Global default response class to be used within the Esmerald application.

Read more about the Responses and how to use them.

Example

from esmerald import Esmerald, JSONResponse

app = Esmerald(response_class=JSONResponse)

TYPE: Optional[ResponseType] DEFAULT: None

response_cookies

A global sequence of esmerald.datastructures.Cookie objects.

Read more about the Cookies.

Example

from esmerald import Esmerald
from esmerald.datastructures import Cookie

response_cookies=[
    Cookie(
        key="csrf",
        value="CIwNZNlR4XbisJF39I8yWnWX9wX4WFoz",
        max_age=3000,
        httponly=True,
    )
]

app = Esmerald(response_cookies=response_cookies)

TYPE: Optional[ResponseCookies] DEFAULT: None

response_headers

A global mapping of esmerald.datastructures.ResponseHeader objects.

Read more about the ResponseHeader.

Example

from esmerald import Esmerald
from esmerald.datastructures import ResponseHeader

response_headers={
    "authorize": ResponseHeader(value="granted")
}

app = Esmerald(response_headers=response_headers)

TYPE: Optional[ResponseHeaders] DEFAULT: None

scheduler_class

Esmerald integrates out of the box with Asyncz and the scheduler class is nothing more than the AsyncIOScheduler provided by the library.

Read more about the scheduler and how to use.

Tip

You can create your own scheduler class and use it with Esmerald. For that you must read the Asyncz documentation and how to make it happen.

Note - To enable the scheduler, you must set the enable_scheduler=True.

Example

from esmerald import Esmerald
from asyncz.schedulers import AsyncIOScheduler

app = Esmerald(scheduler_class=AsyncIOScheduler)

TYPE: Optional[SchedulerType] DEFAULT: None

scheduler_tasks

Mapping in the format <task-name>: <location> indicating the tasks to be run by the scheduler.

Read more about the scheduler and how to use.

Note - To enable the scheduler, you must set the enable_scheduler=True.

Example

from esmerald import Esmerald

app = Esmerald(
    enable_scheduler=True,
    scheduler_tasks={
        "collect_market_data": "accounts.tasks",
        "send_email_newsletter": "accounts.tasks",
    },
)

TYPE: Optional[Dict[str, str]] DEFAULT: None

scheduler_configurations

Mapping of extra configuratioms being passed to the scheduler. These are Asyncz Configurations.

Example

from esmerald import Esmerald

configurations = {
    "asyncz.stores.mongo": {"type": "mongodb"},
    "asyncz.stores.default": {"type": "redis", "database": "0"},
    "asyncz.executors.threadpool": {
        "max_workers": "20",
        "class": "asyncz.executors.threadpool:ThreadPoolExecutor",
    },
    "asyncz.executors.default": {"class": "asyncz.executors.asyncio::AsyncIOExecutor"},
    "asyncz.task_defaults.coalesce": "false",
    "asyncz.task_defaults.max_instances": "3",
    "asyncz.task_defaults.timezone": "UTC",
}

app = Esmerald(
    scheduler_configurations=configurations
)

TYPE: Optional[Dict[str, Union[str, Dict[str, str]]]] DEFAULT: None

enable_scheduler

Boolean flag indicating if the internal scheduler should be enabled or not.

Example

from esmerald import Esmerald

app = Esmerald(enable_scheduler=True)

TYPE: Optional[bool] DEFAULT: None

timezone

Object of time datetime.timezone or string indicating the timezone for the application.

Note - The timezone is internally used for the supported scheduler.

Example

from esmerald import Esmerald

app = Esmerald(timezone="UTC")

TYPE: Optional[Union[timezone, str]] DEFAULT: None

routes

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

This is also the entry-point for the routes of the application itself 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 routing system 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]]] DEFAULT: None

root_path

A path prefix that is handled by a proxy not seen in the application but seen by external libraries.

This affects the tools like the OpenAPI documentation.

**Example^^

from esmerald import Esmerald

app = Esmerald(root_path="/api/v3")

TYPE: Optional[str] DEFAULT: None

middleware

A global sequence of Lilya middlewares or esmerald.middlewares that are used by the application.

Read more about the Middleware.

Example

from esmerald import Esmerald
from esmerald.middleware import HTTPSRedirectMiddleware, TrustedHostMiddleware

app = Esmerald(
    routes=[...],
    middleware=[
        DefineMiddleware(TrustedHostMiddleware, allowed_hosts=["example.com", "*.example.com"]),
        DefineMiddleware(HTTPSRedirectMiddleware),
    ],
)

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

exception_handlers

A global dictionary with handlers for exceptions.

Note almost everything in Esmerald can be done in levels, which means these exception handlers on a Esmerald instance, means the whole application.

Read more about the Exception handlers.

Example

from pydantic.error_wrappers import ValidationError
from esmerald import (
    Esmerald,
    JSONResponse,
    Request,
    ValidationErrorException,
)

async def validation_error_exception_handler(
    request: Request, exc: ValidationError
) -> JSONResponse:
    extra = getattr(exc, "extra", None)
    if extra:
        return JSONResponse(
            {"detail": exc.detail, "errors": exc.extra.get("extra", {})},
            status_code=status.HTTP_400_BAD_REQUEST,
        )
    else:
        return JSONResponse(
            {"detail": exc.detail},
            status_code=status.HTTP_400_BAD_REQUEST,
        )

app = Esmerald(
    exception_handlers={
            ValidationErrorException: validation_error_exception_handler,
        },
)

TYPE: Optional[ExceptionHandlerMap] DEFAULT: None

on_startup

A list of events that are trigger upon the application starts.

Read more about the events.

Example

from pydantic import BaseModel
from saffier import Database, Registry

from esmerald import Esmerald, Gateway, post

database = Database("postgresql+asyncpg://user:password@host:port/database")
registry = Registry(database=database)


class User(BaseModel):
    name: str
    email: str
    password: str
    retype_password: str


@post("/create", tags=["user"], description="Creates a new user in the database")
async def create_user(data: User) -> None:
    # Logic to create the user
    ...


app = Esmerald(
    routes=[Gateway(handler=create_user)],
    on_startup=[database.connect],
)

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

on_shutdown

A list of events that are trigger upon the application shuts down.

Read more about the events.

Example

from pydantic import BaseModel
from saffier import Database, Registry

from esmerald import Esmerald, Gateway, post

database = Database("postgresql+asyncpg://user:password@host:port/database")
registry = Registry(database=database)


class User(BaseModel):
    name: str
    email: str
    password: str
    retype_password: str


@post("/create", tags=["user"], description="Creates a new user in the database")
async def create_user(data: User) -> None:
    # Logic to create the user
    ...


app = Esmerald(
    routes=[Gateway(handler=create_user)],
    on_shutdown=[database.disconnect],
)

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

lifespan

A lifespan context manager handler. This is an alternative to on_startup and on_shutdown and you cannot used all combined.

Read more about the lifespan.

TYPE: Optional[Lifespan[AppType]] 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.

Example

from esmerald import Esmerald

app = Esmerald(tags=["application"])

Example with nested routes

When tags are added on a level bases, those are concatenated into the final handler.

from esmerald import Esmerald, Gateway, get

@get("/home", tags=["home"])
async def home() -> Dict[str, str]:
    return {"hello": "world"}


app = Esmerald(
    routes=[Gateway(handler=home)],
    tags=["application"]
)

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

include_in_schema

Boolean flag indicating if all the routes of the application should be included in the OpenAPI documentation.

Note almost everything in Esmerald can be done in levels, which means when the application level is set to include_in_schema=False, no schemas will be displayed in the OpenAPI documentation.

Tip

This can be particularly useful if you have, for example, a ChildEsmerald and you don't want to include in the schema the routes of the said ChildEsmerald. This way there is no reason to do it route by route and instead you can simply do it directly in the application level.

Example

from esmerald import Esmerald

app = Esmerald(include_in_schema=False)

Example applied to ChildEsmerald

from esmerald import Esmerald, ChildEsmerald, Include

app = Esmerald(routes=[
    Include("/child", app=ChildEsmerald(
        include_in_schema=False
    ))
])

TYPE: Optional[bool] DEFAULT: None

deprecated

Boolean flag indicating if all the routes of the application should be deprecated in the OpenAPI documentation.

Tip

This can be particularly useful if you have, for example, a ChildEsmerald and you want to deprecate in favour of a new one being implemented.

Example

from esmerald import Esmerald

app = Esmerald(deprecated=True)

Example with a ChildEsmerald

from esmerald import Esmerald, ChildEsmerald, Include

app = Esmerald(routes=[
    Include("/child", app=ChildEsmerald(
        deprecated=True
    ))
])

TYPE: Optional[bool] DEFAULT: None

enable_openapi

Boolean flag indicating if the OpenAPI documentation should be generated or not.

When False, no OpenAPI documentation is accessible.

Tip

Disable this option if you run in production and no one should access the documentation unless behind an authentication.

```

TYPE: Optional[bool] DEFAULT: None

redirect_slashes

Boolean flag indicating if the redirect slashes are enabled for the routes or not.

TYPE: Optional[bool] DEFAULT: None

pluggables

A list of global pluggables from objects inheriting from esmerald.interceptors.interceptor.EsmeraldInterceptor.

Read more about how to implement the Plugables in Esmerald and to leverage them.

Example

from typing import Optional

from loguru import logger
from pydantic import BaseModel

from esmerald import Esmerald, Extension, Pluggable
from esmerald.types import DictAny


class PluggableConfig(BaseModel):
    name: str


class MyExtension(Extension):
    def __init__(
        self, app: Optional["Esmerald"] = None, config: PluggableConfig = None, **kwargs: "DictAny"
    ):
        super().__init__(app, **kwargs)
        self.app = app

    def extend(self, config: PluggableConfig) -> None:
        logger.success(f"Successfully passed a config {config.name}")


my_config = PluggableConfig(name="my extension")
pluggable = Pluggable(MyExtension, config=my_config)


app = Esmerald(
    routes=[], pluggables={"my-extension": pluggable}
)

TYPE: Optional[Dict[str, Pluggable]] DEFAULT: None

parent

Used internally by Esmerald to recognise and build the application levels.

Tip

Unless you know what are you doing, it is advisable not to touch this.

TYPE: Optional[Union[ParentType, Esmerald, ChildEsmerald]] DEFAULT: None

root_path_in_servers

Boolean flag use to disable the automatic URL generation in the servers field in the OpenAPI documentation.

Examples

from esmerald import Esmerald

app = Esmerald(root_path_in_servers=False)

TYPE: bool DEFAULT: None

webhooks

This is the same principle of the routes but for OpenAPI webhooks.

Read more about webhooks.

When a webhook is added, it will automatically add them into the OpenAPI documentation.

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

openapi_url

The URL where the OpenAPI schema will be served from. The default is /openapi.json.

Example

from esmerald import Esmerald

app = Esmerald(openapi_url="/api/v1/openapi.json")

TYPE: Optional[str] DEFAULT: None

Source code in esmerald/applications.py
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
def __init__(
    self: AppType,
    *,
    settings_module: Annotated[
        Optional["SettingsType"],
        Doc(
            """
            Alternative settings parameter. This parameter is an alternative to
            `ESMERALD_SETTINGS_MODULE` way of loading your settings into an Esmerald application.

            When the `settings_module` is provided, it will make sure it takes priority over
            any other settings provided for the instance.

            Read more about the [settings module](https://esmerald.dev/application/settings/)
            and how you can leverage it in your application.

            !!! Tip
                The settings module can be very useful if you want to have, for example, a
                [ChildEsmerald](https://esmerald.dev/routing/router/?h=childe#child-esmerald-application) that needs completely different settings
                from the main app.

                Example: A `ChildEsmerald` that takes care of the authentication into a cloud
                provider such as AWS and handles the `boto3` module.
            """
        ),
    ] = None,
    debug: Annotated[
        Optional[bool],
        Doc(
            """
            Boolean indicating if the application should return the debug tracebacks on
            server errors, in other words, if you want to have debug errors being displayed.

            Read more about this in the official [Lilya documentation](https://www.lilya.dev/applications/#applications).

            !!! Tip
                Do not use this in production.

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(debug=True)
            ```
            """
        ),
    ] = None,
    app_name: Annotated[
        Optional[str],
        Doc(
            """
            The name of the Esmerald application/API. This name is displayed when the
            [OpenAPI](https://esmerald.dev/openapi/) documentation is used.

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(app_name="Esmerald")
            ```
            """
        ),
    ] = None,
    title: Annotated[
        Optional[str],
        Doc(
            """
            The title of the Esmerald application/API. This title is displayed when the
            [OpenAPI](https://esmerald.dev/openapi/) documentation is used.

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(title="My awesome Esmerald application")
            ```
            """
        ),
    ] = None,
    version: Annotated[
        Optional[str],
        Doc(
            """
            The version of the Esmerald application/API. This version is displayed when the
            [OpenAPI](https://esmerald.dev/openapi/) documentation is used.

            **Note**: This is the version of your application/API and not th version of the
            OpenAPI specification being used by Esmerald.

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(version="0.1.0")
            ```
            """
        ),
    ] = None,
    summary: Annotated[
        Optional[str],
        Doc(
            """
            The summary of the Esmerald application/API. This short summary is displayed when the [OpenAPI](https://esmerald.dev/openapi/) documentation is used.

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(summary="Black Window joins The Pretenders.")
            ```
            """
        ),
    ] = None,
    description: Annotated[
        Optional[str],
        Doc(
            """
            The description of the Esmerald application/API. This description is displayed when the [OpenAPI](https://esmerald.dev/openapi/) documentation is used.

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(
                description='''
                            Black Window joins The Pretenders.

                            ## Powers

                            You can **activate_powers**

                            ## Skills

                            * **read_skill**
                            * **use_skill**
                            '''
            )
            ```
            """
        ),
    ] = None,
    contact: Annotated[
        Optional[Contact],
        Doc(
            """
            A dictionary or an object of type `openapi_schemas_pydantic.v3_1_0.Contact` containing the contact information of the application/API.

            Both dictionary and object contain several fields.

            * **name** - String name of the contact.
            * **url** - String URL of the contact. It **must** be in the format of a URL.
            * **email** - String email address of the contact. It **must** be in the format
            of an email address.

            **Example with object**

            ```python
            from esmerald import Esmerald
            from openapi_schemas_pydantic.v3_1_0 import Contact

            contact = Contact(
                name="Black Window",
                url="https://thepretenders.com/open-for-business",
                email="black.window@thepretenders.com,
            )

            app = Esmerald(contact=contact)
            ```

            **Example with dictionary**

            ```python
            from esmerald import Esmerald

            app = Esmerald(contact={
                "name": "Black Window",
                "url": "https://thepretenders.com/open-for-business",
                "email": "black.window@thepretenders.com,
            })
            ```
            """
        ),
    ] = None,
    terms_of_service: Annotated[
        Optional[AnyUrl],
        Doc(
            """
            A URL pointing to the Terms of Service of the application.
            This description is displayed when the [OpenAPI](https://esmerald.dev/openapi/) documentation is used.

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(terms_of_service="https://example.com/terms-of-service")
            ```
            """
        ),
    ] = None,
    license: Annotated[
        Optional[License],
        Doc(
            """
            A dictionary or an object of type `openapi_schemas_pydantic.v3_1_0.License` containing the license information of the application/API.

            Both dictionary and object contain several fields.

            * **name** - String name of the license.
            * **identifier** - An [SPDX](https://spdx.dev/) license expression.
            * **url** - String URL of the contact. It **must** be in the format of a URL.

            **Example with object**

            ```python
            from esmerald import Esmerald
            from openapi_schemas_pydantic.v3_1_0 import License

            license = License(
                name="MIT",
                url="https://opensource.org/license/mit/",
            )

            app = Esmerald(license=license)
            ```

            **Example with dictionary**

            ```python
            from esmerald import Esmerald

            app = Esmerald(license={
                "name": "MIT",
                "url": "https://opensource.org/license/mit/",
            })
            ```
            """
        ),
    ] = None,
    security: Annotated[
        Optional[List[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.

            **Example**

            ```python
            from esmerald import Esmerald
            from esmerald.openapi.security.http import Bearer

            app = Esmerald(security=[Bearer()])
            ```
            """
        ),
    ] = None,
    servers: Annotated[
        Optional[List[Dict[str, Union[str, Any]]]],
        Doc(
            """
            A `list` of python dictionaries with the information regarding the connectivity
            to the target.

            This can be useful, for example, if your application is served from different domains and you want a shared OpenAPI documentation to test it all.

            Esmerald automatically handles the OpenAPI documentation generation for you but
            sometimes you might want to add an extra custom domain to it.

            For example, when using `ChildEsmerald` modules, since the object itself subclasses
            Esmerald, that also means you can have independent documentation directly in the
            ChildEsmerald or access the [top level](https://esmerald.dev/application/levels/)
            documentation (the application itself) where you can select the server to test it.

            If the servers `list` is not provided or an is an empty `list`, the default value
            will be a `dict` with the `url` pointing to `/`.

            Each `dict` of the `list` follows the following format for the parameters:

            * **url** - A URL string to the target host/domain. The URL may support server
            variables and it may be also a relative server (for example, the domain/path of a `ChildEsmerald`).
            * **description** - An optional string description of the host/domain.
            * **variables** - A dictionary between the variable and its value. The value
            is used for substitution in the servers URL template. E.g.: `/my-domain/{age: int}`.

            You can read more about how the [OpenAPI](https://esmerald.dev/openapi/) documentation is used.

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(
                servers=[
                    {"url": "https://testing.example.com", "description": "Testing environment"},
                    {"url": "https://uat.example.com", "description": "UAT environment"},
                    {"url": "https://live.example.com", "description": "Production environment"},
                ]
            )
            ```
            """
        ),
    ] = None,
    secret_key: Annotated[
        Union[Optional[str], Optional["Secret"]],
        Doc(
            """
            A unique string value used for the cryptography. This value is also
            used internally by Esmerald with the JWT as well the
            [CSRFConfig](https://esmerald.dev/configurations/csrf/).

            !!! Tip
                Make sure you do not reuse the same secret key across environments as
                this can lead to security issues that you can easily avoid.

            **Example**

            ```python
            from esmerald import Esmerald

            aop = Esmerald(
                secret_key="p7!3cq1rapxd!@l=gz-&&k*h8sk_n8#1#+n6&q@cb&r!^z^2!g"
            )
            ```
            """
        ),
    ] = None,
    allowed_hosts: Annotated[
        Optional[List[str]],
        Doc(
            """
            A `list` of allowed hosts for the application. The allowed hosts when not specified
            defaults to `["*"]` but when specified.

            The allowed hosts are also what controls the
            [TrustedHostMiddleware](https://esmerald.dev/middleware/middleware/#trustedhostmiddleware) and you can read more about how to use it.

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(
                allowed_hosts=["*.example.com", "www.foobar.com"]
            )
            ```
            """
        ),
    ] = None,
    allow_origins: Annotated[
        Optional[List[str]],
        Doc(
            """
            A `list` of allowed origins hosts for the application.

            The allowed origins is used by the [CORSConfig](https://esmerald.dev/configurations/cors/) and controls the [CORSMiddleware](https://esmerald.dev/middleware/middleware/#corsmiddleware).

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(allow_origins=["*"])
            ```

            !!! Tip
                If you create your own [CORSConfig](https://esmerald.dev/configurations/cors/),
                this setting **is ignored** and your custom config takes priority.
            """
        ),
    ] = None,
    permissions: Annotated[
        Optional[Sequence["Permission"]],
        Doc(
            """
            A `list` of global permissions from objects inheriting from
            `esmerald.permissions.BasePermission`.

            Read more about how to implement the [Permissions](https://esmerald.dev/permissions/#basepermission-and-custom-permissions) in Esmerald and to leverage them.

            **Note** almost everything in Esmerald can be done in [levels](https://esmerald.dev/application/levels/), which means
            these permissions on a Esmerald instance, means **the whole application**.

            **Example**

            ```python
            from esmerald import Esmerald, BasePermission, Request
            from esmerald.types import APIGateHandler


            class IsAdmin(BasePermission):
                '''
                Permissions for admin
                '''
                async def has_permission(self, request: "Request", apiview: "APIGateHandler"):
                    is_admin = request.headers.get("admin", False)
                    return bool(is_admin)


            app = Esmerald(permissions=[IsAdmin])
            ```
            """
        ),
    ] = None,
    interceptors: Annotated[
        Optional[Sequence["Interceptor"]],
        Doc(
            """
            A `list` of global interceptors from objects inheriting from
            `esmerald.interceptors.interceptor.EsmeraldInterceptor`.

            Read more about how to implement the [Interceptors](https://esmerald.dev/interceptors/) in Esmerald and to leverage them.

            **Note** almost everything in Esmerald can be done in [levels](https://esmerald.dev/application/levels/), which means
            these interceptors on a Esmerald instance, means **the whole application**.

            **Example**

            ```python
            from loguru import logger
            from lilya.types import Receive, Scope, Send

            from esmerald import Esmerald
            from esmerald import EsmeraldInterceptor


            class LoggingInterceptor(EsmeraldInterceptor):
                async def intercept(self, scope: "Scope", receive: "Receive", send: "Send") -> None:
                    # Log a message here
                    logger.info("This is my interceptor being called before reaching the handler.")


            app = Esmerald(interceptors=[LoggingInterceptor])
            ```
            """
        ),
    ] = None,
    dependencies: Annotated[
        Optional["Dependencies"],
        Doc(
            """
            A dictionary of global dependencies. These dependencies will be
            applied to each **path** of the application.

            Read more about [Dependencies](https://esmerald.dev/dependencies/).

            **Example**

            ```python
            from esmerald import Esmerald, Inject

            def is_valid(number: int) -> bool:
                return number >= 5

            app = Esmerald(
                dependencies={
                    "is_valid": Inject(is_valid)
                }
            )
            ```
            """
        ),
    ] = None,
    csrf_config: Annotated[
        Optional["CSRFConfig"],
        Doc(
            """
            An instance of [CRSFConfig](https://esmerald.dev/configurations/csrf/).

            This configuration is passed to the [CSRFMiddleware](https://esmerald.dev/middleware/middleware/#csrfmiddleware) and enables the middleware.

            !!! Tip
                You can creatye your own `CRSFMiddleware` version and pass your own
                configurations. You don't need to use the built-in version although it
                is recommended to do it so.

            **Example**

            ```python
            from esmerald import Esmerald
            from esmerald.config import CSRFConfig

            csrf_config = CSRFConfig(secret="your-long-unique-secret")

            app = Esmerald(csrf_config=csrf_config)
            ```
            """
        ),
    ] = None,
    openapi_config: Annotated[
        Optional["OpenAPIConfig"],
        Doc(
            """
            An instance of [OpenAPIConfig](https://esmerald.dev/configurations/openapi/config/).

            This object is then used by Esmerald to create the [OpenAPI](https://esmerald.dev/openapi/) documentation.

            **Note**: Here is where the defaults for Esmerald OpenAPI are overriden and if
            this object is passed, then the previous defaults of the settings are ignored.

            !!! Tip
                This is the way you could override the defaults all in one go
                instead of doing attribute by attribute.

            **Example**

            ```python
            from esmerald import OpenAPIConfig

            openapi_config = OpenAPIConfig(
                title="Black Window",
                openapi_url="/openapi.json",
                docs_url="/docs/swagger",
                redoc_url="/docs/redoc",
            )

            app = Esmerald(openapi_config=openapi_config)
            ```
            """
        ),
    ] = None,
    openapi_version: Annotated[
        Optional[str],
        Doc(
            """
            The string version of the OpenAPI.

            Esmerald will generate the OpenAPI 3.1.0 by default and will
            output that as the OpenAPI version.

            If you need to somehow trick some of the tools you are using
            by setting a different version of the OpenAPI, this is the
            field you can use to do it so.

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(openapi_version="3.1.0")
            ```
            """
        ),
    ] = None,
    cors_config: Annotated[
        Optional["CORSConfig"],
        Doc(
            """
            An instance of [CORSConfig](https://esmerald.dev/configurations/cors/).

            This configuration is passed to the [CORSMiddleware](https://esmerald.dev/middleware/middleware/#corsmiddleware) and enables the middleware.

            **Example**

            ```python
            from esmerald import Esmerald
            from esmerald.config import CSRFConfig

            cors_config = CORSConfig(allow_origins=["*"])

            app = Esmerald(cors_config=cors_config)
            ```
            """
        ),
    ] = None,
    static_files_config: Annotated[
        Optional["StaticFilesConfig"],
        Doc(
            """
            An instance of [StaticFilesConfig](https://esmerald.dev/configurations/staticfiles/).

            This configuration is used to enable and serve static files via
            Esmerald application.

            **Example**

            ```python
            from esmerald import Esmerald
            from esmerald.config import StaticFilesConfig

            static_files_config = StaticFilesConfig(
                path="/static", directory=Path("static")
            )

            app = Esmerald(static_files_config=static_files_config)
            ```
            """
        ),
    ] = None,
    template_config: Annotated[
        Optional["TemplateConfig"],
        Doc(
            """
            An instance of [TemplateConfig](https://esmerald.dev/configurations/template/).

            This configuration is a simple set of configurations that when passed enables the template engine.

            !!! Note
                You might need to install the template engine before
                using this. You can always run
                `pip install esmerald[templates]` to help you out.

            **Example**

            ```python
            from esmerald import Esmerald
            from esmerald.config.template import TemplateConfig
            from esmerald.template.jinja import JinjaTemplateEngine

            template_config = TemplateConfig(
                directory=Path("templates"),
                engine=JinjaTemplateEngine,
            )

            app = Esmerald(template_config=template_config)
            ```
            """
        ),
    ] = None,
    session_config: Annotated[
        Optional["SessionConfig"],
        Doc(
            """
            An instance of [SessionConfig](https://esmerald.dev/configurations/session/).

            This configuration is passed to the [SessionMiddleware](https://esmerald.dev/middleware/middleware/#sessionmiddleware) and enables the middleware.

            **Example**

            ```python
            from esmerald import Esmerald
            from esmerald.config import SessionConfig

            session_config = SessionConfig(
                secret_key=settings.secret_key,
                session_cookie="session",
            )

            app = Esmerald(session_config=session_config)
            ```
            """
        ),
    ] = None,
    response_class: Annotated[
        Optional["ResponseType"],
        Doc(
            """
            Global default response class to be used within the
            Esmerald application.

            Read more about the [Responses](https://esmerald.dev/responses/) and how
            to use them.

            **Example**

            ```python
            from esmerald import Esmerald, JSONResponse

            app = Esmerald(response_class=JSONResponse)
            ```
            """
        ),
    ] = None,
    response_cookies: Annotated[
        Optional["ResponseCookies"],
        Doc(
            """
            A global sequence of `esmerald.datastructures.Cookie` objects.

            Read more about the [Cookies](https://esmerald.dev/extras/cookie-fields/?h=responsecook#cookie-from-response-cookies).

            **Example**

            ```python
            from esmerald import Esmerald
            from esmerald.datastructures import Cookie

            response_cookies=[
                Cookie(
                    key="csrf",
                    value="CIwNZNlR4XbisJF39I8yWnWX9wX4WFoz",
                    max_age=3000,
                    httponly=True,
                )
            ]

            app = Esmerald(response_cookies=response_cookies)
            ```
            """
        ),
    ] = None,
    response_headers: Annotated[
        Optional["ResponseHeaders"],
        Doc(
            """
            A global mapping of `esmerald.datastructures.ResponseHeader` objects.

            Read more about the [ResponseHeader](https://esmerald.dev/extras/header-fields/#response-headers).

            **Example**

            ```python
            from esmerald import Esmerald
            from esmerald.datastructures import ResponseHeader

            response_headers={
                "authorize": ResponseHeader(value="granted")
            }

            app = Esmerald(response_headers=response_headers)
            ```
            """
        ),
    ] = None,
    scheduler_class: Annotated[
        Optional["SchedulerType"],
        Doc(
            """
            Esmerald integrates out of the box with [Asyncz](https://asyncz.tarsild.io/)
            and the scheduler class is nothing more than the `AsyncIOScheduler` provided
            by the library.

            Read more about the [scheduler](https://esmerald.dev/scheduler/scheduler/?h=scheduler_class#esmeraldscheduler) and how to use.

            !!! Tip
                You can create your own scheduler class and use it with Esmerald.
                For that you must read the [Asyncz](https://asyncz.tarsild.io/schedulers/)
                documentation and how to make it happen.

            **Note** - To enable the scheduler, you **must** set the `enable_scheduler=True`.

            **Example**

            ```python
            from esmerald import Esmerald
            from asyncz.schedulers import AsyncIOScheduler

            app = Esmerald(scheduler_class=AsyncIOScheduler)
            ```
            """
        ),
    ] = None,
    scheduler_tasks: Annotated[
        Optional[Dict[str, str]],
        Doc(
            """
            Mapping in the format `<task-name>: <location>` indicating the tasks to
            be run by the scheduler.

            Read more about the [scheduler](https://esmerald.dev/scheduler/scheduler/?h=scheduler_class#esmeraldscheduler) and how to use.

            **Note** - To enable the scheduler, you **must** set the `enable_scheduler=True`.

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(
                enable_scheduler=True,
                scheduler_tasks={
                    "collect_market_data": "accounts.tasks",
                    "send_email_newsletter": "accounts.tasks",
                },
            )
            ```
            """
        ),
    ] = None,
    scheduler_configurations: Annotated[
        Optional[Dict[str, Union[str, Dict[str, str]]]],
        Doc(
            """
            Mapping of extra configuratioms being passed to the scheduler.
            These are [Asyncz Configurations](https://asyncz.tarsild.io/schedulers/?h=confi#example-configuration).

            **Example**

            ```python
            from esmerald import Esmerald

            configurations = {
                "asyncz.stores.mongo": {"type": "mongodb"},
                "asyncz.stores.default": {"type": "redis", "database": "0"},
                "asyncz.executors.threadpool": {
                    "max_workers": "20",
                    "class": "asyncz.executors.threadpool:ThreadPoolExecutor",
                },
                "asyncz.executors.default": {"class": "asyncz.executors.asyncio::AsyncIOExecutor"},
                "asyncz.task_defaults.coalesce": "false",
                "asyncz.task_defaults.max_instances": "3",
                "asyncz.task_defaults.timezone": "UTC",
            }

            app = Esmerald(
                scheduler_configurations=configurations
            )
            ```
            """
        ),
    ] = None,
    enable_scheduler: Annotated[
        Optional[bool],
        Doc(
            """
            Boolean flag indicating if the internal scheduler should be enabled
            or not.

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(enable_scheduler=True)
            ```
            """
        ),
    ] = None,
    timezone: Annotated[
        Optional[Union[dtimezone, str]],
        Doc(
            """
            Object of time `datetime.timezone` or string indicating the
            timezone for the application.

            **Note** - The timezone is internally used for the supported
            scheduler.

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(timezone="UTC")
            ```
            """
        ),
    ] = None,
    routes: Annotated[
        Optional[Sequence[Union["APIGateHandler", "Include"]]],
        Doc(
            """
            A global `list` of esmerald routes. Those routes may vary and those can
            be `Gateway`, `WebSocketGateWay` or even `Include`.

            This is also the entry-point for the routes of the application itself
            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 routing system 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/) about this.
            """
        ),
    ] = None,
    root_path: Annotated[
        Optional[str],
        Doc(
            """
            A path prefix that is handled by a proxy not seen in the
            application but seen by external libraries.

            This affects the tools like the OpenAPI documentation.

            **Example^^

            ```python
            from esmerald import Esmerald

            app = Esmerald(root_path="/api/v3")
            ```
            """
        ),
    ] = None,
    middleware: Annotated[
        Optional[Sequence["Middleware"]],
        Doc(
            """
            A global sequence of Lilya middlewares or `esmerald.middlewares` that are
            used by the application.

            Read more about the [Middleware](https://esmerald.dev/middleware/middleware/).

            **Example**

            ```python
            from esmerald import Esmerald
            from esmerald.middleware import HTTPSRedirectMiddleware, TrustedHostMiddleware

            app = Esmerald(
                routes=[...],
                middleware=[
                    DefineMiddleware(TrustedHostMiddleware, allowed_hosts=["example.com", "*.example.com"]),
                    DefineMiddleware(HTTPSRedirectMiddleware),
                ],
            )
            ```
            """
        ),
    ] = None,
    exception_handlers: Annotated[
        Optional["ExceptionHandlerMap"],
        Doc(
            """
            A global dictionary with handlers for exceptions.

            **Note** almost everything in Esmerald can be done in [levels](https://esmerald.dev/application/levels/), which means
            these exception handlers on a Esmerald instance, means **the whole application**.

            Read more about the [Exception handlers](https://esmerald.dev/exception-handlers/).

            **Example**

            ```python
            from pydantic.error_wrappers import ValidationError
            from esmerald import (
                Esmerald,
                JSONResponse,
                Request,
                ValidationErrorException,
            )

            async def validation_error_exception_handler(
                request: Request, exc: ValidationError
            ) -> JSONResponse:
                extra = getattr(exc, "extra", None)
                if extra:
                    return JSONResponse(
                        {"detail": exc.detail, "errors": exc.extra.get("extra", {})},
                        status_code=status.HTTP_400_BAD_REQUEST,
                    )
                else:
                    return JSONResponse(
                        {"detail": exc.detail},
                        status_code=status.HTTP_400_BAD_REQUEST,
                    )

            app = Esmerald(
                exception_handlers={
                        ValidationErrorException: validation_error_exception_handler,
                    },
            )
            ```
            """
        ),
    ] = None,
    on_startup: Annotated[
        Optional[List["LifeSpanHandler"]],
        Doc(
            """
            A `list` of events that are trigger upon the application
            starts.

            Read more about the [events](https://esmerald.dev/lifespan-events/).

            **Example**

            ```python
            from pydantic import BaseModel
            from saffier import Database, Registry

            from esmerald import Esmerald, Gateway, post

            database = Database("postgresql+asyncpg://user:password@host:port/database")
            registry = Registry(database=database)


            class User(BaseModel):
                name: str
                email: str
                password: str
                retype_password: str


            @post("/create", tags=["user"], description="Creates a new user in the database")
            async def create_user(data: User) -> None:
                # Logic to create the user
                ...


            app = Esmerald(
                routes=[Gateway(handler=create_user)],
                on_startup=[database.connect],
            )
            ```
            """
        ),
    ] = None,
    on_shutdown: Annotated[
        Optional[List["LifeSpanHandler"]],
        Doc(
            """
            A `list` of events that are trigger upon the application
            shuts down.

            Read more about the [events](https://esmerald.dev/lifespan-events/).

            **Example**

            ```python
            from pydantic import BaseModel
            from saffier import Database, Registry

            from esmerald import Esmerald, Gateway, post

            database = Database("postgresql+asyncpg://user:password@host:port/database")
            registry = Registry(database=database)


            class User(BaseModel):
                name: str
                email: str
                password: str
                retype_password: str


            @post("/create", tags=["user"], description="Creates a new user in the database")
            async def create_user(data: User) -> None:
                # Logic to create the user
                ...


            app = Esmerald(
                routes=[Gateway(handler=create_user)],
                on_shutdown=[database.disconnect],
            )
            ```
            """
        ),
    ] = None,
    lifespan: Annotated[
        Optional[Lifespan[AppType]],
        Doc(
            """
            A `lifespan` context manager handler. This is an alternative
            to `on_startup` and `on_shutdown` and you **cannot used all combined**.

            Read more about the [lifespan](https://esmerald.dev/lifespan-events/).
            """
        ),
    ] = None,
    tags: Annotated[
        Optional[List[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.

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(tags=["application"])
            ```

            **Example with nested routes**

            When tags are added on a level bases, those are concatenated into the
            final handler.

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

            @get("/home", tags=["home"])
            async def home() -> Dict[str, str]:
                return {"hello": "world"}


            app = Esmerald(
                routes=[Gateway(handler=home)],
                tags=["application"]
            )
            ```
            """
        ),
    ] = None,
    include_in_schema: Annotated[
        Optional[bool],
        Doc(
            """
            Boolean flag indicating if all the routes of the application
            should be included in the OpenAPI documentation.

            **Note** almost everything in Esmerald can be done in [levels](https://esmerald.dev/application/levels/), which means when the application
            level is set to `include_in_schema=False`, no schemas will be
            displayed in the OpenAPI documentation.

            !!! Tip
                This can be particularly useful if you have, for example, a `ChildEsmerald` and
                you don't want to include in the schema the routes of the said `ChildEsmerald`.
                This way there is no reason to do it route by route and instead you can
                simply do it directly in the application [level](https://esmerald.dev/application/levels/).

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(include_in_schema=False)
            ```

             **Example applied to ChildEsmerald**

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

            app = Esmerald(routes=[
                Include("/child", app=ChildEsmerald(
                    include_in_schema=False
                ))
            ])
            ```
            """
        ),
    ] = None,
    deprecated: Annotated[
        Optional[bool],
        Doc(
            """
            Boolean flag indicating if all the routes of the application
            should be deprecated in the OpenAPI documentation.

            !!! Tip
                This can be particularly useful if you have, for example, a `ChildEsmerald` and
                you  want to deprecate in favour of a new one being implemented.

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(deprecated=True)
            ```

            **Example with a ChildEsmerald**

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

            app = Esmerald(routes=[
                Include("/child", app=ChildEsmerald(
                    deprecated=True
                ))
            ])
            ```
            """
        ),
    ] = None,
    enable_openapi: Annotated[
        Optional[bool],
        Doc(
            """
            Boolean flag indicating if the OpenAPI documentation should
            be generated or not.

            When `False`, no OpenAPI documentation is accessible.

            !!! Tip
                Disable this option if you run in production and no one should access the
                documentation unless behind an authentication.
            ```
            """
        ),
    ] = None,
    redirect_slashes: Annotated[
        Optional[bool],
        Doc(
            """
            Boolean flag indicating if the redirect slashes are enabled for the
            routes or not.
            """
        ),
    ] = None,
    pluggables: Annotated[
        Optional[Dict[str, Pluggable]],
        Doc(
            """
            A `list` of global pluggables from objects inheriting from
            `esmerald.interceptors.interceptor.EsmeraldInterceptor`.

            Read more about how to implement the [Plugables](https://esmerald.dev/pluggables/) in Esmerald and to leverage them.

            **Example**

            ```python
            from typing import Optional

            from loguru import logger
            from pydantic import BaseModel

            from esmerald import Esmerald, Extension, Pluggable
            from esmerald.types import DictAny


            class PluggableConfig(BaseModel):
                name: str


            class MyExtension(Extension):
                def __init__(
                    self, app: Optional["Esmerald"] = None, config: PluggableConfig = None, **kwargs: "DictAny"
                ):
                    super().__init__(app, **kwargs)
                    self.app = app

                def extend(self, config: PluggableConfig) -> None:
                    logger.success(f"Successfully passed a config {config.name}")


            my_config = PluggableConfig(name="my extension")
            pluggable = Pluggable(MyExtension, config=my_config)


            app = Esmerald(
                routes=[], pluggables={"my-extension": pluggable}
            )
            ```
            """
        ),
    ] = None,
    parent: Annotated[
        Optional[Union["ParentType", "Esmerald", "ChildEsmerald"]],
        Doc(
            """
            Used internally by Esmerald to recognise and build the [application levels](https://esmerald.dev/application/levels/).

            !!! Tip
                Unless you know what are you doing, it is advisable not to touch this.
            """
        ),
    ] = None,
    root_path_in_servers: Annotated[
        bool,
        Doc(
            """
            Boolean flag use to disable the automatic URL generation in the `servers` field
            in the OpenAPI documentation.

            **Examples**

            ```python
            from esmerald import Esmerald

            app = Esmerald(root_path_in_servers=False)
            ```
            """
        ),
    ] = None,
    webhooks: Annotated[
        Optional[Sequence["gateways.WebhookGateway"]],
        Doc(
            """
            This is the same principle of the `routes` but for OpenAPI webhooks.

            Read more [about webhooks](https://esmerald.dev/routing/webhooks).

            When a webhook is added, it will automatically add them into the
            OpenAPI documentation.
            """
        ),
    ] = None,
    openapi_url: Annotated[
        Optional[str],
        Doc(
            """
            The URL where the OpenAPI schema will be served from.
            The default is `/openapi.json`.

            **Example**

            ```python
            from esmerald import Esmerald

            app = Esmerald(openapi_url="/api/v1/openapi.json")
            ```
            """
        ),
    ] = None,
) -> None:
    self.settings_module = None
    if settings_module is not None:
        if not isinstance(settings_module, EsmeraldAPISettings) and not is_class_and_subclass(
            settings_module, EsmeraldAPISettings
        ):
            raise ImproperlyConfigured(
                "settings_module must be a subclass of EsmeraldSettings"
            )
        elif isinstance(settings_module, EsmeraldAPISettings):
            self.settings_module = settings_module  # type: ignore
        elif is_class_and_subclass(settings_module, EsmeraldAPISettings):
            self.settings_module = settings_module()  # type: ignore

    assert lifespan is None or (
        on_startup is None and on_shutdown is None
    ), "Use either 'lifespan' or 'on_startup'/'on_shutdown', not both."

    if allow_origins and cors_config:
        raise ImproperlyConfigured("It can be only allow_origins or cors_config but not both.")

    self.parent = parent

    self._debug = self.load_settings_value("debug", debug, is_boolean=True)
    self.debug = self._debug

    self.title = self.load_settings_value("title", title)
    self.app_name = self.load_settings_value("app_name", app_name)
    self.description = self.load_settings_value("description", description)
    self.version = self.load_settings_value("version", version)
    self.openapi_version = self.load_settings_value("openapi_version", openapi_version)
    self.summary = self.load_settings_value("summary", summary)
    self.contact = self.load_settings_value("contact", contact)
    self.terms_of_service = self.load_settings_value("terms_of_service", terms_of_service)
    self.license = self.load_settings_value("license", license)
    self.servers = self.load_settings_value("servers", servers)
    self.secret_key = self.load_settings_value("secret_key", secret_key)
    self.allowed_hosts = self.load_settings_value("allowed_hosts", allowed_hosts)
    self.allow_origins = self.load_settings_value("allow_origins", allow_origins)
    self.permissions = self.load_settings_value("permissions", permissions) or []
    self.interceptors = self.load_settings_value("interceptors", interceptors) or []
    self.dependencies = self.load_settings_value("dependencies", dependencies) or {}
    self.csrf_config = self.load_settings_value("csrf_config", csrf_config)
    self.cors_config = self.load_settings_value("cors_config", cors_config)
    self.openapi_config = self.load_settings_value("openapi_config", openapi_config)
    self.template_config = self.load_settings_value("template_config", template_config)
    self.static_files_config = self.load_settings_value(
        "static_files_config", static_files_config
    )
    self.session_config = self.load_settings_value("session_config", session_config)
    self.response_class = self.load_settings_value("response_class", response_class)
    self.response_cookies = self.load_settings_value("response_cookies", response_cookies)
    self.response_headers = self.load_settings_value("response_headers", response_headers)
    self.scheduler_class = self.load_settings_value("scheduler_class", scheduler_class)
    self.scheduler_tasks = self.load_settings_value("scheduler_tasks", scheduler_tasks) or {}
    self.scheduler_configurations = (
        self.load_settings_value("scheduler_configurations", scheduler_configurations) or {}
    )
    self.enable_scheduler = self.load_settings_value(
        "enable_scheduler", enable_scheduler, is_boolean=True
    )
    self.timezone = self.load_settings_value("timezone", timezone)
    self.root_path = self.load_settings_value("root_path", root_path)
    self._middleware = self.load_settings_value("middleware", middleware) or []
    _exception_handlers = self.load_settings_value("exception_handlers", exception_handlers)
    self.exception_handlers = {} if _exception_handlers is None else dict(_exception_handlers)
    self.on_startup = self.load_settings_value("on_startup", on_startup)
    self.on_shutdown = self.load_settings_value("on_shutdown", on_shutdown)
    self.lifespan = self.load_settings_value("lifespan", lifespan)
    self.tags = self.load_settings_value("tags", security)
    self.include_in_schema = self.load_settings_value(
        "include_in_schema", include_in_schema, is_boolean=True
    )
    self.security = self.load_settings_value("security", security)
    self.enable_openapi = self.load_settings_value(
        "enable_openapi", enable_openapi, is_boolean=True
    )
    self.redirect_slashes = self.load_settings_value(
        "redirect_slashes", redirect_slashes, is_boolean=True
    )
    self.pluggables = self.load_settings_value("pluggables", pluggables)

    # OpenAPI Related
    self.root_path_in_servers = self.load_settings_value(
        "root_path_in_servers", root_path_in_servers, is_boolean=True
    )

    if not self.include_in_schema or not self.enable_openapi:
        self.root_path_in_servers = False

    self.webhooks = self.load_settings_value("webhooks", webhooks) or []
    self.openapi_url = self.load_settings_value("openapi_url", openapi_url)
    self.tags = self.load_settings_value("tags", tags)

    self.openapi_schema: Optional["OpenAPI"] = None
    self.state: Annotated[
        State,
        Doc(
            """
            The state object for the application. This is always the
            same object across the whole application.

            This can be defined as the application state and not request state
            which means that it does not change each request.

            Learn more in the [Lilya documentation](https://www.lilya.dev/applications/#storing-state-on-the-app-instance).
            """
        ),
    ] = State()
    self.async_exit_config = esmerald_settings.async_exit_config

    self.router: "Router" = Router(
        on_shutdown=self.on_shutdown,
        on_startup=self.on_startup,
        routes=routes,
        app=self,
        lifespan=self.lifespan,
        deprecated=deprecated,
        security=security,
        redirect_slashes=self.redirect_slashes,
    )

    self.get_default_exception_handlers()
    self.user_middleware = self.build_user_middleware_stack()
    self.middleware_stack = self.build_middleware_stack()
    self.pluggable_stack = self.build_pluggable_stack()
    self.template_engine = self.get_template_engine(self.template_config)

    self._configure()