Skip to main content

Makes a GraphQL query from Python data structures.

Project description

License Release Docs Code Coverage Build Status Travis CI Blog

GraphQL-From-Struct

A simple one-method library makes a GraphQL query from Python data structures.

Table of Contents

  1. Installation

  2. Usage

  3. Exceptions

  4. Parameters

  5. Reserved keywords

  6. Examples

Installation

pip install graphql_from_struct

Usage

# 1. Import GqlFromStruct class

from graphql_from_struct import GqlFromStruct

# 2. Make a query

struct = {'hero':{'@fields':['name']}}

# 3. Generate GraphQL

gql = GqlFromStruct.from_struct(struct)

# Or use OOP-style:

foo = GqlFromStruct(struct)

gql = foo.query()

print (gql)

You should see such result:

query{
        hero{
                name
            }
    }

Exceptions

The module raises GqlFromStructException in case of empty or wrong data structure input.

Parameters

GqlFromStruct() constructor and .from_struct() method take 3 arguments: a struct (default None), a minimize (optional, default False) flag and a force_quotes (optional, default 0) setting. Code:

foo = GqlFromStruct({'hero':{'@fields':['name']}}, True)

# or foo = GqlFromStruct(struct = {'hero':{'@fields':['name']}}, minimize = True)

gql = foo.query()

# or

gql = GqlFromStruct.from_struct({'hero':{'@fields':['name']}}, True)

print (gql)

gives you:

query{hero{name}}

By default the GraphQL-From-Struct sets quotes for any string with spaces. You can change it with the force_quotes flag. It enforces quoting parameters and arguments with 1 value, disables any quotes with -1 or enables only arguments quoting with 2:

gql = GqlFromStruct.from_struct({'hero':{'@fields':['name']}}, True, 1)

print (gql)

gives you:

"query"{"hero"{"name"}}

Or

gql = GqlFromStruct.from_struct({'he ro':{'@fields':['name']}}, True, -1)

print (gql)

gives you:

query{he ro{name}}

Or

gql = GqlFromStruct.from_struct('human':{'@fields':['name', 'height'], '@args':{'id':['foo', 'bar']}}, True, 2)

print (gql)

gives you:

query{human(id:["foo", "bar"]){name height}}

Reserved keywords

Words @alias, @args, @fields, @fragments, @fragment_name, @directives, @include, @mutations, @operation_name, @queries, @query, @skip, @variables are reserved and used for query constructing.

Examples

Examples are shown in the same order as in the GraphQL documentation.

Fields

Use @fields keyword:

struct = {'hero':{'@fields':['name']}}

print (GqlFromStruct.from_struct(struct))

Output:

query{
        hero{
                name
            }
    }

You can use arbitrary field nesting:

struct = {'hero':{'@fields':['name', {'friends':{'@fields':['name']}}]}}

print (GqlFromStruct.from_struct(struct))

Output:

query{
        hero{
                name
                friends{
                        name
                    }
            }
    }

Arguments

Use @args keyword:

struct = {'human':{'@fields':['name', 'height'], '@args':{'id':'"1000"'}}}

print (GqlFromStruct.from_struct(struct))

Output:

query{
        human(
            id : "1000"
            ){
                name
                height
            }
    }

or:

struct = {
  'human': {
    '@fields': ['name', {
      'height': {
        '@args': {
          'unit': 'FOOT'
        }
      }
    }],
    '@args': {
      'id': "1000"
    }
  }
}

print (GqlFromStruct.from_struct(struct))

Output:

query{
        human(
            id : 1000
            ){
                name
                height(
                    unit : FOOT
                    )
            }
    }

Note: GraphQL-From-Struct puts double quotes by default only for values with spaces. Like that:

query = {'human':{'@fields':['name', 'height'], '@args':{'id':'1000 meters'}}}

Output:

query{
        human(
            id : "1000 meters"
            ){
                name
                height
            }
    }

Single words or numerical values are output in the form in which you passed them.

query = {'human':{'@fields':['name', 'height'], '@args':{'id':1000}}}
query{
        human(
            id : 1000
            ){
                name
                height
            }
    }
Default arguments

You can set default values of arguments:

