Metadata-Version: 2.1
Name: ob_graphql
Version: 0.0.1
Summary: A simple GraphQL client that works over Websocket as the transport protocol, instead of HTTP.
Home-page: https://github.com/obytes/ob-graphql
Author: Yasser Tahiri
Author-email: yasserth19@gmail.com
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Utilities
Classifier: Typing :: Typed
Requires-Dist: websocket-client
Requires-Dist: mkdocs ; extra == "docs"
Requires-Dist: mkdocs-markdownextradata-plugin ; extra == "docs"
Requires-Dist: mkdocs-material ; extra == "docs"
Requires-Dist: jinja2 ; extra == "docs"
Requires-Dist: mkdocs-mermaid2-plugin ; extra == "docs"
Requires-Dist: markdown-include ; extra == "docs"
Requires-Dist: pymdown-extensions ; extra == "docs"
Requires-Dist: mdx-include ; extra == "docs"
Requires-Dist: pre-commit==2.18.0 ; extra == "lint"
Provides-Extra: docs
Provides-Extra: lint

# Ob-Graphql

[![Linting](https://github.com/obytes/ob-graphql/actions/workflows/lint.yml/badge.svg)](https://github.com/obytes/ob-graphql/actions/workflows/lint.yml)
[![Test](https://github.com/obytes/ob-graphql/actions/workflows/test.yml/badge.svg)](https://github.com/obytes/ob-graphql/actions/workflows/test.yml)

Setup a simple GraphQL client over websocket using [apollo-transport-ws](https://github.com/apollographql/subscriptions-transport-ws/blob/master/PROTOCOL.md) protocol.

## GraphQL over WebSocket Protocol

### Client-server communication

Each message has a `type` field, which defined in the protocol of this package, as well as associated fields inside `payload` field, depending on the message type, and `id` field so the client can identify each response from the server.

Each WebSocket message is represented in JSON structure, and being stringified before sending it over the network.

This is the structure of each message:

```typescript
export interface OperationMessage {
  payload?: any;
  id?: string;
  type: string;
}
```

## Install

```bash
pip install ob_graphql
```

- Ob-Graphql depends on [websocket-client](https://pypi.org/project/websocket-client/) is a WebSocket client for Python. It provides access to low level APIs for WebSockets.

## Examples

### Setup subscriptions super easily

```python
from ob_graphql import OBQLClient

query = """
  subscription {
    notifications {
      id
      title
      content
    }
  }
"""


def callback(_id, data):
    print("got new data..")
    print(f"msg id: {_id}. data: {data}")


with OBQLClient("ws://localhost:8080/graphql") as client:

    sub_id = client.subscribe(query, callback=callback)
    client.stop_subscribe(sub_id)
```

### Variables can be passed

```python
from ob_graphql import OBQLClient

query = """
    subscription ($limit: Int!) {
      notifications (order_by: {created: "desc"}, limit: $limit) {
        id
        title
        content
      }
    }
  """

def callback(_id, data):
     print("got new data..")
     print(f"msg id: {_id}. data: {data}")

with OBQLClient('ws://localhost:8080/graphql') as client:
  sub_id = client.subscribe(query, variables={'limit': 10}, callback=callback)

```

### Headers can be passed too

```python
from ob_graphql import OBQLClient

query = """
    subscription ($limit: Int!) {
      notifications (order_by: {created: "desc"}, limit: $limit) {
        id
        title
        content
      }
    }
  """


def callback(_id, data):
    print("got new data..")
    print(f"msg id: {_id}. data: {data}")


with OBQLClient("ws://localhost:8080/graphql") as client:
    sub_id = client.subscribe(
        query,
        variables={"limit": 10},
        headers={"Authorization": "Bearer xxxx"},
        callback=callback,
    )
    client.stop_subscribe(sub_id)
```

### Normal queries and mutations work too

```python
from ob_graphql import OBQLClient

query = """
  query ($limit: Int!) {
    notifications (order_by: {created: "desc"}, limit: $limit) {
      id
      title
      content
    }
  }
"""

with OBQLClient('ws://localhost:8080/graphql') as client:
    res = client.query(query, variables={'limit': 10}, headers={'Authorization': 'Bearer xxxx'})
    print(res)
```

### Without the context manager API

```python
from ob_graphql import OBQLClient

query = """
  query ($limit: Int!) {
    notifications (order_by: {created: "desc"}, limit: $limit) {
      id
      title
      content
    }
  }
"""

client = OBQLClient('ws://localhost:8080/graphql')
res = client.query(query, variables={'limit': 10}, headers={'Authorization': 'Bearer xxxx'})
print(res)
client.close()
```

