1   Introduction

You can generate modules that contain code to support GraphQL queries. The queries can be applied to the data contained in XML instance documents described by the XML schema from which you generated your module. For information about GraphQL see -- https://graphql.org/.

Important: This capability requires generateDS version 2.43.2 or later.

The generated code uses the Strawberry GraphQL Python module. See https://pypi.org/project/strawberry-graphql/ and https://strawberry.rocks.

In order to use the generateDS support for GraphQL, you must install Strawberry. See the Strawberry getting started guide at https://strawberry.rocks/docs.

This facility supports GraphQL queries. There is no support for mutations.

For information on generateDS see http://www.davekuhlman.org/generateDS.html.

For information on GraphQL see https://graphql.org/.

There is an example of the use of this capability in the Demos/People directory within the generateDS source distribution, which you can clone with the following:

$ hg clone http://hg.code.sf.net/p/generateds/code generateds-code

Please post suggestions and questions at https://sourceforge.net/p/generateds/discussion/general/.

2   Generate a module containing GraphQL support

In order to generate a module that contains this support code, use the "--graphql=" command line option when you run generateDS.py. For example:

$ generateDS.py -o my_module.py --graphql="tagname:typename" my_xml_schema.xsd

Where:

  • tagname is the tag of the top-most element in your XML instance documents.
  • typename is the name of the XML complexType for the top-most element in your XML instance documents.

You have now generated a GraphQL API against which you can apply GraphQL queries. These queries follow the nested structure of your XML instance document. At each level, you have access to the child nodes and the attributes of the nodes at that level.

3   Run the Strawberry server

After generating your module, you can run the Strawberry server that the module implements with something like the following:

$ strawberry server my_module

Important -- Before running the Strawberry server on your module, you must set the environment variable GRAPHQL_ARGS to specify the path/name of an XML instance document that contains the data to which you want to apply GraphQL queries. This XML document must be an instance of the document type of the schema used to generate your module and should validate against that schema.

I'm on Linux, and so I can do that with, for example, either of the following, assuming that "my_module.py" is the name of the module generated by generateDS.py:

$ export GRAPHQL_ARGS=my_input_data.xml
$ strawberry server my_module

Or, on a single line:

$ GRAPHQL_ARGS=my_input_data.xml strawberry server my_module

For help with starting the Strawberry server, run the following:

$ strawberry --help
$ strawberry server --help

4   Make requests and queries

