Skip to content

Commit

Permalink
Merge branch 'release/0.4.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
ja573 committed Jul 6, 2021
2 parents 56150a3 + 2c88a3c commit 66e4dbd
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 4 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ Python client for Thoth's GraphQL API


```
python3 -m pip install thothlibrary==0.2
python3 -m pip install thothlibrary==0.4
```
5 changes: 3 additions & 2 deletions thothlibrary/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
#!/usr/bin/env python3
"""GraphQL client for Thoth"""

__version__ = "0.2.0"
__version__ = "0.4.0"
__author__ = "Javier Arias <[email protected]>"
__copyright__ = "Copyright (c) 2020 Open Book Publishers"
__license__ = "Apache 2.0"

from .client import ThothClient
from .errors import ThothError
from .mutation import ThothMutation
from .query import ThothQuery

__all__ = ["ThothClient", "ThothMutation", "ThothError"]
__all__ = ["ThothClient", "ThothQuery", "ThothMutation", "ThothError"]
17 changes: 16 additions & 1 deletion thothlibrary/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@
from graphqlclient import GraphQLClient
from .auth import ThothAuthenticator
from .mutation import ThothMutation
from .query import ThothQuery


class ThothClient():
"""Client to Thoth's GraphQL API"""

def __init__(self, thoth_endpoint):
def __init__(self, thoth_endpoint="https://api.thoth.pub"):
"""Returns new ThothClient object at the specified GraphQL endpoint
thoth_endpoint: Must be the full URL (eg. 'http://localhost').
Expand All @@ -35,6 +36,20 @@ def mutation(self, mutation_name, data):
mutation = ThothMutation(mutation_name, data)
return mutation.run(self.client)

def query(self, query_name, parameters):
"""Instantiate a thoth query and execute"""
query = ThothQuery(query_name, parameters)
return query.run(self.client)

def works(self, limit: int = 100, offset: int = 0, filter_str: str = ""):
"""Construct and trigger a query to obtain all works"""
parameters = {
"limit": limit,
"offset": offset,
"filter": filter_str,
}
return self.query("works", parameters)

def create_publisher(self, publisher):
"""Construct and trigger a mutation to add a new publisher object"""
return self.mutation("createPublisher", publisher)
Expand Down
124 changes: 124 additions & 0 deletions thothlibrary/query.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#!/usr/bin/env python3
"""
GraphQL client for Thoth
(c) Open Book Publishers, February 2020
This programme is free software; you may redistribute and/or modify
it under the terms of the Apache License v2.0.
"""


import json
import urllib
from .errors import ThothError


class ThothQuery():
"""GraphQL query in Thoth
Queries are specified in the QUERIES list, which specifies
their fields and desired return value 'fields' must be a list of
tuples (str, bool) where the string represents the attribute and the
boolean represents whether the values should be enclosed with quotes
and sanitised.
"""

QUERIES = {
"works": {
"parameters": [
"limit",
"offset",
"filter",
"order",
"publishers",
"workType",
"workStatus"
],
"fields": [
"workType",
"workStatus",
"fullTitle",
"title",
"subtitle",
"reference",
"edition",
"imprintId",
"doi",
"publicationDate",
"place",
"width",
"height",
"pageCount",
"pageBreakdown",
"imageCount",
"tableCount",
"audioCount",
"videoCount",
"license",
"copyrightHolder",
"landingPage",
"lccn",
"oclc",
"shortAbstract",
"longAbstract",
"generalNote",
"toc",
"coverUrl",
"coverCaption"
]
}
}

def __init__(self, query_name, parameters):
"""Returns new ThothMutation object with specified mutation data
mutation_name: Must match one of the keys found in MUTATIONS.
mutation_data: Dictionary of mutation fields and their values.
"""
self.query_name = query_name
self.parameters = parameters
self.param_str = self.prepare_parameters()
self.fields_str = self.prepare_fields()
self.request = self.prepare_request()

def prepare_request(self):
"""Format the query request string"""
values = {
"query_name": self.query_name,
"parameters": self.param_str,
"fields": self.fields_str
}
payload = """
query {
%(query_name)s(
%(parameters)s
) {
%(fields)s
}
}
"""
return payload % values

def run(self, client):
"""Perform the GraphQL query and report any errors"""
result = ""
try:
result = client.execute(self.request)
if "errors" in result:
raise AssertionError
return json.loads(result)["data"][self.query_name]
except (KeyError, TypeError, ValueError, AssertionError,
json.decoder.JSONDecodeError, urllib.error.HTTPError):
raise ThothError(self.request, result)

def prepare_parameters(self):
"""Returns a string with all query parameters."""
parameters = []
for key, value in self.parameters.items():
parameters.append("{}: {}, ".format(key, json.dumps(value)))
return ", ".join(parameters)

def prepare_fields(self):
"""Returns a string with all query fields."""
return "\n".join(self.QUERIES[self.query_name]["fields"])

0 comments on commit 66e4dbd

Please sign in to comment.