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

Refactor crabpy_pyramid include. #219

Merged
merged 6 commits into from
Oct 16, 2024
Merged
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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
# Packages
*.egg
*.egg-info
.venv
dist
build
eggs
Expand Down Expand Up @@ -43,4 +44,7 @@ dogpile_data

# Rope
.ropeproject

# Editors
.idea/
.vscode/
8 changes: 4 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
dist: focal
sudo: false
language: python
python:
- 3.8
- 3.11
install:
- pip install -r requirements-dev.txt
- python setup.py develop
- pip install nose coverage nose-testconfig coveralls webtest
- pip install -e .
script:
nosetests --nologcapture --config nose_cover.cfg --tc-file nose_travis.ini
cd crabpy_pyramid; python -m unittest discover -s tests
after_success:
coveralls
235 changes: 16 additions & 219 deletions crabpy_pyramid/__init__.py
Original file line number Diff line number Diff line change
@@ -1,192 +1,19 @@
import logging
import os
from collections.abc import Sequence

from crabpy.client import AdressenRegisterClient
from crabpy.gateway.adressenregister import Gateway
from crabpy.gateway.capakey import CapakeyRestGateway
from pyramid.config import Configurator
from pyramid.settings import asbool
from zope.interface import Interface

from crabpy_pyramid.renderers.adressenregister import (
json_item_renderer as adresreg_json_item_renderer,
)
from crabpy_pyramid.renderers.adressenregister import (
json_list_renderer as adresreg_json_list_renderer,
)
from crabpy_pyramid.renderers.capakey import (
json_item_renderer as capakey_json_item_renderer,
)
from crabpy_pyramid.renderers.capakey import (
json_list_renderer as capakey_json_list_renderer,
)

log = logging.getLogger(__name__)
LOG = logging.getLogger(__name__)
GENERATE_ETAG_ROUTE_NAMES = set()


class ICapakey(Interface):
pass


class IAdressenregister(Interface):
pass


def _parse_settings(settings):
defaults = {
"capakey.include": False,
"adressenregister.include": True,
"adressenregister.base_url": "https://api.basisregisters.vlaanderen.be",
"adressenregister.api_key": None,
"cache.file.root": "/tmp/dogpile_data",
}
args = defaults.copy()
if "crabpy.adressenregister.api_key" not in settings:
log.warning(
"No adressenregister.api_key set in settings. "
"The api might stop working after reaching the limit of x requests per day."
)

# booelean settings
for short_key_name in (
"capakey.include",
"adressenregister.include",
):
key_name = "crabpy.%s" % short_key_name
if key_name in settings:
args[short_key_name] = asbool(
settings.get(key_name, defaults.get(short_key_name))
)

# string setting
for short_key_name in (
"proxy.http",
"proxy.https",
"cache.file.root",
"adressenregister.base_url",
"adressenregister.api_key",
):
key_name = "crabpy.%s" % short_key_name
if key_name in settings:
args[short_key_name] = settings.get(key_name)

# cache configuration
for short_key_name in (
"capakey.cache_config",
"adressenregister.cache_config",
):
key_name = "crabpy.%s." % short_key_name
cache_config = {}
for skey in settings.keys():
if skey.startswith(key_name):
cache_config[skey[len(key_name) :]] = settings.get(skey)
if cache_config:
args[short_key_name] = cache_config

log.debug(settings)
log.debug(args)
return args


def _filter_settings(settings, prefix):
"""
Filter all settings to only return settings that start with a certain
prefix.

:param dict settings: A settings dictionary.
:param str prefix: A prefix.
"""
ret = {}
for skey in settings.keys():
if skey.startswith(prefix):
key = skey[len(prefix) :]
ret[key] = settings[skey]
return ret


def _build_capakey(registry, settings):
capakey = registry.queryUtility(ICapakey)
if capakey is not None:
return capakey
if "cache_config" in settings:
cache_config = settings["cache_config"]
del settings["cache_config"]
else:
cache_config = {}
gateway = CapakeyRestGateway(cache_config=cache_config)

registry.registerUtility(gateway, ICapakey)
return registry.queryUtility(ICapakey)


def _build_adressenregister(registry, settings):
adressenregister = registry.queryUtility(IAdressenregister)
if adressenregister is not None:
return adressenregister
if "cache_config" in settings:
cache_config = settings["cache_config"]
del settings["cache_config"]
else:
cache_config = None
gateway = Gateway(
client=AdressenRegisterClient(settings["base_url"], settings["api_key"]),
cache_settings=cache_config,
)

registry.registerUtility(gateway, IAdressenregister)
return registry.queryUtility(IAdressenregister)


