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.reifywork.com/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:
- https://pypi.org/project/libNeuroML/
- https://libneuroml.readthedocs.io/en/latest/
- https://docs.neuroml.org/Landing.html
Instructions:
Download the repository -- https://github.com/NeuroML/NeuroML2.git
Build the server module:
$ ./generateDS.py \ -f \ -o tmp01.py \ --graphql="neuroml:NeuroMLDocument" \ ../Git/NeuroML2/Schemas/NeuroML2/NeuroML_v2.2.xsd
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:
Download the repository -- https://github.com/openastronomylog/openastronomylog
Build the server module:
$ ./generateDS.py -f -o tmp01.py -g observations:observations openastronomylog-master/src/oal21.xsd
Run the server:
$ GRAPHQL_ARGS=openastronomylog-master/doc/OAL20_simple_example.xml strawberry server tmp01
5.3 Nexml
Instructions:
Download the Nexml repository -- https://github.com/nexml/nexml.git. For example:
$ mkdir MyTestDir $ cd MyTestDir $ git clone https://github.com/nexml/nexml.git
Build the server module. For example:
$ ./generateDS.py -f -o tmp01.py --graphql="Nexml:Nexml" ./nexml/xsd/nexml.xsd
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:
- Documentation on generateDS, itself -- http://www.reifywork.com/generateDS.html
- Documentation of GraphQL support by generateDS -- http://www.reifywork.com/generateDS.html#graphql-support
- The generateDS source repository -- https://sourceforge.net/projects/generateds/
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.
Download the generateDS repository -- https://sourceforge.net/p/generateds/code/ci/default/tree/
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
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:
(Optional) Create and switch to an empty directory in which to create files and run your test.
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
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.