After starting Strawberry, you can interact with your Strawberry server in the following ways (among others):

  • Visit http://0.0.0.0:8000/graphql in your Web browser and use the Strawberry interactive REPL (read–eval–print loop). Note that interactive Strawberry supports tab completion and provides visual hints to guide you through your generated GraphQL API. Alternatively, near the upper left of the screen (in your Web browser) is a button that will display a GraphQL Explorer, which, among other things, will describe your GraphQL API.

  • Use cUrl to make requests (see https://curl.se/) and receive JSON data. For example, here is a bash shell script that I can run from the Linux command line:

    #!/usr/bin/bash -x
    
    curl 'http://0.0.0.0:8000/graphql' \
      -X POST \
      -H 'content-type: application/json' \
      --data '{
        "query": "{ container { author { name book { author title date genre rating }}}}"
      }'
    
  • Use a Python script and the Python requests module (see https://pypi.org/project/requests/ and https://requests.readthedocs.io/en/latest/). For example:

    #!/usr/bin/env python
    
    """
    synopsis:
        Demonstration of Python requests to a Strawberry GraphQL server.
    usage:
        python request01.py
    """
    
    import requests
    # import json
    
    def test():
        headers = {
            'content-type': 'application/json',
        }
        url = "http://0.0.0.0:8000/graphql"
        query = ('{ "query": "{ container { author '
                 '{ name book {author title date rating genre}}}}"  }')
        response = requests.post(url, query, headers=headers)
        jsonobj = response.json()
        data = jsonobj["data"]
        container = data["container"]
        author = container["author"]
        for item in author:
            print('name: {}'.format(item["name"]))
            for item1 in item["book"]:
                print(
                    '    author: {}  date: {}  title: "{}" '
                    'genre: "{}"  rating: {}'.format(
                        item1["author"],
                        item1["date"],
                        item1["title"],
                        item1["genre"],
                        item1["rating"],
                    ))
    
    def main():
        test()
    
    if __name__ == "__main__":
        main()
    

5   Examples of usage

The examples below are intended to show how to prepare and run generatDS GraphQL servers. They may or may not have uses in the real world.

5.1   NeuroML and libNeuroML

References:

Instructions:

  1. Download the repository -- https://github.com/NeuroML/NeuroML2.git

  2. Build the server module:

    $ ./generateDS.py \
        -f \
        -o tmp01.py \
        --graphql="neuroml:NeuroMLDocument" \
        ../Git/NeuroML2/Schemas/NeuroML2/NeuroML_v2.2.xsd
    
  3. Run the server -- We need to set an environment variable GRAPHQL_ARGS. On Linux, I can do the following. On other platforms, you may need to make an adjustment:

    $ GRAPHQL_ARGS=../Git/NeuroML2/examples/NML2_FullCell.nml strawberry server tmp01
    

5.2   OpenAstronomyLog

References:

Instructions:

  1. Download the repository -- https://github.com/openastronomylog/openastronomylog

  2. Build the server module:

    $ ./generateDS.py -f -o tmp01.py -g observations:observations openastronomylog-master/src/oal21.xsd
    
  3. Run the server:

    $ GRAPHQL_ARGS=openastronomylog-master/doc/OAL20_simple_example.xml strawberry server tmp01
    

5.3   Nexml

Instructions:

  1. Download the Nexml repository -- https://github.com/nexml/nexml.git. For example:

    $ mkdir MyTestDir
    $ cd MyTestDir
    $ git clone https://github.com/nexml/nexml.git
    
  2. Build the server module. For example:

    $ ./generateDS.py -f -o tmp01.py --graphql="Nexml:Nexml" ./nexml/xsd/nexml.xsd
    
  3. Run the server -- Here are several data sets that seem to produce reasonable results:

    $ GRAPHQL_ARGS=./nexml/examples/characters.xml strawberry server tmp01
    $ GRAPHQL_ARGS=./nexml/examples/tolskeletaldump-nexml.xml strawberry server tmp01
    

If you run the server in the basic way (as above), you can explore your data in your Web browser at http://0.0.0.0:8000/graphql

And, here is a shell script that makes a request:

#!/usr/bin/bash -x

echo
curl 'http://0.0.0.0:8000/graphql' \
  -X POST \
  -H 'content-type: application/json' \
  --data '{ "query": "{ Nexml { characters { format { states { id state { id } } char { id states } } } } }" }' \
  | python -m json.tool
echo

Here is a roughly equivalent Python script:

#!/usr/bin/env python

import requests
import pprint

Query05 = """
{ "query":
"{
  Nexml {
    characters {
      format {
        states {
          id
          state {
            id
          }
        }
        char {
          id
          states
        }
      }
    }
  }
}"
}
"""

def test():
    headers = {
        'content-type': 'application/json',
    }
    url = "http://0.0.0.0:8000/graphql"
    query = Query05
    query = query.replace('\n', ' ')
    response = requests.post(url, query, headers=headers)
    jsonobj = response.json()
    data = jsonobj["data"]
    print('-' * 40)
    pprint.pprint(data)
    print('-' * 40)

def main():
    test()

if __name__ == "__main__":
    main()

5.4   Demos/People in the generateDS repository

There is a reasonably usable example in the generateDS source code distribution.

References:

Instructions:

There are scripts that can be used to build and run the server. See Demos/People/run-gen-graphql.sh and ./Demoes/People/run-test-graphql.sh.

  1. Download the generateDS repository -- https://sourceforge.net/p/generateds/code/ci/default/tree/

  2. Use ./Demos/People/run-gen-graphql.sh (or the following) to generate a module that implements a Strawberry GraphQL server:

    $ generateDS.py \
        -f \
        -o people_graphql.py \
        --namespacedef='xmlns:pl="http://kuhlman.com/people.xsd"' \
        -c people_catalog.xml \
        --graphql="people:peopleType" \
        people.xsd
    
  3. Run the Strawberry GraphQL server (use ./Demoes/People/run-test-graphql.sh) or the following:

    $ GRAPHQL_ARGS=people.xml strawberry server people_graphql
    

5.5   Emdb -- the Electron Microscopy Data Bank

Emdb provides a good test for generateDS + GraphQL.

Use these instructions to try it out:

  1. (Optional) Create and switch to an empty directory in which to create files and run your test.

  2. In that directory, run the following:

    #!/usr/bin/bash -x
    
    wget https://ftp.ebi.ac.uk/pub/databases/emdb/doc/XML-schemas/emdb-schemas/current/emdb.xsd
    wget https://ftp.ebi.ac.uk/pub/databases/emdb/structures/EMD-16296/header/emd-16296-v30.xml
    
    generateDS.py -f -o test01.py --member-specs=dict emdb.xsd
    python test01.py emd-16296-v30.xml
    
    generateDS.py -f -o emdb_graphql.py --graphql="emd:entry_type" emdb.xsd
    GRAPHQL_ARGS=emd-16296-v30.xml strawberry server emdb_graphql
    
  3. Point your browser at http://0.0.0.0:8000/graphql.

Notes:

  • The first two lines of the above script download the Emdb XML schema and a sample XML data file that validates against that schema.
  • The next two lines generate and test a standard generateDS module and test it against our Emdb sample data file.
  • And, the final two lines generate a generateDS module that contains support for GraphQL and then starts the Strawberry GraphQL server using that module.

Published

Last Updated

Category

python

Tags

Contact