Skip to content

Commit

Permalink
refactor: existing python code
Browse files Browse the repository at this point in the history
revert unintended change

feat: rust code

fix configuration loading

feat: fix settings (rust)

 fix configuration loading

feat: fix settings (rust)

feat: rust code debugging

feat: rust code debugging

feat: rust code debugging

feat: rust code debugging

feat: rust code debugging

 fix configuration loading

feat: fix settings (rust)

 fix configuration loading

feat: fix settings (rust)

feat: rust code debugging

feat: rust code debugging

feat: rust code debugging

feat: rust code debugging

feat: rust code debugging

refactor: existing python code

refactor: existing python code

refactor: existing python code

refactor: existing python code
  • Loading branch information
subotic committed Feb 22, 2025
1 parent 108d216 commit e9dda39
Show file tree
Hide file tree
Showing 9 changed files with 54 additions and 49 deletions.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ PhpResourceVersionRedirectUrl : http://$host/resources/$resource_int_id?citdate=
ProjectHost : meta.dasch.swiss

############################################################################
# anything test project
# anything tests project

[0001]

Expand Down
62 changes: 34 additions & 28 deletions python/ark_resolver/ark.py → python/src/ark_resolver/ark.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,18 @@
import sentry_sdk
from sentry_sdk.integrations.asyncio import AsyncioIntegration
from sentry_sdk.integrations.sanic import SanicIntegration
from sentry_sdk.integrations.rust_tracing import RustTracingIntegration

import requests
from sanic import HTTPResponse, Sanic, response
from sanic.log import logger
from sanic_cors import CORS

import ark_resolver.base64url_check_digit as base64url_check_digit_py
from ark_resolver.ark_url import (ArkUrlException, ArkUrlFormatter, ArkUrlInfo, ArkUrlSettings)

import _rust
from sentry_sdk.integrations.rust_tracing import RustTracingIntegration
from ark_resolver import ark_url
import ark_resolver.check_digit as check_digit_py
import ark_resolver.health

from ark_resolver.health import health_bp

#################################################################################################
# OpenTelemetry
Expand All @@ -65,17 +64,19 @@
CORS(app)

# Register health check route
app.blueprint(health_bp)
app.blueprint(ark_resolver.health.health_bp)


