Skip to content

Commit a0beaf1

Browse files
authored
Merge pull request #337 from CLARIAH/dev
Release 1.3.6
2 parents 1324ce0 + 441a172 commit a0beaf1

12 files changed

+84
-35
lines changed

.travis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
sudo: false
22
language: python
33
cache: pip
4-
python: 3.5
4+
python: 3.6
55

66
before_install:
77
- source .travis/before_install.sh

.travis/install.sh

+1
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,6 @@ if [[ $TRAVIS_BUILD_STAGE_NAME == 'Deploy' ]]; then
1919
fi
2020

2121
pip install --upgrade pip
22+
pip install docutils==0.17.1
2223
pip install .
2324
pip install -r requirements-test.txt

.zenodo.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,5 @@
3131
},
3232
"publication_date": "2017-11-22",
3333
"title": "grlc",
34-
"version": "1.3.5"
34+
"version": "1.3.6"
3535
}

CITATION.cff

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,4 @@ keywords:
3232
- "linked-data"
3333
- "semantic-web"
3434
- "linked-data-api"
35-
version: "1.3.5"
35+
version: "1.3.6"

CONTRIBUTING.md

+22
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
Thank you very much for your interest in contributing to grlc! It's people like you that truly make the Semantic Web more accessible to everyone :)
22

