-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add docs on how to cosume graphql with python
- Loading branch information
1 parent
d097a78
commit 4945c32
Showing
1 changed file
with
139 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
# Consume GraphQL API using Python | ||
|
||
## Preface | ||
|
||
This guide will explain how fetch data from a GraphQL endpoint and map the response to a | ||
Pydantic model. | ||
We will cover: | ||
|
||
- Defining a Pydantic model in [Define the Pydantic Model](#define-the-pydantic-model) | ||
- Fetching the data from GraphQL API in [Fetch Data from GraphQL API](#fetch-data-from-graphql-api) | ||
- Mapping the response to the Pydantic model in [Map Response Pydantic Model](#map-response-to-pydantic-model) | ||
|
||
## Dependencies | ||
|
||
This guide will utilize the following dependencies: | ||
|
||
- `requests` to send HTTP request to the GraphQL endpoint | ||
- `pydantic` for validating and parsing the fetched data | ||
|
||
## Define the Pydantic Model | ||
|
||
Pydantic is a data validation and parsing library in Python. It provides a efficient way to | ||
validate and parse data into Python objects. We can use pydantic models to define the structure and type | ||
of data we intend to fetch from the enpoint. It automatically validates the input data based on | ||
the defined type annotations. If the data does not match the expected types, Pydantic raises errors | ||
ensuring the integrity of the data. | ||
|
||
To defind a Pydantic model, we define a class with Pydantic's `BaseModel` class as the base class. | ||
We can define a `Person` class with the attributes we intend to fetch from the endpoint. | ||
|
||
!!! example "Define Pydantic Model" | ||
|
||
```python | ||
from pydantic import BaseModel | ||
|
||
class Person(BaseModel): | ||
id: int | ||
first_name: str | ||
last_name: str | ||
|
||
``` | ||
!!! info | ||
|
||
Refer to the [How to Guide for Python Service docs](https://diamondlightsource.github.io/graph-federation/how-tos/python_service/) to learn more about the GraphQL API structure | ||
|
||
## Fetch Data From GraphQL API | ||
|
||
To fetch data from a GraphQL API, we use the `requests` library to send a POST request with a GraphQL query. | ||
We specify the GraphQL query as a string. | ||
|
||
!!! example "Define Pydantic Model" | ||
|
||
```python | ||
import requests | ||
|
||
url = 'http://127.0.0.1:8000/graphql' | ||
graphql_query = """ | ||
query { | ||
person { | ||
id, | ||
firstName, | ||
lastName, | ||
} | ||
} | ||
""" | ||
|
||
response = requests.post(url, json={'query': graphql_query}) | ||
|
||
``` | ||
## Map Response to Pydantic Model | ||
|
||
We can now map the json response we got from the endpoint to a Pydantic model by mapping the response fields to | ||
the Pydantic model fields. | ||
|
||
!!! example "Define Pydantic Model" | ||
|
||
```python | ||
response_data = response.json() | ||
|
||
# Extract the person data from the response | ||
person_data = response_data['data']['person'] | ||
|
||
# Map the GraphQL response fields to the Pydantic model fields | ||
person = Person( | ||
id=person_data['id'], | ||
first_name=person_data['firstName'], | ||
last_name=person_data['lastName'] | ||
|
||
``` | ||
|
||
We can define a function `fetch_person` to fetch and map the `Person` data to the Pydantic model. | ||
|
||
!!! example "Fetch and Map Person Data" | ||
|
||
```python | ||
def fetch_person(): | ||
url = 'http://127.0.0.1:8000/graphql' | ||
query = """ | ||
query { | ||
person { | ||
id, | ||
firstName, | ||
lastName, | ||
} | ||
} | ||
""" | ||
|
||
response = requests.post(url, json={'query': query}) | ||
response_data = response.json() | ||
|
||
person_data = response_data['data']['person'] | ||
person = Person( | ||
id=person_data['id'], | ||
first_name=person_data['firstName'], | ||
last_name=person_data['lastName'] | ||
) | ||
return person | ||
|
||
``` | ||
!!! tip | ||
|
||
Ensure robustness by handling potential validation errors using `pydantic.ValidationError` | ||
|
||
Finally, we can use the function to fetch and print the person data: | ||
|
||
!!! example "Fetch data from GraphQL" | ||
|
||
```python | ||
if __name__ == "__main__": | ||
person = fetch_person() | ||
if person: | ||
print(person) | ||
``` | ||
|
||
If the [Python graphQL service](https://diamondlightsource.github.io/graph-federation/how-tos/python_service/) is running, executing | ||
the script should output: | ||
|
||
`id=1 first_name='foo' last_name='bar'` |