Python + Marvel + GraphQL = PyMarvelQL

Jorge Carlos

Jorge Carlos

May 29 • 3 Min Read

Introduction 🌋

With the release of Avengers Endgame, there was no better time to build PyMarvelQL, a program that allows you to query the Marvel Database using GraphQL.

PyMarvelQL allows you to send GraphQL queries to Marvel’s REST API to get information about characters, comic series, stories, creators and much more

Try it out 😲

Here is a query for characters with names starting with Captain. The query getCharacter() accepts the parameter nameStartsWith, which can be set to any value you want. Inside the query, you can include any fields that you want to fetch with from the Marvel API. The available queries and parameters are based on the Marvel API documentation. If you would like to download this tool head on over to this Github repository.

How it works 🏗

PyMarvelQL is built with 5 tools — Graphene 2.1, Python 3.7, Flask, flask-graphql, and Marvelous. Flask and Graphene will be the main tools in this project. Flask-graphQl is used to host a local GraphQL server, while Graphene is used to create the GraphQL resolvers and Object Types that allow the user to query the JSON data from the Marvel database.

Flask and Flask-GraphQL 🧪

“Flask is a web framework for python that provides you with tools, libraries, and technologies that allow you to build a web application.” This project relies on Flask to support running GraphiQL in the browser. It uses GraphQLView from the flask-graphql package to add a /graphql endpoint to the flask app. This is what the setup file looks like for flask-graphql.

view_func = GraphQLView.as_view( 'graphql', schema=Schema(query=Query), graphiql=True) app = Flask(__name__) app.add_url_rule('/graphql', view_func=view_func) app.debug = True @app.route('/') def index(): return '<h1> Hi, Go to http://127.0.0.1:5000/graphql to type queries</h1>' if __name__ == '__main__': app.run()
Setting up flask-graphql

Navigate to the /graphql endpoint to visit the GraphiQL playground to query comics, characters, creators and events.

Marvelous 🦸

“Marvelous is an Marvel API wrapper for python”. PyMarvelQL uses Marvelous to call a Marvel endpoint to retrieve a JSON object with all the data needed for the resolvers. PyMarvelQL ships with our API key, but you can register for your own by visiting Marvel’s website. After getting the API key, you can fetch JSON objects like this:

m = marvelous.api( public_key, private_key, ) def accessData(name): if(name == "characters"): characters = m.call(['characters'], {'limit': 10}) return characters['data']['results'] elif(name == "comics"): comics = m.call(['comics'], {'limit': 10}) return comics['data']['results']

The variable m contains an instance of the marvelous API where you can call for data in the Marvel database. As shown above, the function returns a JSON object depending on what the variable name is.

Graphene-Python 2.1 👌

“Graphene-Python is a library for building GraphQL APIs in Python easily, its main goal is to provide a simple but extendable API for making developers’ lives easier.” One of the main features of Graphene is that it allows us to create resolver methods and ObjectTypes. A resolver method uses the data fetched from the JSON object and returns it when you query for it. For example, when fetching for Marvel characters the accessData function(mentioned above) is called and the JSON object is stored in the variable characters. Afterward, the data is returned using 2 functions:

def _json_object_hook(d): return namedtuple('X', d.keys())(*d.values()) def json2obj(data): return json.loads(data, object_hook=_json_object_hook)
def resolve_characters(self, info): characters = getData.accessData('characters') return json2obj(json.dumps(characters))
Function Returning Characters using json2obj

These helper functions allow us to read the object as a string and return our query as an object. An ObjectType is also essential to returning the data that is being queried. As stated in Graphenes documentation, “it is the single definitive source of information about your data. It contains the essential fields and behaviors of the data you’re querying.”

When creating an ObjectType, you must create the “fields and behaviors” exactly the same as how it is presented in the API’s documentation. This will ensure that the data will be returned correctly.

Marvels Class Representation of Creator

For instance, in Marvel’s API documentation they display what fields a Creator object has. Most importantly, they show what data type a field is. Using that information, you can create an ObjectType like this:

class Creator(ObjectType): id = ID() firstName = String() middleName = String() lastName = String() suffix = String() fullName = String() resourceURI = String() urls = List(MarvelUrl) thumbnail = Field(Image) series = Field(AllList) stories = Field(AllList) comics = Field(AllList) events = Field(AllList)
My Class Representation of Creator

As shown above, the ObjectType is similar to the way Marvel creates their Creator class. The main difference is that the datatype of each field is declared with Graphene functions: String(), List(), and Field(). A detailed explanation of all the different Graphene functions can be found in its documentation.

Contact Us

If you like PyMarvelQL, please follow us on twitter (@novvumio) and give us a star 🌟 on GitHub! If you find any issues, we’d love to fix them! You can submit them here.”


Tags
MarvelPythonGrapheneGraphQLFlask