3+
## Communication channels
4+
5+
If you would like to get in touch with the grlc developers, and with other users of grlc, you can reach us in two ways:
6+
- Via Twitter, by using the grlc handle (**@grlcldapi**). Follow this account to hear about updates.
7+
- Via the grlc [mailing list](https://groups.google.com/g/grlc-list/). Sign up to the mailing list to ask questions and make suggestions.
8+
39
## Filing bug reports
410

511
The official channel to file bug reports is via our GitHub's [issue tracker](https://github.com/CLARIAH/grlc/issues). When doing so make sure that:
@@ -17,6 +23,14 @@ As with bug reports, for requesting features please use the [issue tracker](http
1723
- Name the file/module if known/available
1824
- Tag the issue as **enhancement**
1925

26+
## Sending pull requests
27+
28+
If you would like to contribute to the code directly, please send in a [pull request (PR)](https://github.com/CLARIAH/grlc/pulls). Please make sure that:
29+
- The title of your PR briefly describes the content
30+
- Describe in detail what your PR contributes
31+
- If your PR addresses a specific issue, indicate the issue number
32+
- Assign @albertmeronyo or @c-martinez as reviewer of your PR.
33+
2034
## Testing environment
2135

2236
To get started with hacking grlc, follow these steps to create a local testing environment (you'll need [docker](https://www.docker.com/) and [docker-compose](https://docs.docker.com/compose/)):
@@ -46,6 +60,14 @@ services:
4660

4761
You're good to pick any issue at the [issue tracker](https://github.com/CLARIAH/grlc/issues) marked as **enhancement** and start implementing it :)
4862

63+
## Governance model
64+
65+
As creators of grlc, [@albertmeronyo](https://github.com/albertmeronyo) and [@c-martinez](http://github.com/c-martinez) are benevolent dictators for this project. This means that they have a final say of the direction of the project. This DOES NOT mean they are not willing to listen to suggestion (on the contrary, they *love* to hear new ideas)!
66+
67+
## Contributing
68+
69+
All grlc contributors will be listed in the [CONTRIBUTORS.md](CONTRIBUTORS.md) file. Also, [notes of new releases](https://github.com/CLARIAH/grlc/releases) will mention who contributed to that specific release.
70+
4971
## Questions
5072

5173
Please open an issue at the [issue tracker](https://github.com/CLARIAH/grlc/issues) and tag it as **question**

CONTRIBUTORS.md

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Contributors
2+
This is a list of all people who have contributed to grlc. Big thanks to everyone.
3+
4+
[RinkeHoekstra](https://github.com/RinkeHoekstra)
5+
[pasqLisena](https://github.com/pasqLisena)
6+
[rlzijdeman](https://github.com/rlzijdeman)
7+
[RoderickvanderWeerdt](https://github.com/RoderickvanderWeerdt)
8+
[arnikz](https://github.com/arnikz)
9+
[jetschni](https://github.com/jetschni)
10+
[mwigham](https://github.com/mwigham)
11+
[steltenpower](https://github.com/steltenpower)
12+
[jspaaks](https://github.com/jspaaks)
13+
[ecow](https://github.com/ecow)
14+
[rapw3k](https://github.com/rapw3k)

README.md

+15-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<p algin="center"><img src="https://raw.githubusercontent.com/CLARIAH/grlc/master/src/static/grlc_logo_01.png" width="250px"></p>
22

3-
[![Join the chat at https://gitter.im/grlc](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/grlc/Lobby#)
3+
[![PyPI version](https://badge.fury.io/py/grlc.svg)](https://badge.fury.io/py/grlc)
44
[![DOI](https://zenodo.org/badge/46131212.svg)](https://zenodo.org/badge/latestdoi/46131212)
55
[![Build Status](https://travis-ci.org/CLARIAH/grlc.svg?branch=master)](https://travis-ci.org/CLARIAH/grlc)
66

@@ -103,7 +103,7 @@ queries:
103103
104104
The API paths of all location types point to the generated [swagger-ui](https://swagger.io/) style API documentation. On the API documentation page, you can explore available API calls and execute individual API calls.
105105
106-
You can also view the swagger spec of your API, by visiting `<API-path>/spec/`, for example: `http://grlc.io/api-git/CLARIAH/grlc-queries/spec/`
106+
You can also view the swagger spec of your API, by visiting `<API-path>/swagger`, for example: `http://grlc.io/api-git/CLARIAH/grlc-queries/swagger`
107107

108108
### grlc query execution
109109
When you call an API endpoint, grlc executes the SPARQL query for that endpoint by combining supplied parameters and decorators.
@@ -192,6 +192,17 @@ Syntax:
192192

193193
Example [query](https://github.com/CLARIAH/grlc-queries/blob/master/tags.rq) and the equivalent [API operation](http://grlc.io/api-git/CLARIAH/grlc-queries/#/group1/get_tags).
194194

195+
### `defaults`
196+
Set the default value in the swagger-ui for a specific parameter in the query.
197+
198+
Syntax:
199+
```
200+
#+ defaults:
201+
#+ - param_name: default_value
202+
```
203+
204+
Example [query](https://github.com/CLARIAH/grlc-queries/blob/master/defaults.rq) and the equivalent [API operation](http://grlc.io/api-git/CLARIAH/grlc-queries/#/default/get_defaults).
205+
195206
### `enumerate`
196207
Indicates which parameters of your query/operation should get enumerations (and get dropdown menus in the swagger-ui) using the given values from the SPARQL endpoint. The values for each enumeration variable can also be specified into the query decorators to save endpoint requests and speed up the API generation.
197208

@@ -218,7 +229,7 @@ Syntax:
218229
Example [query](https://github.com/CLARIAH/grlc-queries/blob/master/endpoint_url.rq) and the equivalent [API operation](http://grlc.io/api-git/CLARIAH/grlc-queries/#/default/get_endpoint_url).
219230

220231
### `transform`
221-
Allows query results to be converted to the specified JSON structure, by using [SPARQLTransformer](https://github.com/D2KLab/py-sparql-transformer) syntax.
232+
Allows query results to be converted to the specified JSON structure, by using [SPARQLTransformer](https://github.com/D2KLab/py-sparql-transformer) syntax. Notice that the response content type must be set to `application/json` for the transformation to take effect.
222233

223234
Syntax:
224235
```
@@ -351,7 +362,7 @@ Check our [contributing](CONTRIBUTING.md) guidelines for these and more, and joi
351362

352363
If you cannot code, that's no problem! There's still plenty you can contribute:
353364

354-
- Share your experience at using grlc in Twitter (mention the handler **@grlcldapi**)
365+
- Share your experience at using grlc in Twitter (mention the handle **@grlcldapi**)
355366
- If you are good with HTML/CSS, [let us know](mailto:albert.meronyo@gmail.com)
356367

357368
## Related tools

requirements.txt

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
docopt==0.6.2
2+
docutils==0.17.1
23
Flask==1.0.2
34
Flask-Cors==3.0.6
45
gevent==1.4.0
@@ -10,14 +11,14 @@ keepalive==0.5
1011
MarkupSafe==0.23
1112
pyaml==18.11.0
1213
pyparsing==2.0.7
13-
PyYAML==4.2b1
14+
PyYAML==5.4
1415
rdflib==4.2.2
1516
rdflib-jsonld==0.4.0
1617
requests==2.20.0
1718
six==1.12.0
1819
simplejson==3.16.0
1920
setuptools>=38.6.0
20-
SPARQLTransformer==1.9.0
21+
SPARQLTransformer==2.1.1
2122
SPARQLWrapper==1.8.2
2223
werkzeug>=0.16.0
2324
PyGithub==1.43.5

src/fileLoaders.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ def getRepoURI(self):
340340

341341
def getLicenceURL(self):
342342
"""Returns the URL of the license file in the specification."""
343-
return self.spec['licence'] if self.spec['licence'] else ''
343+
return self.spec['licence'] if 'licence' in self.spec else None
344344

345345
def getEndpointText(self):
346346
"""Return content of endpoint file (endpoint.txt)"""

src/server.py

+7-17
Original file line numberDiff line numberDiff line change
@@ -81,18 +81,18 @@ def api_docs_local():
8181
# Spec generation, JSON
8282
@app.route('/api-local/swagger', methods=['GET'])
8383
@app.route('/api/local/local/swagger', methods=['GET'], strict_slashes=False) # backward compatibility route
84-
@app.route('/api-local/spec', methods=['GET']) # backward compatibility route
85-
@app.route('/api/local/local/spec', methods=['GET'], strict_slashes=False) # backward compatibility route
8684
def swagger_spec_local():
8785
"""Swagger spec for local routes."""
8886
return swagger_spec(user=None, repo=None, sha=None, content=None)
8987

9088
# Callname execution
9189
@app.route('/api-local/<query_name>', methods=['GET', 'POST'])
90+
@app.route('/api-local/<query_name>.<content>', methods=['GET', 'POST'])
9291
@app.route('/api/local/local/<query_name>', methods=['GET', 'POST'], strict_slashes=False) # backward compatibility route
93-
def query_local(query_name):
92+
@app.route('/api/local/local/<query_name>.<content>', methods=['GET', 'POST'], strict_slashes=False) # backward compatibility route
93+
def query_local(query_name, content=None):
9494
"""SPARQL query execution for local routes."""
95-
return query(user=None, repo=None, query_name=query_name)
95+
return query(user=None, repo=None, query_name=query_name, content=content)
9696

9797
################################
9898
### Routes for URL HTTP APIs ###
@@ -109,7 +109,6 @@ def api_docs_param():
109109

110110
# Spec generation, JSON
111111
@app.route('/api-url/swagger', methods=['GET'])
112-
@app.route('/api-url/spec', methods=['GET']) # backward compatibility route
113112
def swagger_spec_param():
114113
"""Swagger spec for specifications loaded via http."""
115114
spec_url = request.args['specUrl']
@@ -118,11 +117,12 @@ def swagger_spec_param():
118117

119118
# Callname execution
120119
@app.route('/api-url/<query_name>', methods=['GET', 'POST'])
121-
def query_param(query_name):
120+
@app.route('/api-url/<query_name>.<content>', methods=['GET', 'POST'])
121+
def query_param(query_name, content=None):
122122
"""SPARQL query execution for specifications loaded via http."""
123123
spec_url = request.args['specUrl']
124124
glogger.debug("Spec URL: {}".format(spec_url))
125-
return query(user=None, repo=None, query_name=query_name, spec_url=spec_url)
125+
return query(user=None, repo=None, query_name=query_name, spec_url=spec_url, content=content)
126126

127127
##############################
128128
### Routes for GitHub APIs ###
@@ -157,18 +157,8 @@ def api_docs_git(user, repo, subdir=None, sha=None):
157157
@app.route('/api/<user>/<repo>/<subdir>/swagger', methods=['GET']) # backward compatibility route
158158
@app.route('/api/<user>/<repo>/commit/<sha>/swagger') # backward compatibility route
159159
@app.route('/api/<user>/<repo>/<subdir>/commit/<sha>/swagger') # backward compatibility route
160-
@app.route('/api-git/<user>/<repo>/spec', methods=['GET']) # backward compatibility route
161-
@app.route('/api-git/<user>/<repo>/swagger', methods=['GET']) # backward compatibility route
162-
@app.route('/api-git/<user>/<repo>/subdir/<subdir>/spec', methods=['GET']) # backward compatibility route
163160
@app.route('/api-git/<user>/<repo>/<path:subdir>/swagger', methods=['GET']) # backward compatibility route
164-
@app.route('/api-git/<user>/<repo>/commit/<sha>/spec') # backward compatibility route
165-
@app.route('/api-git/<user>/<repo>/subdir/<subdir>/commit/<sha>/spec') # backward compatibility route
166-
@app.route('/api-git/<user>/<repo>/<subdir>/commit/<sha>/spec') # backward compatibility route
167161
@app.route('/api-git/<user>/<repo>/<path:subdir>/commit/<sha>/swagger') # backward compatibility route
168-
@app.route('/api/<user>/<repo>/spec', methods=['GET']) # backward compatibility route
169-
@app.route('/api/<user>/<repo>/<subdir>/spec', methods=['GET']) # backward compatibility route
170-
@app.route('/api/<user>/<repo>/commit/<sha>/spec') # backward compatibility route
171-
@app.route('/api/<user>/<repo>/<subdir>/commit/<sha>/spec') # backward compatibility route
172162
def swagger_spec_git(user, repo, subdir=None, sha=None):
173163
"""Swagger spec for specifications loaded from a Github repo."""
174164
return swagger_spec(user, repo, subdir=subdir, spec_url=None, sha=sha, content=None)

src/swagger.py

+6-5
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def get_repo_info(loader, sha, prov_g):
2929
contact_name = loader.getContactName()
3030
contact_url = loader.getContactUrl()
3131
commit_list = loader.getCommitList()
32-
licence_url = loader.getLicenceURL()
32+
licence_url = loader.getLicenceURL() # This will be None if there is no license
3333

3434
# Add the API URI as a used entity by the activity
3535
if prov_g:
@@ -50,12 +50,13 @@ def get_repo_info(loader, sha, prov_g):
5050
'contact': {
5151
'name': contact_name,
5252
'url': contact_url
53-
},
54-
'license': {
53+
}
54+
}
55+
if licence_url:
56+
info['license'] = {
5557
'name': 'License',
5658
'url': licence_url
5759
}
58-
}
5960

6061
if type(loader) is GithubLoader:
6162
basePath = '/api-git/' + user_repo + '/'
@@ -82,7 +83,7 @@ def get_path_for_item(item):
8283
query = "\n" + json.dumps(query, indent=2) + "\n"
8384

8485
description = item['description']
85-
description += '\n\n```{}```'.format(query)
86+
description += '\n\n```\n{}\n```'.format(query)
8687
description += '\n\nSPARQL transformation:\n```json\n{}```'.format(
8788
item['transform']) if 'transform' in item else ''
8889

src/utils.py

+12-3
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,11 @@ def dispatchSPARQLQuery(raw_sparql_query, loader, requestArgs, acceptHeader, con
124124
glogger.debug("Sending query to SPARQL endpoint: {}".format(endpoint))
125125
glogger.debug("=====================================================")
126126

127-
query_metadata = gquery.get_metadata(raw_sparql_query, endpoint)
127+
try:
128+
query_metadata = gquery.get_metadata(raw_sparql_query, endpoint)
129+
except Exception as e:
130+
# extracting metadata
131+
return { 'error': str(e) }, 400, {}
128132

129133
acceptHeader = 'application/json' if isinstance(raw_sparql_query, dict) else acceptHeader
130134
pagination = query_metadata['pagination'] if 'pagination' in query_metadata else ""
@@ -194,7 +198,12 @@ def dispatchSPARQLQuery(raw_sparql_query, loader, requestArgs, acceptHeader, con
194198
glogger.debug('Sending HTTP request to SPARQL endpoint with params: {}'.format(data))
195199
glogger.debug('Sending HTTP request to SPARQL endpoint with headers: {}'.format(reqHeaders))
196200
glogger.debug('Sending HTTP request to SPARQL endpoint with auth: {}'.format(auth))
197-
response = requests.get(endpoint, params=data, headers=reqHeaders, auth=auth)
201+
try:
202+
response = requests.get(endpoint, params=data, headers=reqHeaders, auth=auth)
203+
except Exception as e:
204+
# Error contacting SPARQL endpoint
205+
glogger.debug('Exception encountered while connecting to SPARQL endpoint')
206+
return { 'error': str(e) }, 400, headers
198207
glogger.debug('Response header from endpoint: ' + response.headers['Content-Type'])
199208

200209
# Response headers
@@ -212,7 +221,7 @@ def dispatchSPARQLQuery(raw_sparql_query, loader, requestArgs, acceptHeader, con
212221
if 'proto' in query_metadata: # sparql transformer
213222
resp = SPARQLTransformer.post_process(json.loads(resp), query_metadata['proto'], query_metadata['opt'])
214223

215-
if 'transform' in query_metadata: # sparql transformer
224+
if 'transform' in query_metadata and acceptHeader == 'application/json': # sparql transformer
216225
rq = { 'proto': query_metadata['transform'] }
217226
_, _, opt = SPARQLTransformer.pre_process(rq)
218227
resp = SPARQLTransformer.post_process(json.loads(resp), query_metadata['transform'], opt)

0 commit comments

Comments
 (0)