Skip to content

Commit

Permalink
add docs on how to cosume graphql with python
Browse files Browse the repository at this point in the history
  • Loading branch information
iamvigneshwars committed Jul 8, 2024
1 parent d097a78 commit 4945c32
Showing 1 changed file with 139 additions and 0 deletions.
139 changes: 139 additions & 0 deletions docs/how-tos/python_consume.md
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'`

0 comments on commit 4945c32

Please sign in to comment.