def get_capakey(registry):
"""
Get the Capakey Gateway

:rtype: :class:`crabpy.gateway.capakey.CapakeyRestGateway`
"""
# argument might be a config or a request
regis = getattr(registry, "registry", None)
if regis is None:
regis = registry

return regis.queryUtility(ICapakey)


def get_adressenregister(registry):
"""
Get the Adresssenregister Gateway

:rtype: :class:`crabpy.gateway.adressenregister.Gateway`
# argument might be a config or a request
"""
# argument might be a config or a request
regis = getattr(registry, "registry", None)
if regis is None:
regis = registry

return regis.queryUtility(IAdressenregister)


def _get_proxy_settings(settings):
base_settings = {}
http = settings.get("proxy.http", None)
https = settings.get("proxy.https", None)
if http or https:
base_settings["proxy"] = {}
if "proxy.http" in settings:
base_settings["proxy"]["http"] = settings["proxy.http"]
log.info("HTTP proxy: %s" % base_settings["proxy"]["http"])
if "proxy.https" in settings:
base_settings["proxy"]["https"] = settings["proxy.https"]
log.info("HTTPS proxy: %s" % base_settings["proxy"]["https"])
return base_settings


def add_route(config, name, pattern, *args, **kwargs):
"""
Adds a pyramid route to the config. All args and kwargs will be
passed on to config.add_route.
Add a pyramid route to the config with etag tween support.

All args and kwargs will be passed on to config.add_route.

This exists so the default behaviour of including crabpy will still be to
cache all crabpy routes.
Expand All @@ -197,8 +24,7 @@ def add_route(config, name, pattern, *args, **kwargs):

def conditional_http_tween_factory(handler, registry):
"""
Tween that adds ETag headers and tells Pyramid to enable
conditional responses where appropriate.
Tween that automatically adds ETag headers enables conditional responses.
"""
settings = registry.settings if hasattr(registry, "settings") else {}
if "generate_etag_for.list" in settings:
Expand Down Expand Up @@ -233,62 +59,33 @@ def conditional_http_tween(request):
return conditional_http_tween


def includeme(config):
def includeme(config: Configurator):
"""
Include `crabpy_pyramid` in this `Pyramid` application.

:param pyramid.config.Configurator config: A Pyramid configurator.
"""

settings = _parse_settings(config.registry.settings)
base_settings = _get_proxy_settings(settings)

settings = config.registry.settings
# http caching tween
if not settings.get("etag_tween_disabled", False):
config.add_tween("crabpy_pyramid.conditional_http_tween_factory")

# create cache
root = settings.get("cache.file.root", "/tmp/dogpile_data")
if not os.path.exists(root):
os.makedirs(root)

capakey_settings = dict(_filter_settings(settings, "capakey."), **base_settings)
if "include" in capakey_settings:
log.info(
# capakey
if "crabpy.capakey.include" in settings:
LOG.info(
"The 'capakey.include' setting is deprecated. Capakey will "
"always be included."
)
log.info("Adding CAPAKEY Gateway.")
config.add_renderer("capakey_listjson", capakey_json_list_renderer)
config.add_renderer("capakey_itemjson", capakey_json_item_renderer)
_build_capakey(config.registry, capakey_settings)
config.add_request_method(get_capakey, "capakey_gateway")
config.add_directive("get_capakey", get_capakey)
config.include("crabpy_pyramid.routes.capakey")
config.scan("crabpy_pyramid.views.capakey")

# adressenregister wordt afgekort tot adresreg
adresreg_settings = dict(
_filter_settings(settings, "adressenregister."), **base_settings
)
config.include("crabpy_pyramid.capakey")

if adresreg_settings["include"]:
log.info("Adding adressen register Gateway.")
del adresreg_settings["include"]
config.add_renderer("adresreg_listjson", adresreg_json_list_renderer)
config.add_renderer("adresreg_itemjson", adresreg_json_item_renderer)
_build_adressenregister(config.registry, adresreg_settings)
config.add_directive("get_adressenregister", get_adressenregister)
config.add_request_method(get_adressenregister, "adressenregister_gateway")
config.include("crabpy_pyramid.routes.adressenregister")
config.scan("crabpy_pyramid.views.adressenregister")
config.scan("crabpy_pyramid.views.exceptions")
# adressenregister
if "crabpy.adressenregister.include" in settings:
if asbool(settings["crabpy.adressenregister.include"]):
config.include("crabpy_pyramid.adressenregister")


def main(global_config, **settings):
"""
This function returns a Pyramid WSGI application.
"""
"""Create a Pyramid WSGI application."""
config = Configurator(settings=settings)

includeme(config)
Expand Down
Loading