-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #5 from elsevierlabs-os/dev
New features
- Loading branch information
Showing
9 changed files
with
487 additions
and
197 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# Simple Linked Data Redirect Proxy | ||
|
||
The `proxy.py` script in this folder can be used as a simple proxy for redirecting requests from the viewer to Linked Data services on the web. This is particularly useful when: | ||
|
||
* The services require authentication | ||
* The services do not dereference from the original Linked Data URI | ||
* The services are not CORS enabled. | ||
|
||
## Configuration | ||
|
||
* Rename `config.template.yml` to `config.yml` | ||
* Make adjustments in the config file to suit your needs: | ||
* The `rewrites` dictionary should contain entries that match the requested IRI to a regex, with an `id` part. | ||
* If a match is found, this `id` part is then concatenated at the back of the `rewrite_url_prefix` and the request is forwarded to that. | ||
* The `apis` dictionary are also triggered by a regex match. | ||
* Create an object for each api, including an address for retrieving a JSON web token. | ||
* The proxy will always forward only to the first service that matches. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
apis: | ||
API_1_NAME: | ||
regex: "https://data.elsevier.com/health/(core/)?(?P<id>.*)" | ||
token_url: "URL FOR RETRIEVING WEBTOKEN" | ||
key: "SECRET KEY TO OBTAIN TOKEN" | ||
secret: "SECRET TO OBTAIN TOKEN" | ||
api_url: "API URL. The <id> value is concatenated at the end of this URL." | ||
rewrites: | ||
REWRITE_1_NAME: | ||
regex: "https://some.example.iri/namespace/(?P<id>.*)" | ||
rewrite_url_prefix: "https://some.different.example/iri/namespace/to/which/to/redirect/" | ||
REWRITE_2_NAME: | ||
regex: "https://some.other.example.iri/namespace/(?P<id>.*)" | ||
rewrite_url_prefix: "https://some.other.different.example/iri/namespace/to/which/to/redirect/" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import requests | ||
import re | ||
import yaml | ||
import rfc3987 | ||
from flask import Flask, request, make_response | ||
from flask_cors import CORS | ||
|
||
app = Flask(__name__) | ||
CORS(app) | ||
|
||
|
||
try: | ||
config = yaml.safe_load(open("config.yml")); | ||
except: | ||
config = {'apis': {}, 'rewrites': {}} | ||
|
||
@app.route("/browse", methods=["GET"]) | ||
def browse(): | ||
iri = request.args.get('uri', None) | ||
|
||
|
||
is_iri = rfc3987.match(iri) | ||
if is_iri is None: | ||
return make_response({"ERROR": f"{is_iri} is not a valid IRI according to RFC3987"},400) | ||
|
||
response = None | ||
if iri is not None: | ||
print(iri) | ||
passed_through_response = do_request(iri, request.headers) | ||
response = make_response(passed_through_response.content) | ||
response.headers['Content-Type'] = passed_through_response.headers['Content-Type'] | ||
else: | ||
response = make_response({}) | ||
response.headers['Content-Type'] = "application/ld+json" | ||
|
||
return response | ||
|
||
def do_request(iri, headers): | ||
|
||
print(headers.get("Accept")) | ||
proxy_headers = { | ||
"Accept": headers.get("Accept") | ||
} | ||
|
||
for api in config['apis'].values(): | ||
regex = api['regex'] | ||
token_url = api['token_url'] | ||
key = api['key'] | ||
secret = api['secret'] | ||
api_url = api['api_url'] | ||
|
||
# Test for match against H-Graph API | ||
match = re.match(regex,iri) | ||
|
||
if match != None: | ||
# Get token | ||
response = requests.post(token_url, auth=(key,secret)) | ||
if response.status_code == 200: | ||
access_token = response.json()['access_token'] | ||
print(access_token) | ||
else: | ||
raise Exception("API Token could not be retrieved for API call") | ||
|
||
api_call_url = api_url + match.group("id") | ||
|
||
proxy_headers["Authorization"] = f"Bearer {access_token}" | ||
|
||
print(api_call_url) | ||
try: | ||
return requests.get(api_call_url, headers=proxy_headers) | ||
except Exception as e: | ||
raise e | ||
|
||
for rewrite in config['rewrites'].values(): | ||
regex = rewrite['regex'] | ||
rewrite_url_prefix = rewrite['rewrite_url_prefix'] | ||
|
||
match = re.match(regex, iri) | ||
if match != None: | ||
rewrite_call_url = rewrite_url_prefix + match.group('id') | ||
print(rewrite_call_url) | ||
return requests.get(rewrite_call_url, headers=proxy_headers) | ||
|
||
|
||
return requests.get(iri, headers=proxy_headers) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
[tool.poetry] | ||
name = "linked-data-proxy" | ||
version = "0.1.0" | ||
description = "" | ||
authors = ["Rinke Hoekstra <r.hoekstra@elsevier.com>"] | ||
readme = "README.md" | ||
packages = [{include = "linked_data_proxy"}] | ||
|
||
[tool.poetry.dependencies] | ||
python = "^3.10" | ||
requests = "^2.31.0" | ||
flask = "^2.3.2" | ||
flask-cors = "^3.0.10" | ||
pyyaml = "^6.0" | ||
rfc3987 = "^1.3.8" | ||
|
||
|
||
[build-system] | ||
requires = ["poetry-core"] | ||
build-backend = "poetry.core.masonry.api" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.