ASGI Fundamentals 2: Application classes vs. functions
TLDRThis video from ASGI Fundamentals explores the distinction between application callables and application classes within the context of building asynchronous Python web applications. It explains that according to the ASGI standard, an application is an asynchronous callable that takes three parameters: a scope dictionary, and receive and send functions. However, when using frameworks like FastAPI or Starlette, applications are typically defined as instances of a class rather than a single callable function. The video clarifies that these frameworks still adhere to the ASGI specification by using a `__call__` method within the class, which is an asynchronous callable. The `__call__` method is demonstrated in FastAPI's source code, confirming that instances of the FastAPI class are indeed asynchronous callables. The video argues for the use of application classes over functions, as classes can hold state and maintain configuration settings, which is useful for managing multiple instances of applications or sub-applications. It also discusses the benefits of using classes for organization and the avoidance of global variables, making the application more modular and testable.
Takeaways
- 📚 ASGI standard defines an application as a single asynchronous callable with three parameters: a scope dictionary, and receive/send functions.
- 🤔 While ASGI specifies an application as a callable, frameworks like FastAPI and Starlette allow you to define applications as instances of a class.
- 👀 FastAPI and Starlette applications are indeed asynchronous callables, as they implement an `__call__` method that is an async function.
- 🔄 The `__call__` method in these frameworks takes the same parameters as required by the ASGI spec: scope, receive, and send.
- 🧩 Middleware, responses, and routers are also ASGI applications and can be asynchronous callables, even if not immediately apparent.
- 📦 Application classes are preferred for holding state and maintaining configuration, such as routes, middleware, startup events, and exception handling.
- 🔑 Classes are useful to avoid using global variables and to encapsulate information specific to a single instance of an application.
- 👥 In scenarios where multiple application instances are needed, such as running different ASGI applications simultaneously or for testing purposes, classes provide a structured approach.
- 🛠️ Instances of application classes have bound parameters, simplifying the callable interface to just three parameters: scope, receive, and send.
- 💡 Defining an application as a class is beneficial for complex applications that require extensive configuration and state management.
- ⚖️ The choice between a function or a class for an application depends on the complexity and requirements of the application, with classes being more suitable for most real-world applications.
Q & A
What is the ASGI standard?
-The ASGI standard defines an application as a single asynchronous callable that takes three parameters: a scope dictionary, and receive and send functions, which allow communication with the client.
Why do frameworks like Starlet or FastAPI use class instances instead of a single callable?
-Frameworks use class instances to allow for the definition of asynchronous callables through the use of a Dunder call method, which provides flexibility and the ability to maintain state and configuration.
How does the Dunder call method relate to ASGI applications?
-The Dunder call method is an async def function that takes a scope, a receive, and a send, making instances of a class, like those in FastAPI, asynchronous callables and thus compliant with the ASGI specification.
What are the benefits of using an application class over a simple function?
-Application classes allow for holding state and maintaining configuration, which is useful for managing various aspects like routes, middleware, startup events, and exception handling.
Why might you have more than one application object during the same run?
-You might have multiple application objects to run multiple ASGI applications simultaneously, to have sub-applications mounted at different paths, or to create independent applications for testing purposes.
What is the role of the scope dictionary in an ASGI application?
-The scope dictionary provides information about the current connection, which is essential for the application to understand the context of the request and respond accordingly.
How does the receive function work in an ASGI application?
-The receive function is an asynchronous function that allows the application to receive messages from the client associated with the current connection.
What is the purpose of the send function in the context of ASGI?
-The send function is used to send messages to the client, enabling the application to respond to the client's requests or push updates to the client.
Can middleware and responses also be considered ASGI applications?
-Yes, many objects such as middleware, responses, and routers can act as ASGI applications if they are asynchronous callables, even if it's not immediately apparent from their initial appearance.
Why might global variables still be used in an application?
-Global variables might be used for configurations or objects that are truly global in nature, like login configurations, but specific configurations for an application instance should be stored within the application class.
What is the significance of the Dunder call method in making class instances callable?
-The Dunder call method allows an instance of a class to be treated as a callable by defining how the instance should respond when it is called, which is essential for making class instances comply with the ASGI standard.
How does the use of an application class pattern benefit the structure of a web application?
-The application class pattern provides a structured way to manage application-specific configurations and state, which improves maintainability and allows for better organization of the application's components.
Outlines
🚀 Introduction to Asynchronous Python Web Applications
The video begins with an introduction to asynchronous Python web applications, focusing on the concept of application callables and classes as defined by the ASGI (Asynchronous Server Gateway Interface) standard. It explains that an application is a single asynchronous callable that accepts a scope dictionary, and receive and send functions for client communication. The video then contrasts this with the typical class-based application definition seen in frameworks like Starlet and FastAPI. It clarifies that these frameworks do indeed support the ASGI specification by implementing an async Dunder call method, making instances of their classes also asynchronous callables.
🤔 The Role of Classes in Defining ASGI Applications
The video script delves into why developers might choose to use class instances as their ASGI applications rather than simple functions. It argues that classes are beneficial for holding state and maintaining configuration settings such as routes, middleware, startup events, and exception handling. The use of classes allows for the management of multiple application instances, which could be necessary for running multiple ASGI applications simultaneously, having sub-applications, or ensuring test modules are independent. The video emphasizes the advantages of using classes over global variables for application-specific configurations.
Mindmap
Keywords
💡ASGI
💡Application Callables
💡Scope Dictionary
💡Receive and Send Functions
💡Async Def
💡Dunder Call Method
💡FastAPI
💡State
💡Invariance
💡Global Variables
💡Sub Applications
Highlights
The ASGI standard defines an application as a single asynchronous callable with three parameters: a scope dictionary, and receive and send functions.
Frameworks like Starlet or FastAPI allow you to define an application as an instance of a class, which is also an asynchronous callable.
To make instances of a class callable, a `__call__` method is defined within the class.
FastAPI's source code includes a `__call__` method that is an async function, taking a scope, receive, and send parameters.
Instances of the FastAPI class and Starlette applications are asynchronous callables, as per the ASGI specification.
Middleware, responses, and routers are also considered ASGI applications in the context of the ASGI spec.
An asynchronous callable application doesn't need to be a literal `async def` function; it can be an instance of a class with an async `__call__` method.
The `__call__` method of an app class instance has its self parameter bound, acting similarly to a traditional app with three parameters.
Defining an application as an instance of an app class is preferred for maintaining state and configuration for different application instances.
Classes are useful for holding state and maintaining invariance in real applications, as opposed to using global variables.
An application class can hold various configurations such as routes, middleware, startup events, and exception handling.
Using global variables is still common for truly global objects, but application-specific configurations should be stored within the application object.
Having more than one application object during the same run is common, for instance, running two ASGI applications simultaneously or having sub-applications.
Sub-applications can be mounted at different paths, such as one at '/api' and another at the root.
Constructing multiple applications can be necessary for testing purposes, to ensure test modules are independent.
The presenter, James Murphy, thanks patrons and donors for their support and mentions his software consultancy company, M Coding.