@app.before_server_start
async def init_sentry(_):
sentry_dsn = os.environ.get("ARK_SENTRY_DSN", None)
sentry_debug = os.environ.get("ARK_SENTRY_DEBUG", "False")
sentry_environment = os.environ.get("ARK_SENTRY_ENVIRONMENT", None)
sentry_release = os.environ.get("ARK_SENTRY_RELEASE", None)
if sentry_dsn:
sentry_sdk.init(
dsn=sentry_dsn,
debug=sentry_debug,
environment=sentry_environment,
release=sentry_release,
# Add data like request headers and IP for users;
Expand Down Expand Up @@ -108,7 +109,7 @@ async def init_sentry(_):
logger.info("No SENTRY_DSN found in environment variables. Sentry will not be initialized.")


def get_config() -> str:
def get_safe_config() -> str:
"""
Returns the app's configuration
"""
Expand All @@ -127,20 +128,22 @@ def get_config() -> str:
return safe_config_output.getvalue()


@tracer.start_as_current_span("config_get")
@app.get("/config")
async def config_get(_) -> HTTPResponse:
async def safe_config_get(_) -> HTTPResponse:
"""
Returns the app's configuration
"""
return response.text(get_config())
return response.text(get_safe_config())


@tracer.start_as_current_span("config_head")
@app.head("/config")
async def config_head(_) -> HTTPResponse:
async def safe_config_head(_) -> HTTPResponse:
"""
Returns only the head of the config response
"""
config_str = get_config()
config_str = get_safe_config()

headers = {
"Content-Length": str(len(config_str)),
Expand Down Expand Up @@ -181,27 +184,28 @@ async def reload(req) -> HTTPResponse:
else:
return response.text("Unauthorized", status=401)


@tracer.start_as_current_span("redirect")
@app.get('/<path:path>')
async def catch_all(_, path="") -> HTTPResponse:
"""
Catch all URL. Tries to redirect the given ARK ID.
"""
try:
redirect_url = ArkUrlInfo(settings=app.config.settings, ark_id=path).to_redirect_url()
except ArkUrlException as ex:
logger.info(ex.message, ex, exc_info=True)
redirect_url = ark_url.ArkUrlInfo(settings=app.config.settings, ark_id=path).to_redirect_url()

except ark_url.ArkUrlException as ex:
logger.error(f"Invalid ARK ID: {path}", exc_info=ex)
return response.text(body=ex.message, status=400)

except base64url_check_digit_py.CheckDigitException as ex:
logger.info(ex.message, ex, exc_info=True)
except check_digit_py.CheckDigitException as ex:
logger.error(f"Invalid ARK ID: {path}", exc_info=ex)
return response.text(body=ex.message, status=400)

except KeyError:
logger.info("Invalid ARK ID")
except KeyError as ex:
logger.error(f"Invalid ARK ID: {path}", exc_info=ex)
return response.text(body="Invalid ARK ID", status=400)

logger.info(f"Redirecting {path} to {redirect_url}")
return response.redirect(redirect_url)


Expand Down Expand Up @@ -235,7 +239,7 @@ def reload_config() -> None:
#################################################################################################
# Loading of config and registry files.

def load_settings(config_path: str) -> ArkUrlSettings:
def load_settings(config_path: str) -> ark_url.ArkUrlSettings:
"""
Loads configuration from given path and returns an ArkUrlSettings.
"""
Expand Down Expand Up @@ -264,7 +268,7 @@ def load_settings(config_path: str) -> ArkUrlSettings:
else:
config.read_file(open(registry_path))

settings = ArkUrlSettings(config)
settings = ark_url.ArkUrlSettings(config)

return settings

Expand All @@ -282,8 +286,10 @@ def main() -> None:
parser.add_argument("-c", "--config", help="config file (default {})".format(default_config_path))
group = parser.add_mutually_exclusive_group()
group.add_argument("-s", "--server", help="start server", action="store_true")
group.add_argument("-i", "--iri", help="print the converted ARK URL from a given DSP resource IRI (add -v and -d optionally)")
group.add_argument("-a", "--ark", help="print the converted DSP resource IRI (requires -r) or DSP URL from a given ARK ID")
group.add_argument("-i", "--iri",
help="print the converted ARK URL from a given DSP resource IRI (add -v and -d optionally)")
group.add_argument("-a", "--ark",
help="print the converted DSP resource IRI (requires -r) or DSP URL from a given ARK ID")
parser.add_argument("-r", "--resource", help="generate resource IRI", action="store_true")
parser.add_argument("-v", "--value", help="value UUID (has to be provided with -i)")
parser.add_argument("-d", "--date", help="DSP ARK timestamp (has to be provided with -i)")
Expand All @@ -303,20 +309,20 @@ def main() -> None:
server(settings)
elif args.iri:
# prints the converted ARK URL from a given DSP resource IRI
print(ArkUrlFormatter(settings).resource_iri_to_ark_url(args.iri, args.value, args.date))
print(ark_url.ArkUrlFormatter(settings).resource_iri_to_ark_url(args.iri, args.value, args.date))
elif args.ark:
if args.resource:
# prints the converted DSP resource IRI from a given ARK URL
print(ArkUrlInfo(settings, args.ark).to_resource_iri())
print(ark_url.ArkUrlInfo(settings, args.ark).to_resource_iri())
else:
# prints the converted DSP URL from a given ARK URL
print(ArkUrlInfo(settings, args.ark).to_redirect_url())
print(ark_url.ArkUrlInfo(settings, args.ark).to_redirect_url())
else:
parser.print_help()
except ArkUrlException as ex:
except ark_url.ArkUrlException as ex:
print(ex.message)
exit(1)
except base64url_check_digit_py.CheckDigitException as ex:
except check_digit_py.CheckDigitException as ex:
print(ex.message)
exit(1)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from string import Template
from urllib import parse

import ark_resolver.base64url_check_digit as base64url_check_digit_py
import ark_resolver.check_digit as check_digit_py


#################################################################################################
Expand Down Expand Up @@ -44,9 +44,6 @@ def __init__(self, config):
self.v0_ark_url_regex = re.compile(
"^https?://" + self.top_config["ArkExternalHost"] + "/" + self.v0_ark_path_pattern + "$")

print(f"config: {self.config.__dict__}")
print(f"top_config: {self.top_config.__dict__}")


class ArkUrlException(Exception):
"""
Expand Down Expand Up @@ -126,7 +123,8 @@ def __init__(self, settings, ark_id):
if not project_config.getboolean("AllowVersion0"):
raise ArkUrlException(f"Invalid ARK ID (version 0 not allowed): {ark_id}")
else:
raise ArkUrlException(f"Invalid ARK ID {ark_id}. The version of the ARK ID doesn't match the version defined in the settings.")
raise ArkUrlException(
f"Invalid ARK ID {ark_id}. The version of the ARK ID doesn't match the version defined in the settings.")

self.template_dict = {
"url_version": self.url_version,
Expand Down Expand Up @@ -169,7 +167,8 @@ def to_resource_iri(self) -> str:
# in case of an ARK URL version 0, the resource_id generated from the salsah ID has to be converted to a
# base64 UUID version 5
generic_namespace_url = uuid.NAMESPACE_URL
dasch_uuid_ns = uuid.uuid5(generic_namespace_url, "https://dasch.swiss") # cace8b00-717e-50d5-bcb9-486f39d733a2
dasch_uuid_ns = uuid.uuid5(generic_namespace_url,
"https://dasch.swiss") # cace8b00-717e-50d5-bcb9-486f39d733a2
resource_id = template_dict["resource_id"]
dsp_iri = base64.urlsafe_b64encode(uuid.uuid5(dasch_uuid_ns, resource_id).bytes).decode("utf-8")
# remove the padding ('==') from the end of the string
Expand Down Expand Up @@ -261,7 +260,7 @@ def add_check_digit_and_escape(uuid) -> str:
"""
Adds a check digit to a Base64-encoded UUID, and escapes the result.
"""
check_digit = base64url_check_digit_py.calculate_check_digit(uuid)
check_digit = check_digit_py.calculate_check_digit(uuid)
uuid_with_check_digit = uuid + check_digit

# Escape '-' as '=' in the resource ID and check digit, because '-' can be ignored in ARK URLs.
Expand All @@ -275,7 +274,7 @@ def unescape_and_validate_uuid(ark_url, escaped_uuid) -> str:
# '-' is escaped as '=' in the UUID and check digit, because '-' can be ignored in ARK URLs.
unescaped_uuid = escaped_uuid.replace('=', '-')

if not base64url_check_digit_py.is_valid(unescaped_uuid):
if not check_digit_py.is_valid(unescaped_uuid):
raise ArkUrlException(f"Invalid ARK ID: {ark_url}")

return unescaped_uuid[0:-1]
Expand Down
File renamed without changes.
File renamed without changes.
8 changes: 4 additions & 4 deletions python/test/test_ark_url.py → python/tests/test_ark_url.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import os
import pytest

from ark_resolver.ark import load_settings
from ark_resolver.ark_url import ArkUrlFormatter, ArkUrlInfo, ArkUrlException
from ark_resolver import ark

@pytest.fixture(scope="module")
def settings():
"""Loads settings."""
config_path = "python/ark_resolver/ark-config.ini"
os.environ['ARK_REGISTRY'] = 'python/ark_resolver/ark-registry.ini'
return load_settings(config_path)
config_path = "python/src/ark_resolver/ark-config.ini"
os.environ['ARK_REGISTRY'] = 'python/src/ark_resolver/ark-registry.ini'
return ark.load_settings(config_path)

def test_ark_url_formatter(settings):
ark_url_formatter = ArkUrlFormatter(settings)
Expand Down
16 changes: 8 additions & 8 deletions python/test/test_base64.py → python/tests/test_ckeck_digit.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
import ark_resolver.base64url_check_digit as base64url_check_digit_py
from ark_resolver import check_digit as ckeck_digit_py

def test_base64url_check_digit():
correct_resource_id = "cmfk1DMHRBiR4-_6HXpEFA"

# reject a string without a check digit
assert not base64url_check_digit_py.is_valid(correct_resource_id)
assert not ckeck_digit_py.is_valid(correct_resource_id)

# calculate a check digit for a string and validate it
correct_resource_id_check_digit = "n"
check_digit = base64url_check_digit_py.calculate_check_digit(correct_resource_id)
check_digit = ckeck_digit_py.calculate_check_digit(correct_resource_id)
assert check_digit == correct_resource_id_check_digit
correct_resource_id_with_correct_check_digit = correct_resource_id + check_digit
assert base64url_check_digit_py.is_valid(correct_resource_id_with_correct_check_digit)
assert ckeck_digit_py.is_valid(correct_resource_id_with_correct_check_digit)

# reject a string with an incorrect check digit
correct_resource_id_with_incorrect_check_digit = correct_resource_id + "m"
assert not base64url_check_digit_py.is_valid(correct_resource_id_with_incorrect_check_digit)
assert not ckeck_digit_py.is_valid(correct_resource_id_with_incorrect_check_digit)

# reject a string with a missing character
resource_id_with_missing_character = "cmfk1DMHRBiR4-6HXpEFA"
resource_id_with_missing_character_and_correct_check_digit = resource_id_with_missing_character + correct_resource_id_check_digit
assert not base64url_check_digit_py.is_valid(resource_id_with_missing_character_and_correct_check_digit)
assert not ckeck_digit_py.is_valid(resource_id_with_missing_character_and_correct_check_digit)

# reject a string with an incorrect character
resource_id_with_incorrect_character = "cmfk1DMHRBir4-_6HXpEFA"
resource_id_with_incorrect_character_and_correct_check_digit = resource_id_with_incorrect_character + correct_resource_id_check_digit
assert not base64url_check_digit_py.is_valid(resource_id_with_incorrect_character_and_correct_check_digit)
assert not ckeck_digit_py.is_valid(resource_id_with_incorrect_character_and_correct_check_digit)

# reject a string with swapped characters
resource_id_with_swapped_characters = "cmfk1DMHRBiR4_-6HXpEFA"
resource_id_with_swapped_characters_and_correct_check_digit = resource_id_with_swapped_characters + correct_resource_id_check_digit
assert not base64url_check_digit_py.is_valid(resource_id_with_swapped_characters_and_correct_check_digit)
assert not ckeck_digit_py.is_valid(resource_id_with_swapped_characters_and_correct_check_digit)

0 comments on commit e9dda39

Please sign in to comment.