9. The context
15m

Overview

We've got a client ready to fetch data from the Spotify API. We could use this client directly in our , but that would lead to quite a bit of code duplication. Instead, we'll use the context feature of Strawberry to create the client once and share it across all .

In this lesson, we will:

  • Learn about the context in Strawberry
  • Learn how to use the info to access the context in our s

What is the context?

The context in Strawberry is an object that allows us to pass any kind of data to our . Usually, it's used for things like database connections or authentication information.

We'll be using context to share the Spotify client across all our .

Instantiating the client

To create an instance of the Spotify client, we'll make use of FastAPI's lifespan feature.

FastAPI's lifespan

FastAPI's lifespan feature enables us to run code when the application starts and stops. This is useful for setting up resources that need to be created once and shared across requests (just like our Spotify client!).

Open up the main.py file, where all the server code lives.

We'll import a few things at the top: the asynccontextmanager (which we'll need for the lifespan), the mock_spotify_rest_api_client.client, and Request from FastAPI.

main.py
from contextlib import asynccontextmanager
from mock_spotify_rest_api_client.client import Client
from fastapi import Request

Next, we can define the lifespan function, decorating it with @asynccontextmanager.

main.py
@asynccontextmanager
async def lifespan(app):
...

Inside, we'll instantiate the Client class, giving it the base_url parameter with the Spotify API endpoint as the value. We'll also name this instance as spotify_client.

main.py
@asynccontextmanager
async def lifespan(app):
async with Client(
base_url="https://spotify-demo-api-fe224840a08c.herokuapp.com/v1"
) as spotify_client:
...

To make spotify_client available in the FastAPI app, we can yield an object containing it. This object will be available on the request object under request.state later on.

main.py
yield {"spotify_client": spotify_client}

Note: Code before the yield function runs before the application starts. You can read more about FastAPI's lifespan in the docs.

Finally, let's pass the lifespan into the FastAPI constructor down below.

main.py
app = FastAPI(lifespan=lifespan)

Great! The FastAPI app has access to the Spotify client, but we still need to pass it along to the using context.

Creating the context object

Let's start by defining an async function called context_getter. It accepts an called request of type Request.

main.py
async def context_getter(request: Request):
...

The request object represents the request, which includes the GraphQL and any HTTP headers. Additionally, it contains the spotify_client object we set up in the lifespan function earlier!

We can now access the spotify_client object from the request.state object.

main.py
spotify_client = request.state.spotify_client

Then, we'll return an object, representing the context object. Inside, we'll include the spotify_client.

main.py
return {"spotify_client": spotify_client}

Finally, down below, we'll pass this context_getter function into the context_getter parameter of the GraphQLRouter class.

main.py
graphql_router = GraphQLRouter(
schema, path="/", graphql_ide="apollo-sandbox", context_getter=context_getter
)

Strawberry automatically calls the context_getter on every request and passes the result to the via the info , which we'll tackle in the next lesson.

Key takeaways

  • The context in Strawberry allows us to pass data to our . We use the context_getter parameter in GraphQLRouter to return a custom context object.
  • FastAPI's lifespan allows us to create resources that need to be shared across requests.

Up next

It's time for the function to start making real requests to the Spotify API.

Previous

Share your questions and comments about this lesson

This course is currently in

beta
. Your feedback helps us improve! If you're stuck or confused, let us know and we'll help you out. All comments are public and must follow the Apollo Code of Conduct. Note that comments that have been resolved or addressed may be removed.

You'll need a GitHub account to post below. Don't have one? Post in our Odyssey forum instead.