MCPcopy Index your code
hub / github.com/cancan101/graphql-db-api

github.com/cancan101/graphql-db-api @main

Chat with this repo
repository ↗ · DeepWiki ↗ · + Follow
77 symbols 269 edges 11 files 10 documented · 13%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

graphql-db-api PyPI version main workflow codecov

A Python DB API 2.0 for GraphQL APIs

This module allows you to query GraphQL APIs using SQL.

SQLAlchemy support

This module provides a SQLAlchemy dialect.

from sqlalchemy.engine import create_engine

# Over HTTPS (default):
engine_https = create_engine('graphql://host:port/path')

# Over HTTP:
engine_http = create_engine('graphql://host:port/path?is_https=0')

# With a `Bearer` token in the `Authorization` header:
engine_http = create_engine('graphql://:token@host:port/path')

Example Usage

Querying Connections

from sqlalchemy import create_engine
from sqlalchemy import text

# We use GraphQL SWAPI (The Star Wars API) c/o Netlify:
engine = create_engine('graphql://swapi-graphql.netlify.app/.netlify/functions/index')

# Demonstration of requesting nested resource of homeworld
# and then selecting fields from it
query = "select name, homeworld__name from 'allPeople?include=homeworld'"

with engine.connect() as connection:
    for row in connection.execute(text(query)):
        print(row)

Querying Lists

We can mark a given GQL query as being a List when we query that "Table" using a query parameter:

from sqlalchemy import create_engine
from sqlalchemy import text

engine = create_engine('graphql://pet-library.moonhighway.com/')

# The default assumes top level is a Connection.
# For Lists, we must disable this:
query = "select id, name from 'allPets?is_connection=0'"

with engine.connect() as connection:
    for row in connection.execute(text(query)):
        print(row)

alternatively, we can set that at the Engine level:

from sqlalchemy import create_engine
from sqlalchemy import text

# We mark 'allPets' as being a List at the Engine level:
engine = create_engine(
    'graphql://pet-library.moonhighway.com/',
    list_queries=["allPets"],
)

query = "select id, name from allPets"

with engine.connect() as connection:
    for row in connection.execute(text(query)):
        print(row)

Superset support

In order to use with Superset, install this package and then use the graphql protocol in the SQLAlchemy URI like: graphql://swapi-graphql.netlify.app/.netlify/functions/index. We install a db_engine_spec so Superset should recognize the driver.

Roadmap

  • [x] Non-Connections top level
  • [x] Path traversal (basic)
  • [ ] Path traversal (basic + nested)
  • [ ] Path traversal (list / connection)
  • [x] Bearer Tokens in Authorization Header
  • [ ] Advanced Auth (e.g. with token refresh)
  • [ ] Passing Headers (e.g. Auth in other locations)
  • [ ] Filtering
  • [ ] Sorting
  • [x] Relay Pagination

Core symbols most depended-on inside this repo

extract_flattened_value
called by 8
graphqldb/adapter.py
status
called by 7
setup.py
system
called by 7
setup.py
get_gql_fields
called by 7
graphqldb/adapter.py
parse_gql_type
called by 6
graphqldb/adapter.py
_parse_query_args
called by 6
graphqldb/adapter.py
get_last_query
called by 6
graphqldb/lib.py
_get_variable_argument_str
called by 4
graphqldb/adapter.py

Shape

Function 46
Method 20
Class 11

Languages

Python100%

Modules by API surface

graphqldb/adapter.py26 symbols
setup.py11 symbols
tests/test_dialect.py10 symbols
tests/test_adapter.py10 symbols
tests/conftest.py7 symbols
graphqldb/dialect.py6 symbols
tests/test_lib.py3 symbols
graphqldb/lib.py3 symbols
graphqldb/db_engine_specs.py1 symbols

For agents

$ claude mcp add graphql-db-api \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact