Overview
The data that our resolvers retrieve can come from all kinds of places: a database, a third-party API, webhooks, and so on. These are called data sources. The beauty of GraphQL is that you can mix any number of data sources to create an API that serves the needs of your client applications and graph consumers.
In this lesson, we will:
- Examine the existing Spotify REST API, the perfect data source for MusicMatcher
- Generate a Python client using an OpenAPI specification to handle our HTTP requests, responses and types
The Spotify Web API
MusicMatcher needs music, and for this course, we're going to be using a lite, pared-down version of the official Spotify Web API. We can access that version here: https://spotify-demo-api-fe224840a08c.herokuapp.com/v1/docs/
Let's explore the documentation. We've got a few endpoints available for us centered around playlistsβ in fact, it's all we need to implement the features we covered earlier!
Diving into the /browse/featured-playlists
endpoint, let's click "Try it out", then "Execute" a request.
We get a JSON object back with two top-level properties: message
and playlists
. Inside the playlists
property, we have an items
property, which contains a list, as well as a few other properties that seem to be related to pagination (like limit
, next
, previous
, offset
). And then the items
list contains objects with its own properties. These objects represent a playlist!
That's a lot of nested properties just to get to what we want β the list of featured playlists!
The shape of the response from our HTTP endpoints often doesn't exactly match what we want to return from our GraphQL schema's types and fields. And that's okay! One of the benefits of GraphQL is that we only expose what the client may need. In this iteration of the schema for example, we only need to expose the name, description and ID of a playlist.
The HTTP responses also come back in JSON (JavaScript Object Notation) format, whereas in Python we're dealing with classes. For these reasons, we'll need to do some conversions, serializing, and deserializing our HTTP response types to our Python types.
A common way to make HTTP requests and handle responses is with the httpx library.
In this course, we want to focus on the GraphQL concepts, not fiddling around manually writing types from a REST API. To help make our work go faster, we're going to auto-generate the code to fetch the data from our API.
Auto-generating an HTTP Client
We'll use a OpenAPI Python client to generate a Python client based on an OpenAPI specification.
We've already included a openapi.json
file in your project inside the data
folder. This OpenAPI file defines the endpoints, expected responses, and schemas for response objects.
We'll use openapi-python-client
from the command line so let's install it! We'll be using pipx to install the package and its dependencies.
Open a new terminal and run the following command.
pipx install openapi-python-client --include-deps
We should get this message as a result:
Installed package openapi-python-client 0.19.0, installed using Python 3.12.2
Finally, we'll run the command to use openapi-python-client
to generate:
openapi-python-client generate --meta none --path data/openapi.json
This command performs the following steps:
- Takes the
openapi.json
file as an input - Generates a Python module called
mock_spotify_rest_api_client
- Generates a
Client
class inside that module
The terminal output should look something like this:
Generating mock_spotify_rest_api_client
The generated package will have a structure similar to this:
π¦ mock_spotify_rest_api_clientβ£ π __init__.pyβ£ π apiβ β£ π __init__.pyβ β π playlistsβ β β£ π __init__.pyβ β β£ π add_tracks_to_playlist.pyβ β β£ π get_featured_playlists.pyβ β β£ π get_playlist.pyβ β β£ π get_playlists_tracks.pyβ β β π search.pyβ£ π modelsβ β β£ π __init__.pyβ β β£ ...β β β π spotify_response_post_playlistsidtracks.pyβ£ π client.pyβ£ π errors.pyβ π types.py
The api
folder contains the endpoints we can use to interact with the Spotify REST API. For example, the get_featured_playlists.py
file contains functions that map to the GET /browse/featured-playlists
endpoint (it has both sync and async functions).
The models
folder contains the classes that represent the responses from the Spotify REST API.
Finally, the client.py
file contains the Client
class that we will use to make requests to the Spotify REST API.
We're almost ready to make use of this data source; one last thing! We need to install the dependencies of the auto-generated HTTP Client
: httpx
and attrs
.
Let's activate our virtual environment.
source .venv/bin/activate
And install the dependencies:
pip install httpx attrs
Practice
Client
class generated by openapi-python-client
?Key takeaways
- GraphQL allows the use of various data sources, such as databases, REST APIs, and webhooks, to create a flexible API that caters to client application needs.
- A GraphQL schema does not need to follow the shape, pattern, or naming of the data sources it uses.
- We can use the
openapi-python-client
tool to auto-generate a Python HTTP Client based on an OpenAPI specification, simplifying the handling of HTTP requests and responses.
Up next
In the next lesson, we'll connect the pieces to make this data source available to our resolvers, using Strawberry's context
feature.
Share your questions and comments about this lesson
This course is currently in
You'll need a GitHub account to post below. Don't have one? Post in our Odyssey forum instead.