Skip to content

Commit

Permalink
Merge pull request #5 from elsevierlabs-os/dev
Browse files Browse the repository at this point in the history
New features
  • Loading branch information
RinkeHoekstra committed Jun 26, 2023
2 parents 2562118 + a57216b commit 64d494f
Show file tree
Hide file tree
Showing 9 changed files with 487 additions and 197 deletions.
2 changes: 1 addition & 1 deletion media/js/cpldviewer.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"license": "SEE LICENSE IN LICENSE.md",
"repository": "https://github.com/elsevierlabs-os/cpld-viewer.git",
"icon": "media/img/cpld-icon.png",
"version": "1.0.4",
"version": "1.0.5",
"engines": {
"vscode": "^1.61.0"
},
Expand Down
17 changes: 17 additions & 0 deletions proxy/README.md
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.
14 changes: 14 additions & 0 deletions proxy/config.template.yml
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/"
85 changes: 85 additions & 0 deletions proxy/proxy.py
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)
20 changes: 20 additions & 0 deletions proxy/pyproject.toml
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"
23 changes: 23 additions & 0 deletions src/cpldviewer.css
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ body {
background: #E0E4CC;
}

.object.literal {
background: #e0e4cc7e !important;
font-style: oblique;
cursor:text;
}

.cpld-box {
background: rgba(170, 170, 170, 0.4);
cursor: pointer;
Expand Down Expand Up @@ -91,6 +97,23 @@ body {
grid-template-columns: repeat(3, 1fr);
}

.error-container {
min-height: 300px;
min-width: 100%;
display: flex;
align-items: center;
justify-content: center;
}

.error {
border: 1px black;
background-color: #fa690029;
color: black;
border-radius: 5px;
padding: 3em;
text-align: center;
}

.toast {
max-width: 420px;
}
Expand Down
Loading

0 comments on commit 64d494f

Please sign in to comment.