Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PARKED - RDF Patch functionality #414

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 57 additions & 6 deletions source/web-service/flaskapp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from flaskapp.logging_configuration import get_logging_config
import json

from datetime import datetime
from datetime import datetime, timedelta
import sqlite3

from flask import Flask, Response
Expand Down Expand Up @@ -62,7 +62,7 @@ def create_app():
app.config["DEBUG_LEVEL"] = getenv("DEBUG_LEVEL", "INFO")
app.config["FLASK_ENV"] = getenv("FLASK_ENV", "production")

app.logger.info(f"LOD Gateway logging INFO at level {app.config['DEBUG_LEVEL']}")
app.logger.info(f"LOD Gateway logging at level {app.config['DEBUG_LEVEL']}")

CORS(app, send_wildcard=True)
# Setup global configuration
Expand All @@ -87,6 +87,7 @@ def create_app():
app.config["PROCESS_RDF"] = False
if environ.get("PROCESS_RDF", "False").lower() == "true":
app.config["PROCESS_RDF"] = True
app.logger.info(f"RDF Processing functionality is enabled.")
app.config["SPARQL_QUERY_ENDPOINT"] = environ["SPARQL_QUERY_ENDPOINT"]
app.config["SPARQL_UPDATE_ENDPOINT"] = environ["SPARQL_UPDATE_ENDPOINT"]

Expand All @@ -99,6 +100,12 @@ def create_app():
environ.get("USE_PYLD_REFORMAT", "true").lower() == "true"
)

app.logger.info(
"Using PyLD for parsing/reserialization"
if app.config["USE_PYLD_REFORMAT"]
else "Using RDFLib for parsing/reserialization"
)

# set up a default RDF context cache?
doccache_default_expiry = int(environ.get("RDF_CONTEXT_CACHE_EXPIRES", 30))
app.config["RDF_DOCLOADER"] = document_loader(
Expand All @@ -120,13 +127,32 @@ def create_app():
app.logger.error(
f"The data in ENV: 'RDF_CONTEXT_CACHE' is not JSON! Will not load presets."
)
else:
app.logger.info(f"RDF Processing functionality is disabled.")

# Setting the limit on number of records returned due to a glob browse request
try:
app.config["BROWSE_PAGE_SIZE"] = int(environ.get("BROWSE_PAGE_SIZE", 200))
except (ValueError, TypeError) as e:
app.config["BROWSE_PAGE_SIZE"] = 200

# PATCH_UPDATE_THRESHOLD
app.config["PATCH_UPDATE_THRESHOLD"] = None
if patch_threshold := environ.get("PATCH_UPDATE_THRESHOLD"):
try:
patch_threshold = int(patch_threshold)
app.config["PATCH_UPDATE_THRESHOLD"] = timedelta(minutes=patch_threshold)
except TypeError.ValueError as e:
app.logger.warning(
f"Value in the PATCH_UPDATE_THRESHOLD env var was not understood as a number"
)

app.logger.info(
f"RDF GRAPH PATCH enabled, edit threshold is set to a duration of {app.config['PATCH_UPDATE_THRESHOLD']}"
if app.config["PATCH_UPDATE_THRESHOLD"]
else "RDF GRAPH PATCH is disabled"
)

app.config["JSON_AS_ASCII"] = False
app.config["FLASK_GZIP_COMPRESSION"] = environ["FLASK_GZIP_COMPRESSION"]
app.config["PREFIX_RECORD_IDS"] = getenv("PREFIX_RECORD_IDS", default="RECURSIVE")
Expand All @@ -147,19 +173,43 @@ def create_app():
if environ.get("LINK_HEADER_PREV_VERSION", "False").lower() == "true":
app.config["LINK_HEADER_PREV_VERSION"] = True

app.logger.info(
"Versioning enabled"
if app.config["KEEP_LAST_VERSION"]
else "Versioning is disabled"
)

app.config["SUBADDRESSING"] = False
if environ.get("SUBADDRESSING", "False").lower() == "true":
app.config["SUBADDRESSING"] = True
if environ.get("SUBADDRESSING_DEPTH") is not None:
app.config["SUBADDRESSING_MAX_PARTS"] = 4
app.config["SUBADDRESSING_MIN_PARTS"] = 1

if environ.get("SUBADDRESSING_MAX_PARTS") is not None:
try:
app.config["SUBADDRESSING_MAX_PARTS"] = int(
environ.get("SUBADDRESSING_MAX_PARTS")
)
except (ValueError, TypeError) as e:
app.logger.error(
f"Value for SUBADDRESSING_MAX_PARTS could not be interpreted as an integer. Ignoring."
)
if environ.get("SUBADDRESSING_MIN_PARTS") is not None:
try:
app.config["SUBADDRESSING_DEPTH"] = int(
environ.get("SUBADDRESSING_DEPTH")
app.config["SUBADDRESSING_MIN_PARTS"] = int(
environ.get("SUBADDRESSING_MIN_PARTS")
)
except (ValueError, TypeError) as e:
app.logger.error(
f"Value for SUBADDRESSING_DEPTH could not be interpreted as an integer. Ignoring."
f"Value for SUBADDRESSING_MIN_PARTS could not be interpreted as an integer. Ignoring."
)

app.logger.info(
f"Subaddressing enabled - search depth up to (app.config['SUBADDRESSING_MAX_PARTS']"
if app.config["SUBADDRESSING"]
else "Subaddressing disabled"
)

if app.config["FLASK_ENV"].lower() == "development":
app.config["SQLALCHEMY_ECHO"] = True

Expand Down Expand Up @@ -196,6 +246,7 @@ def create_app():
("FULL_BASE_GRAPH", "Base Graph"),
("SUBADDRESSING", "Subaddressing"),
("KEEP_LAST_VERSION", "Versioning"),
("PATCH_UPDATE_THRESHOLD", "RDF Graph PATCH"),
]
if app.config.get(k)
]
Expand Down
15 changes: 14 additions & 1 deletion source/web-service/flaskapp/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
status_nt = namedtuple("name", "code title detail")

status_ok = status_nt(200, "OK", "OK")
status_not_modified = status_nt(
304, "Not Modified", "No change was made to the resource."
)

status_bad_auth_header = status_nt(
400, "Bad Authorization Header", "Syntax of Authorization header is invalid"
Expand All @@ -31,6 +34,17 @@
405, "Forbidden Method", "For the requested URL only 'POST' method is allowed"
)

status_patch_method_not_allowed = status_nt(
405, "Method Not allowed", "This is not a valid target for a PATCH method"
)

status_patch_request_unparsable = status_nt(
400,
"Bad Request",
"This is not a valid request for the PATCH method. Requires a JSON body,"
" with add and/or delete keys, and a format key indicating the correct RDF serialization type",
)

status_wrong_syntax = status_nt(422, "Invalid JSON", "Could not parse JSON record")

status_id_missing = status_nt(422, "ID Missing", "ID for the JSON record not found")
Expand All @@ -52,7 +66,6 @@

# Construct 'error response' object
def construct_error_response(status, source=None):

err = {}
err["status"] = status.code

Expand Down
Loading