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

FLEXMEASURES_PLUGINS configurable from env #660

Merged
merged 7 commits into from May 5, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions documentation/changelog.rst
Expand Up @@ -15,6 +15,8 @@ Bugfixes
Infrastructure / Support
----------------------

.. warning:: The setting `FLEXMEASURES_PLUGIN_PATHS` has been sunset. It had been deprecated since v0.7.


v0.13.0 | May 1, 2023
============================
Expand Down
18 changes: 17 additions & 1 deletion documentation/configuration.rst
Expand Up @@ -26,6 +26,8 @@ Level above which log messages are added to the log file. See the ``logging`` pa

Default: ``logging.WARNING``

.. note:: This setting is also recognized as environment variable.


.. _modes-config:

Expand Down Expand Up @@ -72,6 +74,7 @@ FLEXMEASURES_PLUGINS
^^^^^^^^^^^^^^^^^^^^^^^^^

A list of plugins you want FlexMeasures to load (e.g. for custom views or CLI functions).
This can be a Python list (e.g. ``["plugin1", "plugin2"]``) or a comma-separated string (e.g. ``"plugin1, plugin2"``).

Two types of entries are possible here:

Expand All @@ -80,9 +83,10 @@ Two types of entries are possible here:

Added functionality in plugins needs to be based on Flask Blueprints. See :ref:`plugins` for more information and examples.


Default: ``[]``

.. note:: This setting is also recognized as environment variable.


FLEXMEASURES_DB_BACKUP_PATH
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down Expand Up @@ -299,6 +303,8 @@ Token for accessing the MapBox API (for displaying maps on the dashboard and ass

Default: ``None``

.. note:: This setting is also recognized as environment variable.

.. _sentry_access_token:

SENTRY_SDN
Expand All @@ -309,6 +315,8 @@ E.g.: ``https://<examplePublicKey>@o<something>.ingest.sentry.io/<project-Id>``

Default: ``None``

.. note:: This setting is also recognized as environment variable.


SQLAlchemy
----------
Expand All @@ -323,6 +331,9 @@ Connection string to the postgres database, format: ``postgresql://<user>:<passw

Default: ``None``

.. note:: This setting is also recognized as environment variable.


SQLALCHEMY_ENGINE_OPTIONS
^^^^^^^^^^^^^^^^^^^^^^^^^

Expand Down Expand Up @@ -432,6 +443,8 @@ For FlexMeasures to be able to send email to users (e.g. for resetting passwords
This is only a selection of the most important settings.
See `the Flask-Mail Docs <https://flask-mail.readthedocs.io/en/latest/#configuring-flask-mail>`_ for others.

.. note:: The mail settings are also recognized as environment variables.

MAIL_SERVER (*)
^^^^^^^^^^^^^^^

Expand Down Expand Up @@ -543,6 +556,9 @@ Redis

FlexMeasures uses the Redis database to support our forecasting and scheduling job queues.

.. note:: The redis settings are also recognized as environment variables.


FLEXMEASURES_REDIS_URL (*)
^^^^^^^^^^^^^^^^^^^^^^^^^^

Expand Down
29 changes: 29 additions & 0 deletions documentation/plugin/customisation.rst
Expand Up @@ -81,6 +81,35 @@ get computed by your custom function! For later lookup, the data will be linked
.. todo:: We're planning to use a similar approach to allow for custom forecasting algorithms, as well.


Deploying your plugin via Docker
----------------------------------

You can extend the FlexMeasures Docker image with your plugin's logic.
nhoening marked this conversation as resolved.
Show resolved Hide resolved

Imagine your package (with an ``__init__.py`` file, one of the setups we discussed in :ref:`plugin_showcase`) is called ``flexmeasures_testplugin``.
Then, this is a minimal possible Dockerfile:

.. code-block:: docker

FROM lfenergy/flexmeasures

COPY flexmeasures_testplugin/ /app/flexmeasures_testplugin
ENV FLEXMEASURES_PLUGINS="/app/flexmeasures_testplugin"

nhoening marked this conversation as resolved.
Show resolved Hide resolved

If you also want to install your requirements, you could for instance add these layers:

.. code-block:: docker

COPY requirements/app.in /app/requirements/flexmeasures_testplugin.txt
RUN pip3 install --no-cache-dir -r requirements/flexmeasures_testplugin.txt

.. note:: No need to install flexmeasures here, as the Docker image we are based on already installed FlexMeasures from code. If you pip3-install your plugin here (assuming it's on Pypi), check if it recongizes that FlexMeasures installation as it should.
nhoening marked this conversation as resolved.
Show resolved Hide resolved

.. warning:: Using the :ref:`plugin-config` setting like this depends on FlexMeasures version v0.14.
nhoening marked this conversation as resolved.
Show resolved Hide resolved



Adding your own style sheets
----------------------------

Expand Down
2 changes: 1 addition & 1 deletion flexmeasures/utils/config_defaults.py
Expand Up @@ -95,7 +95,7 @@ class Config(object):
# This setting contains the domain on which FlexMeasures runs
# and the first month when the domain was under the current owner's administration
FLEXMEASURES_HOSTS_AND_AUTH_START: dict = {"flexmeasures.io": "2021-01"}
FLEXMEASURES_PLUGINS: List[str] = []
FLEXMEASURES_PLUGINS: Union[List[str], str] = [] # str will be checked for commas
nhoening marked this conversation as resolved.
Show resolved Hide resolved
FLEXMEASURES_PROFILE_REQUESTS: bool = False
FLEXMEASURES_DB_BACKUP_PATH: str = "migrations/dumps"
FLEXMEASURES_MENU_LOGO_PATH: str = ""
Expand Down
2 changes: 1 addition & 1 deletion flexmeasures/utils/config_utils.py
Expand Up @@ -163,7 +163,7 @@ def read_env_vars(app: Flask):
for var in (
required
+ list(warnable.keys())
+ ["LOGGING_LEVEL", "MAPBOX_ACCESS_TOKEN", "SENTRY_SDN"]
+ ["LOGGING_LEVEL", "MAPBOX_ACCESS_TOKEN", "SENTRY_SDN", "FLEXMEASURES_PLUGINS"]
):
app.config[var] = os.getenv(var, app.config.get(var, None))
# DEBUG in env can come in as a string ("True") so make sure we don't trip here
Expand Down
8 changes: 2 additions & 6 deletions flexmeasures/utils/plugin_utils.py
Expand Up @@ -24,12 +24,8 @@ def register_plugins(app: Flask):
(last part of the path).
"""
plugins = app.config.get("FLEXMEASURES_PLUGINS", [])
if not plugins:
# this is deprecated behaviour which we should remove in version 1.0
app.logger.debug(
"No plugins configured. Attempting deprecated setting FLEXMEASURES_PLUGIN_PATHS ..."
)
plugins = app.config.get("FLEXMEASURES_PLUGIN_PATHS", [])
if isinstance(plugins, str):
plugins = [plugin.strip() for plugin in plugins.split(",")]
nhoening marked this conversation as resolved.
Show resolved Hide resolved
if not isinstance(plugins, list):
app.logger.error(
f"The value of FLEXMEASURES_PLUGINS is not a list: {plugins}. Cannot install plugins ..."
Expand Down