From 56fb0a5fc8b30413e75c9cb06f295d345c8cbdf5 Mon Sep 17 00:00:00 2001
From: mutantsan
Date: Thu, 25 Jan 2024 22:58:30 +0200
Subject: [PATCH] move to ckanext-admin-panel
---
ckanext/drupal_api/assets/webassets.yml | 5 -
ckanext/drupal_api/config.py | 116 +++++++++++++++++-
ckanext/drupal_api/config_declaration.yaml | 2 +
ckanext/drupal_api/helpers.py | 14 +--
ckanext/drupal_api/logic/api.py | 24 ++--
ckanext/drupal_api/plugin.py | 35 +++++-
.../templates/admin/drupal_api_config.html | 108 ----------------
.../templates/drupal_api/config.html | 65 ++++++++++
ckanext/drupal_api/templates/page.html | 6 -
ckanext/drupal_api/tests/test_plugin.py | 54 --------
ckanext/drupal_api/tests/test_utils.py | 5 -
ckanext/drupal_api/types.py | 4 +-
ckanext/drupal_api/utils.py | 24 +---
ckanext/drupal_api/views.py | 85 ++++++++-----
setup.py | 2 +-
15 files changed, 295 insertions(+), 254 deletions(-)
delete mode 100644 ckanext/drupal_api/templates/admin/drupal_api_config.html
create mode 100644 ckanext/drupal_api/templates/drupal_api/config.html
delete mode 100644 ckanext/drupal_api/templates/page.html
delete mode 100644 ckanext/drupal_api/tests/test_plugin.py
delete mode 100644 ckanext/drupal_api/tests/test_utils.py
diff --git a/ckanext/drupal_api/assets/webassets.yml b/ckanext/drupal_api/assets/webassets.yml
index ee0105e..e69de29 100644
--- a/ckanext/drupal_api/assets/webassets.yml
+++ b/ckanext/drupal_api/assets/webassets.yml
@@ -1,5 +0,0 @@
-# styles:
-# filters: cssrewrite
-# output: ckanext-drupal_api/%(version)s-styles.css
-# contents:
-# - css/styles.css
diff --git a/ckanext/drupal_api/config.py b/ckanext/drupal_api/config.py
index 7c265df..5fd2857 100644
--- a/ckanext/drupal_api/config.py
+++ b/ckanext/drupal_api/config.py
@@ -1,7 +1,19 @@
+from __future__ import annotations
+
+from typing import Any
+
+import ckan.plugins.toolkit as tk
+
+
CONFIG_DRUPAL_URL = "ckanext.drupal_api.drupal_url"
+DEFAULT_DRUPAL_URL = ""
CONFIG_CACHE_DURATION = "ckanext.drupal_api.cache.duration"
+DEFAULT_CACHE_DURATION = 3600
+
CONFIG_REQUEST_TIMEOUT = "ckanext.drupal_api.timeout"
+DEFAULT_REQUEST_TIMEOUT = 5
+
CONFIG_REQUEST_HTTP_USER = "ckanext.drupal_api.request.user"
CONFIG_REQUEST_HTTP_PASS = "ckanext.drupal_api.request.pass"
@@ -14,5 +26,105 @@
CONFIG_MENU_EXPORT = "ckanext.drupal_api.core.menu_export_endpoint"
DEFAULT_MENU_EXPORT_EP = "/resource/layout/export"
-DEFAULT_REQUEST_TIMEOUT = 5
-DEFAULT_CACHE_DURATION = 3600
+
+def get_cache_ttl() -> int:
+ return tk.asint(tk.config[CONFIG_CACHE_DURATION] or DEFAULT_CACHE_DURATION)
+
+
+def get_drupal_url() -> str:
+ return (tk.config[CONFIG_DRUPAL_URL] or DEFAULT_DRUPAL_URL).strip("/")
+
+
+def get_api_version() -> str:
+ return tk.config[CONFIG_DRUPAL_API_VERSION] or DEFAULT_API_VERSION
+
+
+def get_menu_export_endpoint() -> str:
+ if get_api_version() == JSON_API:
+ return "/jsonapi/menu_items/{menu_id}"
+
+ return tk.config[CONFIG_MENU_EXPORT] or DEFAULT_MENU_EXPORT_EP
+
+
+def get_request_timeout() -> int:
+ return tk.asint(tk.config[CONFIG_REQUEST_TIMEOUT] or DEFAULT_REQUEST_TIMEOUT)
+
+
+def get_http_user() -> str | None:
+ return tk.config[CONFIG_REQUEST_HTTP_USER]
+
+
+def get_http_pass() -> str | None:
+ return tk.config[CONFIG_REQUEST_HTTP_PASS]
+
+
+def get_config_options() -> dict[str, dict[str, Any]]:
+ """Defines how we are going to render the global configuration
+ options for an extension."""
+ unicode_safe = tk.get_validator("unicode_safe")
+ one_of = tk.get_validator("one_of")
+ default = tk.get_validator("default")
+ int_validator = tk.get_validator("is_positive_integer")
+ url_validator = tk.get_validator("url_validator")
+
+ return {
+ "cache_ttl": {
+ "key": CONFIG_CACHE_DURATION,
+ "label": tk._("Cache TTL"),
+ "value": get_cache_ttl(),
+ "validators": [default(DEFAULT_CACHE_DURATION), int_validator],
+ "type": "number",
+ },
+ "drupal_url": {
+ "key": CONFIG_DRUPAL_URL,
+ "label": tk._("Drupal base URL"),
+ "value": get_drupal_url(),
+ "validators": [unicode_safe, url_validator],
+ "type": "text",
+ "required": True,
+ },
+ "api_version": {
+ "key": CONFIG_DRUPAL_API_VERSION,
+ "label": tk._("API version"),
+ "value": get_api_version(),
+ "validators": [default(DEFAULT_API_VERSION), one_of([JSON_API, CORE_API])],
+ "type": "select",
+ "options": [
+ {"value": JSON_API, "text": "JSON API"},
+ {"value": CORE_API, "text": "Core REST API"},
+ ],
+ },
+ "menu_export_endpoint": {
+ "key": CONFIG_MENU_EXPORT,
+ "label": tk._("Menu export API endpoint"),
+ "value": get_menu_export_endpoint(),
+ "validators": [unicode_safe],
+ "type": "text",
+ "disabled": get_api_version() == JSON_API,
+ "required": True,
+ "help_text": tk._(
+ "If you are using the core API version, you might face the situation when your endpoint differ from the default one"
+ ),
+ },
+ "request_timeout": {
+ "key": CONFIG_REQUEST_TIMEOUT,
+ "label": tk._("API request timeout"),
+ "value": get_request_timeout(),
+ "validators": [default(DEFAULT_REQUEST_TIMEOUT), int_validator],
+ "type": "number",
+ },
+ "http_user": {
+ "key": CONFIG_REQUEST_HTTP_USER,
+ "label": tk._("HTTP auth user"),
+ "value": get_http_user(),
+ "validators": [unicode_safe],
+ "type": "text",
+ },
+ "http_pass": {
+ "key": CONFIG_REQUEST_HTTP_PASS,
+ "label": tk._("HTTP auth password"),
+ "value": get_http_pass(),
+ "validators": [unicode_safe],
+ "type": "password",
+ },
+ }
diff --git a/ckanext/drupal_api/config_declaration.yaml b/ckanext/drupal_api/config_declaration.yaml
index e4d44db..def8436 100644
--- a/ckanext/drupal_api/config_declaration.yaml
+++ b/ckanext/drupal_api/config_declaration.yaml
@@ -3,6 +3,8 @@ groups:
- annotation: ckanext-drupal-api
options:
- key: ckanext.drupal_api.drupal_url
+ default: ""
+
- key: ckanext.drupal_api.cache.duration
type: int
default: 3600
diff --git a/ckanext/drupal_api/helpers.py b/ckanext/drupal_api/helpers.py
index 076d6ce..bfba45c 100644
--- a/ckanext/drupal_api/helpers.py
+++ b/ckanext/drupal_api/helpers.py
@@ -6,10 +6,8 @@
from requests.exceptions import RequestException
-import ckan.plugins.toolkit as tk
-
-import ckanext.drupal_api.config as c
-from ckanext.drupal_api.utils import cached, _get_api_version
+import ckanext.drupal_api.config as da_conf
+from ckanext.drupal_api.utils import cached, get_api_version
from ckanext.drupal_api.logic.api import make_request
from ckanext.drupal_api.types import Menu, T, MaybeNotCached, DontCache
@@ -30,7 +28,7 @@ def get_helpers():
@helper
@cached
def menu(name: str, cache_extras: Optional[dict[str, Any]] = None) -> MaybeNotCached[Menu]:
- api_connector = _get_api_version()
+ api_connector = get_api_version()
drupal_api = api_connector.get()
if not drupal_api:
@@ -55,9 +53,10 @@ def custom_endpoint(endpoint: str) -> dict:
Returns:
dict: response from Drupal
"""
- base_url = tk.config.get(c.CONFIG_DRUPAL_URL)
+ base_url = da_conf.get_drupal_url()
+
if not base_url:
- log.error("Drupal URL is missing: %s", c.CONFIG_DRUPAL_URL)
+ log.error("Drupal URL is missing: %s", da_conf.CONFIG_DRUPAL_URL)
return DontCache({})
try:
@@ -65,4 +64,5 @@ def custom_endpoint(endpoint: str) -> dict:
except RequestException as e:
log.error(f"Custom endpoint request error - {endpoint}: {e}")
return DontCache({})
+
return resp
diff --git a/ckanext/drupal_api/logic/api.py b/ckanext/drupal_api/logic/api.py
index 540b5d4..7965223 100644
--- a/ckanext/drupal_api/logic/api.py
+++ b/ckanext/drupal_api/logic/api.py
@@ -1,4 +1,5 @@
from __future__ import annotations
+
import logging
import requests
from typing import Optional
@@ -6,18 +7,17 @@
import ckan.plugins.toolkit as tk
import ckan.plugins as p
-import ckanext.drupal_api.config as c
+
+import ckanext.drupal_api.config as da_conf
log = logging.getLogger(__name__)
def make_request(url: str) -> dict:
- http_user: str = tk.config.get(c.CONFIG_REQUEST_HTTP_USER)
- http_pass: str = tk.config.get(c.CONFIG_REQUEST_HTTP_PASS)
- timeout = tk.asint(
- tk.config.get(c.CONFIG_REQUEST_TIMEOUT, c.DEFAULT_REQUEST_TIMEOUT)
- )
+ http_user = da_conf.get_http_user()
+ http_pass = da_conf.get_http_pass()
+ timeout = da_conf.get_request_timeout()
session = requests.Session()
@@ -35,10 +35,12 @@ class Drupal:
@classmethod
def get(cls, instance: str = "default") -> Optional[Drupal]:
- url = tk.config.get(c.CONFIG_DRUPAL_URL)
+ url = da_conf.get_drupal_url()
+
if not url:
- log.error("Drupal URL is missing: %s", c.CONFIG_DRUPAL_URL)
+ log.error("Drupal URL is missing: %s", da_conf.CONFIG_DRUPAL_URL)
return
+
default_lang = tk.config.get("ckan.locale_default")
current_lang = tk.h.lang()
localised_url = url.format(
@@ -92,12 +94,10 @@ def _request(self, endpoint: str) -> dict:
return make_request(url)
def get_menu(self, name: str) -> dict:
- data: dict = self._request(
- endpoint=tk.config.get(c.CONFIG_MENU_EXPORT, c.DEFAULT_MENU_EXPORT_EP)
- )
+ data: dict = self._request(endpoint=da_conf.get_menu_export_endpoint())
log.info(
f"Menu {name} has been fetched successfully. Cached for \
- {tk.config.get(c.CONFIG_CACHE_DURATION, c.DEFAULT_CACHE_DURATION)} seconds"
+ {da_conf.get_cache_ttl()} seconds"
)
return data.get(name, {})
diff --git a/ckanext/drupal_api/plugin.py b/ckanext/drupal_api/plugin.py
index af86dea..9460978 100644
--- a/ckanext/drupal_api/plugin.py
+++ b/ckanext/drupal_api/plugin.py
@@ -1,13 +1,22 @@
+from __future__ import annotations
+
import ckan.plugins as p
import ckan.plugins.toolkit as tk
import ckanext.drupal_api.helpers as helpers
from ckanext.drupal_api.views import blueprints
+import ckanext.ap_main.types as ap_types
+from ckanext.ap_main.interfaces import IAdminPanel
+
+import ckanext.drupal_api.config as da_config
+
+
class DrupalApiPlugin(p.SingletonPlugin):
p.implements(p.ITemplateHelpers)
p.implements(p.IConfigurer)
p.implements(p.IBlueprint)
+ p.implements(IAdminPanel, inherit=True)
# ITemplateHelpers
@@ -18,13 +27,37 @@ def get_helpers(self):
def update_config(self, config_):
tk.add_template_directory(config_, "templates")
- tk.add_ckan_admin_tab(config_, "drupal_api.drupal_api_config", "Drupal API")
+
+ def update_config_schema(self, schema):
+ for _, config in da_config.get_config_options().items():
+ schema.update({config["key"]: config["validators"]})
+
+ return schema
# IBlueprint
def get_blueprint(self):
return blueprints
+ # IAdminPanel
+
+ def register_config_sections(
+ self, config_list: list[ap_types.SectionConfig]
+ ) -> list[ap_types.SectionConfig]:
+ config_list.append(
+ ap_types.SectionConfig(
+ name="Drupal API",
+ configs=[
+ ap_types.ConfigurationItem(
+ name="Configuration",
+ blueprint="drupal_api.config",
+ info="Drupal API settings",
+ )
+ ],
+ )
+ )
+ return config_list
+
if tk.check_ckan_version("2.10"):
tk.blanket.config_declarations(DrupalApiPlugin)
diff --git a/ckanext/drupal_api/templates/admin/drupal_api_config.html b/ckanext/drupal_api/templates/admin/drupal_api_config.html
deleted file mode 100644
index 71166e7..0000000
--- a/ckanext/drupal_api/templates/admin/drupal_api_config.html
+++ /dev/null
@@ -1,108 +0,0 @@
-{% extends "admin/base.html" %}
-
-{% block primary_content_inner %}
-
-{% if not drupal_url %}
-
-
-
- {{ _('ERROR. Missing Drupal URL. The extension won\'t work properly!') }}
-
-
-{% endif %}
-
-
-{% endblock %}
-
-{% block secondary_content %}
-
-
-
- {{ _('Drupal API') }}
-
-
-
{{ _('Cache info') }}
-
- {{ _('Default cache TTL is {} sec.').format(cache_ttl_default) }}
- {{ _('You can specify the TTL by providing next config option:') }}
-
ckanext.drupal_api.cache.duration
-
-
-
-
-
{{ _('API versions') }}
-
- {{ _("Currently, there are two supported API versions:") }}
- JSON API {{ _('and') }}
- RESTful Web Services
- ({{ _('default') }})
- {{ _("You can specify the API version with next config option:") }}
-
ckanext.drupal_api.api_version
- {{ _("There are two options: ") }}
json
{{ _('and') }}
core
-
-
-
-{% endblock %}
\ No newline at end of file
diff --git a/ckanext/drupal_api/templates/drupal_api/config.html b/ckanext/drupal_api/templates/drupal_api/config.html
new file mode 100644
index 0000000..e2692eb
--- /dev/null
+++ b/ckanext/drupal_api/templates/drupal_api/config.html
@@ -0,0 +1,65 @@
+{% extends 'admin_panel/base.html' %}
+
+{% import 'macros/autoform.html' as autoform %}
+{% import 'macros/form.html' as form %}
+
+{% block breadcrumb_content %}
+ {% link_for _("Configuration"), named_route='drupal_api.config' %}
+{% endblock breadcrumb_content %}
+
+{% block ap_content %}
+ {{ _("Drupal API config") }}
+
+
+
+ {% if not configs.drupal_url.value %}
+
+
+ {{ _('ERROR. Missing Drupal URL. The extension won\'t work properly!') }}
+
+ {% endif %}
+
+
+{% endblock ap_content %}
diff --git a/ckanext/drupal_api/templates/page.html b/ckanext/drupal_api/templates/page.html
deleted file mode 100644
index 0704e83..0000000
--- a/ckanext/drupal_api/templates/page.html
+++ /dev/null
@@ -1,6 +0,0 @@
-{% ckan_extends %}
-
-{%- block styles %}
- {{ super() }}
- {% asset 'ckanext-drupal-api/styles' %}
-{% endblock %}
\ No newline at end of file
diff --git a/ckanext/drupal_api/tests/test_plugin.py b/ckanext/drupal_api/tests/test_plugin.py
deleted file mode 100644
index 44e503e..0000000
--- a/ckanext/drupal_api/tests/test_plugin.py
+++ /dev/null
@@ -1,54 +0,0 @@
-"""
-Tests for plugin.py.
-
-Tests are written using the pytest library (https://docs.pytest.org), and you
-should read the testing guidelines in the CKAN docs:
-https://docs.ckan.org/en/2.9/contributing/testing.html
-
-To write tests for your extension you should install the pytest-ckan package:
-
- pip install pytest-ckan
-
-This will allow you to use CKAN specific fixtures on your tests.
-
-For instance, if your test involves database access you can use `clean_db` to
-reset the database:
-
- import pytest
-
- from ckan.tests import factories
-
- @pytest.mark.usefixtures("clean_db")
- def test_some_action():
-
- dataset = factories.Dataset()
-
- # ...
-
-For functional tests that involve requests to the application, you can use the
-`app` fixture:
-
- from ckan.plugins import toolkit
-
- def test_some_endpoint(app):
-
- url = toolkit.url_for('myblueprint.some_endpoint')
-
- response = app.get(url)
-
- assert response.status_code == 200
-
-
-To temporary patch the CKAN configuration for the duration of a test you can use:
-
- import pytest
-
- @pytest.mark.ckan_config("ckanext.myext.some_key", "some_value")
- def test_some_action():
- pass
-"""
-import ckanext.drupal_api.plugin as plugin
-
-
-def test_plugin():
- pass
diff --git a/ckanext/drupal_api/tests/test_utils.py b/ckanext/drupal_api/tests/test_utils.py
deleted file mode 100644
index f4b2056..0000000
--- a/ckanext/drupal_api/tests/test_utils.py
+++ /dev/null
@@ -1,5 +0,0 @@
-from ckanext.drupal_api.utils import cached
-
-
-def test_cached():
- pass
diff --git a/ckanext/drupal_api/types.py b/ckanext/drupal_api/types.py
index 542f288..0839c61 100644
--- a/ckanext/drupal_api/types.py
+++ b/ckanext/drupal_api/types.py
@@ -1,4 +1,6 @@
-from typing import Callable, Dict, Generic, Optional, TypeVar, Union, cast, Iterable
+from __future__ import annotations
+
+from typing import Callable, Dict, Generic, TypeVar, Union, Iterable
T = TypeVar("T", bound=Callable)
diff --git a/ckanext/drupal_api/utils.py b/ckanext/drupal_api/utils.py
index e98b926..4449efb 100644
--- a/ckanext/drupal_api/utils.py
+++ b/ckanext/drupal_api/utils.py
@@ -4,12 +4,12 @@
import pickle
from functools import wraps
-from typing import Callable, Dict, Optional, Union, cast, Any
+from typing import Callable, Optional, Union, cast
import ckan.plugins.toolkit as tk
import ckan.lib.redis as redis
-import ckanext.drupal_api.config as c
+import ckanext.drupal_api.config as da_conf
from ckanext.drupal_api.types import T, MaybeNotCached, DontCache
from ckanext.drupal_api.logic.api import CoreAPI, JsonAPI
@@ -17,17 +17,16 @@
log = logging.getLogger(__name__)
-def _get_api_version() -> Optional[Union[CoreAPI, JsonAPI]]:
+def get_api_version() -> Optional[Union[CoreAPI, JsonAPI]]:
"""
Returns a connector class for an API
There are two supported versions:
- JSON API
- Rest API (Drupal core)
"""
- supported_api = {c.JSON_API: JsonAPI, c.CORE_API: CoreAPI}
+ supported_api = {da_conf.JSON_API: JsonAPI, da_conf.CORE_API: CoreAPI}
- api_version: str = tk.config.get(c.CONFIG_DRUPAL_API_VERSION, c.DEFAULT_API_VERSION)
- return supported_api.get(api_version)
+ return supported_api.get(da_conf.get_api_version())
def cached(func: Callable[..., MaybeNotCached[T]]) -> Callable[..., T]:
@@ -47,9 +46,7 @@ def wrapper(*args, **kwargs):
return cast(T, json.loads(value))
value = func(*args, **kwargs)
- cache_duration = tk.asint(
- tk.config.get(c.CONFIG_CACHE_DURATION, c.DEFAULT_CACHE_DURATION)
- )
+ cache_duration = da_conf.get_cache_ttl()
if isinstance(value, DontCache):
return cast(T, value.unwrap())
@@ -79,12 +76,3 @@ def drop_cache_for(name):
def _get_redis_conn():
return redis.connect_to_redis()
-
-
-def _get_menu_export_endpoint():
- if tk.config.get(
- c.CONFIG_DRUPAL_API_VERSION, c.DEFAULT_API_VERSION
- ) == "json":
- return "/jsonapi/menu_items/{menu_id}"
- else:
- return tk.config.get(c.CONFIG_MENU_EXPORT, c.DEFAULT_MENU_EXPORT_EP)
diff --git a/ckanext/drupal_api/views.py b/ckanext/drupal_api/views.py
index 812bfb8..8f2fd44 100644
--- a/ckanext/drupal_api/views.py
+++ b/ckanext/drupal_api/views.py
@@ -1,58 +1,75 @@
import logging
from flask import Blueprint
+from flask.views import MethodView
import ckan.plugins.toolkit as tk
-import ckan.model as model
+from ckan.logic import parse_params
-import ckanext.drupal_api.config as c
-from ckanext.drupal_api.utils import drop_cache_for, _get_menu_export_endpoint
+from ckanext.ap_main.utils import ap_before_request
+
+import ckanext.drupal_api.config as da_conf
+from ckanext.drupal_api.utils import drop_cache_for
from ckanext.drupal_api.helpers import custom_endpoint, menu
log = logging.getLogger(__name__)
-drupal_api = Blueprint("drupal_api", __name__)
+drupal_api = Blueprint("drupal_api", __name__, url_prefix="/admin-panel/drupal_api")
+drupal_api.before_request(ap_before_request)
+class ConfigView(MethodView):
+ def get(self):
+ return tk.render(
+ "drupal_api/config.html",
+ {"configs": da_conf.get_config_options(), "data": {}, "errors": {}},
+ )
-@drupal_api.before_request
-def before_request():
- try:
- context = {
- "model": model,
- "user": tk.g.user,
- "auth_user_obj": tk.g.userobj
- }
- tk.check_access('sysadmin', context)
- except tk.NotAuthorized:
- tk.base.abort(403, tk._('Need to be system administrator to manage cache'))
+ def post(self):
+ data_dict = parse_params(tk.request.form)
+ try:
+ tk.get_action("config_option_update")(
+ {"user": tk.current_user.name},
+ data_dict,
+ )
+ except tk.ValidationError as e:
+ return tk.render(
+ "drupal_api/config.html",
+ extra_vars={
+ "data": data_dict,
+ "errors": e.error_dict,
+ "error_summary": e.error_summary,
+ "configs": da_conf.get_config_options(),
+ },
+ )
-@drupal_api.route("/ckan-admin/drupal-api", methods=("GET", "POST"))
-def drupal_api_config():
- """
- Invalidates cache
- """
- if not tk.request.form:
- return tk.render(
- "admin/drupal_api_config.html",
- {
- "cache_ttl_default": c.DEFAULT_CACHE_DURATION,
- "cache_ttl_current": tk.config.get(c.CONFIG_CACHE_DURATION),
- "drupal_url": tk.config.get(c.CONFIG_DRUPAL_URL, "").strip('/'),
- "menu_export_endpoint": _get_menu_export_endpoint(),
- "api_version": tk.config.get(c.CONFIG_DRUPAL_API_VERSION, c.DEFAULT_API_VERSION)
- },
- )
- else:
+ tk.h.flash_success(tk._("Config options have been updated"))
+ return tk.h.redirect_to("drupal_api.config")
+
+
+class ConfigClearCacheView(MethodView):
+ def post(self):
if "clear-menu-cache" in tk.request.form:
drop_cache_for(menu.__name__)
- tk.h.flash_success(tk._("Cache has been cleared"))
if "clear-custom-cache" in tk.request.form:
drop_cache_for(custom_endpoint.__name__)
- return tk.h.redirect_to("drupal_api.drupal_api_config")
+ tk.h.flash_success(tk._("Cache has been cleared"))
+
+ return tk.h.redirect_to("drupal_api.config")
+
+drupal_api.add_url_rule(
+ "/config",
+ view_func=ConfigView.as_view("config"),
+ methods=("GET", "POST"),
+)
+drupal_api.add_url_rule(
+ "/clear_cache",
+ view_func=ConfigClearCacheView.as_view("clear_cache"),
+ methods=("POST",),
+)
blueprints = [drupal_api]
diff --git a/setup.py b/setup.py
index 7be6a2a..8a55243 100644
--- a/setup.py
+++ b/setup.py
@@ -16,7 +16,7 @@
# Versions should comply with PEP440. For a discussion on single-sourcing
# the version across setup.py and the project code, see
# http://packaging.python.org/en/latest/tutorial.html#version
- version='0.6.1',
+ version='0.7.0',
description='''''',
long_description=long_description,