ASGI Fundamentals 2: Application classes vs. functions

mCoding
6 May 202403:51

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

00:00

🚀 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

ASGI stands for Asynchronous Server Gateway Interface, which is a Python web framework standard for asynchronous web applications. It defines how web servers communicate with asynchronous Python web applications, allowing for the creation of scalable and efficient web services. In the video, ASGI is the central theme as it discusses the fundamentals of building asynchronous Python web applications using the ASGI standard.

💡Application Callables

Application callables are a core concept in ASGI, referring to any Python object that can be called to handle a web request. They are defined as single asynchronous callables that take three parameters: a scope dictionary, and receive and send functions. In the context of the video, application callables are contrasted with application classes, highlighting that they can be either a function or an instance of a class with an async callable method.

💡Scope Dictionary

The scope dictionary is a data structure that contains information about the current HTTP request, such as the type of connection, client information, and other relevant details. It is one of the three parameters passed to an ASGI application callable, allowing the application to understand the context of the request it is handling. The video emphasizes its role in providing information about the current connection.

💡Receive and Send Functions

Receive and send functions are asynchronous functions used in ASGI to facilitate communication between the web server and the application. The receive function is used to get messages from the client, while the send function is used to send messages to the client. These functions are part of the three parameters that an ASGI application callable must accept, enabling the asynchronous handling of web requests.

💡Async Def

Async def is a keyword in Python used to define an asynchronous function, which can be paused and resumed. This is essential in ASGI as it allows for non-blocking I/O operations, making web applications more efficient and scalable. The video mentions async def in the context of defining an asynchronous callable method within a class, which is a way to make instances of the class callable in ASGI applications.

💡Dunder Call Method

The 'dunder' call method, short for 'double underscore call', is a special method in Python denoted by __call__. When defined in a class, it allows an instance of that class to be used as if it were a function. In the video, it is shown that the FastAPI class has a __call__ method, which makes instances of the class act as asynchronous callables, thus conforming to the ASGI standard.

💡FastAPI

FastAPI is a modern, fast (high-performance), web framework for building APIs with Python based on standard Python type hints. It is one of the frameworks mentioned in the video as an example of how application classes can be used to define ASGI applications. The video discusses how FastAPI's class instances are made callable to fit the ASGI application model.

💡State

In the context of object-oriented programming, state refers to the data or information that an object holds. The video explains that using application classes allows developers to maintain state within the application object, which is useful for configuring various aspects of the application, such as routes, middleware, and exception handling.

💡Invariance

Invariance in programming refers to the property of an object to maintain a consistent state or behavior under certain conditions. The video discusses how using classes for ASGI applications can help maintain invariance, as it allows for the encapsulation of application-specific data and behavior within the class.

💡Global Variables

Global variables are variables that are defined in a global scope and can be accessed from any part of the program. The video contrasts the use of global variables with the use of class instances for application-specific data. It suggests that while global variables might be used for truly global configurations, class instances are preferable for data specific to a single application instance.

💡Sub Applications

Sub applications refer to smaller, modular parts of a larger application that can be mounted at different endpoints within the main application. The video discusses how using class instances for ASGI applications allows for the creation of sub applications, which can be beneficial for organizing and isolating different parts of a web application.

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.