struct = {'human':{'@fields':['name', 'height'], '@args':{'$first': {'Int':'3'}}}

print (GqlFromStruct.from_struct(struct))

Output:

query{
        human(
            $first : Int = 3
            ){
                name
                height
            }
    }

Aliases

Use @alias keyword:

struct = [{
  'hero': {
    '@alias': 'empireHero',
    '@args': {
      'episode': "EMPIRE"
    },
    '@fields': ['name']
  }
}, {
  'hero': {
    '@alias': 'jediHero',
    '@args': {
      'episode': "JEDI"
    },
    '@fields': ['name']
  }
}]

print (GqlFromStruct.from_struct(struct))

Output:

query{
        empireHero : hero(
            episode : EMPIRE
            ){
                name
            }
        jediHero : hero(
            episode : JEDI
            ){
                name
            }
    }

Fragments

Use @fragments and @fragment_name keywords for fragments setting up. Use @query and @queries for join some queries into one.

struct = {
            "@queries": [{
              '@query': [{
                  'hero': {
                    '@alias': 'leftComparison',
                    '@args': {
                      'episode': "EMPIRE"
                    },
                    '@fields': ['...comparisonFields']
                  }
                },
                {
                  'hero': {
                    '@alias': 'rightComparison',
                    '@args': {
                      'episode': "JEDI"
                    },
                    '@fields': ['...comparisonFields']
                  }
                }
              ]
            }],
            "@fragments": [{
              'Character': {
                '@fragment_name': 'comparisonFields',
                '@fields': ['name', 'appearsIn', {
                  'friends': {
                    '@fields': ['name']
                  }
                }]
              }
            }]
          }

print (GqlFromStruct.from_struct(struct))

Output:

query{
        leftComparison : hero(
            episode : EMPIRE
            ){
                ...comparisonFields
            }
        rightComparison : hero(
            episode : JEDI
            ){
                ...comparisonFields
            }
    }
fragment comparisonFields on Character{
        name
        appearsIn
        friends{
                name
            }
    }
Using variables inside fragments
struct = {
  "@queries": [{
    '@args': {
      '$first': {
        'Int': '3'
      }
    },
    '@operation_name': 'HeroComparison',
    '@query': [{
        'hero': {
          '@alias': 'leftComparison',
          '@args': {
            'episode': "EMPIRE"
          },
          '@fields': ['...comparisonFields']
        }
      },
      {
        'hero': {
          '@alias': 'rightComparison',
          '@args': {
            'episode': "JEDI"
          },
          '@fields': ['...comparisonFields']
        }
      }
    ]
  }],
  "@fragments": [{
    'Character': {
      '@fragment_name': 'comparisonFields',
      '@fields': ['name', {
        'friendsConnection': {
          '@args': {
            'first': '$first'
          },
          '@fields': ['totalCount', {
            'edges': {
              '@fields': [{
                'node': {
                  '@fields': ['name']
                }
              }]
            }
          }]
        }
      }]
    }
  }]
}

print (GqlFromStruct.from_struct(struct))

Output:

query HeroComparison (
$first : Int = 3
){
        leftComparison : hero(
            episode : EMPIRE
            ){
                ...comparisonFields
            }
        rightComparison : hero(
            episode : JEDI
            ){
                ...comparisonFields
            }
    }
fragment comparisonFields on Character{
        name
        friendsConnection(
            first : $first
            ){
                totalCount
                edges{
                        node{
                                name
                            }
                    }
            }
    }

Operation name

Use @operation_name keyword:

struct =  {
   '@queries': [{
     '@operation_name': 'HeroNameAndFriends',
     '@query': {
       'hero': {
         '@fields': ['name', {
           'friends': {
             '@fields': ['name']
           }
         }]
       }
     }
   }]
 }

print (GqlFromStruct.from_struct(struct))

Output:

query HeroNameAndFriends{
        hero{
                name
                friends{
                        name
                    }
            }
    }

Variables

Use @variables block at the same high level nesting as @queries:

struct = {
            '@queries': [{
              '@operation_name': 'HeroNameAndFriends',
              '@query': {
                'hero': {
                  '@fields': ['name', {
                    'friends': {
                      '@fields': ['name']
                    }
                  }]
                }
              }
            }],
            '@variables': {
              "episode": "JEDI"
            }
          }

print (GqlFromStruct.from_struct(struct))

Output:

query HeroNameAndFriends{
        hero{
                name
                friends{
                        name
                    }
            }
    }
{
    "episode": "JEDI"
}
Default variables

Use @fields keyword:

struct =  {
            '@queries': [{
              '@operation_name': 'HeroNameAndFriends',
              '@args': {
                '$episode': {
                  'Episode': 'JEDI'
                }
              },
              '@query': {
                'hero': {
                  '@fields': ['name', {
                    'friends': {
                      '@fields': ['name']
                    }
                  }]
                }
              }
            }],
            '@variables': {
              "episode": "JEDI"
            }
          }

print (GqlFromStruct.from_struct(struct))

Output:

query HeroNameAndFriends (
$episode : Episode = JEDI
){
        hero{
                name
                friends{
                        name
                    }
            }
    }
{
    "episode": "JEDI"
}

Directives

Use @directives keyword and @skip or @include as directives:

struct = {
  '@queries': [{
    '@operation_name': 'Hero',
    '@args': {
      '$episode': 'Episode',
      '$withFriends': 'Boolean!'
    },
    '@query': {
      'hero': {
        '@args': {
          'episode': '$episode'
        },
        '@fields': ['name', {
          'friends': {
            '@fields': ['name'],
            '@directives': {
              '@include': '$withFriends'
            }
          }
        }]
      }
    }
  }],
  '@variables': {
    "episode": "JEDI"
  }
}

print (GqlFromStruct.from_struct(struct))

Output:

query Hero (
$episode : Episode,
$withFriends : Boolean!
){
        hero(
            episode : $episode
            ){
                name
                friends @include (if :  $withFriends){
                        name
                    }
            }
    }
{
    "episode": "JEDI"
}

Mutations

Use @mutations keyword:

struct = {
  '@mutations': [{
    '@operation_name': 'CreateReviewForEpisode',
    '@args': {
      '$episode': 'Episode!',
      '$review': 'ReviewInput!'
    },
    '@query': {
      'createReview': {
        '@args': {
          'episode': '$ep',
          'review': '$review'
        },
        '@fields': ['stars', 'commentary']
      }
    }
  }],
  '@variables': {
    "episode": "JEDI",
    "review": {
      "stars": 5,
      "commentary": "This is a great movie!"
    }
  }
}

print (GqlFromStruct.from_struct(struct))

Output:

mutation CreateReviewForEpisode (
$episode : Episode!,
$review : ReviewInput!
){
        createReview(
            episode : $ep,
            review : $review
            ){
                stars
                commentary
            }
    }
{
    "episode": "JEDI",
    "review": {
        "stars": 5,
        "commentary": "This is a great movie!"
    }
}

Inline Fragments

Nothing special needed.

struct =  {
   "@queries": [{
     '@args': {
       '$ep': 'Episode!'
     },
     '@operation_name': 'HeroForEpisode',
     '@query': [{
       'hero': {
         '@args': {
           'episode': '$ep'
         },
         '@fields': ['name',
           {
             '... on Droid': {
               '@fields': ['primaryFunction']
             }
           },
           {
             '... on Human': {
               '@fields': ['height']
             }
           }
         ]
       }
     }]
   }]
 }

print (GqlFromStruct.from_struct(struct))

Output:

query HeroForEpisode (
$ep : Episode!
){
        hero(
            episode : $ep
            ){
                name
                ... on Droid{
                        primaryFunction
                    }
                ... on Human{
                        height
                    }
            }
    }

Meta fields

Use meta field as usual field:

struct = {
  'search': {
    '@args': {
      'text': 'an'
    },
    '@fields': ['__typename',
      {
        '... on Human': {
          '@fields': ['name']
        }
      },
      {
        '... on Droid': {
          '@fields': ['name']
        }
      },
      {
        '... on Starship': {
          '@fields': ['name']
        }
      }
    ]
  }
}

print (GqlFromStruct.from_struct(struct))

Output:

query{
        search(
            text : an
            ){
                __typename
                ... on Human{
                        name
                    }
                ... on Droid{
                        name
                    }
                ... on Starship{
                        name
                    }
            }
    }

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

graphql-from-struct-1.0.2.tar.gz (12.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

graphql_from_struct-1.0.2-py2.py3-none-any.whl (7.5 kB view details)

Uploaded Python 2Python 3

File details

Details for the file graphql-from-struct-1.0.2.tar.gz.

File metadata

  • Download URL: graphql-from-struct-1.0.2.tar.gz
  • Upload date:
  • Size: 12.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.7.0 requests/2.25.1 setuptools/49.2.1 requests-toolbelt/0.9.1 tqdm/4.56.2 CPython/3.9.1

File hashes

Hashes for graphql-from-struct-1.0.2.tar.gz
Algorithm Hash digest
SHA256 d1923da9f88529d247649b8f0e1e2826e5974819e75b9a68f114dcc7b957257c
MD5 5fb57b12bf18a6525fc51f680455a630
BLAKE2b-256 86596b58cdb9b2e3c5bd9c95766adab81061044c2d242ac8a1a671696b249ec7

See more details on using hashes here.

File details

Details for the file graphql_from_struct-1.0.2-py2.py3-none-any.whl.

File metadata

  • Download URL: graphql_from_struct-1.0.2-py2.py3-none-any.whl
  • Upload date:
  • Size: 7.5 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.7.0 requests/2.25.1 setuptools/49.2.1 requests-toolbelt/0.9.1 tqdm/4.56.2 CPython/3.9.1

File hashes

Hashes for graphql_from_struct-1.0.2-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 7b6c3b33936a42e566822ac9f20809250246dcf82645c4093d03b75ebc1f0d34
MD5 204968280cbc2a05ca277a0f71743ea6
BLAKE2b-256 8bcec624a39a9311015c21b8e227f336585bba7c66ca2d72ae962ae1254e2b79

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page