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 or disables any quotes with -1:

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

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}}

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.1.tar.gz (12.4 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.1-py2.py3-none-any.whl (7.4 kB view details)

Uploaded Python 2Python 3

File details

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

File metadata

  • Download URL: graphql-from-struct-1.0.1.tar.gz
  • Upload date:
  • Size: 12.4 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.1.tar.gz
Algorithm Hash digest
SHA256 288f3bcdd6f648c7601fae446f89093122ac443bac899d6b91ab4159b9bc210e
MD5 bffc4e89955fb12976be804866ad34de
BLAKE2b-256 f9a54e975884e735d43323067c12ef0b232360207fffe5db59667e4b85c90818

See more details on using hashes here.

File details

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

File metadata

  • Download URL: graphql_from_struct-1.0.1-py2.py3-none-any.whl
  • Upload date:
  • Size: 7.4 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.1-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 6b75f61c0d03579f081ffe8db354a633cdd27286d3874c5ed1f1cb018aa59035
MD5 af78aacbd92f6debb0091d5429a1f4a6
BLAKE2b-256 2356580642e9cf6bb3e3c071074c50dbfe396279c3928bc511968394e603378e

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