Skip to content
Snippets Groups Projects
Commit de483ec4 authored by Jan Mach's avatar Jan Mach
Browse files

Implemented Hawat command line interface based on flask.cli and Click.

Currently only built-in Flask commands run, shell, etc. are available. It can be used to launch development web server, which is now documented in development documentation page. (Redmine issue: #4216)
parent 72b7e4dc
No related branches found
No related tags found
No related merge requests found
......@@ -102,6 +102,8 @@ help:
@echo " * $(GREEN)deps-postgresql$(NC): configure required PostgreSQL user accounts and databases"
@echo " * $(GREEN)deps-translations$(NC): compile all available translations"
@echo ""
@echo " * $(GREEN)run-webui-dev$(NC): run development web server with development configuration"
@echo ""
@echo " * $(GREEN)clean-pycs$(NC): clean up Python compiled files"
@echo " * $(GREEN)clean-build-python$(NC): clean up Python build directories"
@echo " * $(GREEN)clean-build-debian$(NC): clean up Debian build directories"
......@@ -331,6 +333,14 @@ deps-postgresql: FORCE
#-------------------------------------------------------------------------------
run-webui-dev:
@echo "\n$(GREEN)*** Running development web server with development configuration ***$(NC)\n"
FLASK_ENV=development FLASK_CONFIG=development FLASK_CONFIG_FILE=$(shell realpath ./hawat.local.conf) hawat-cli run
#-------------------------------------------------------------------------------
clean-pycs: FORCE
@echo "\n$(GREEN)*** Cleaning up Python precompiled files ***$(NC)\n"
@find . -name '*.pyc' -delete
......
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#-------------------------------------------------------------------------------
# This file is part of Mentat system (https://mentat.cesnet.cz/).
#
# Copyright (C) since 2011 CESNET, z.s.p.o (http://www.ces.net/)
# Use of this source is governed by the MIT license, see LICENSE file.
#-------------------------------------------------------------------------------
"""
Web interface for Mentat system - local development server
This command will launch built-in development HTTP server and bind it to ``localhost``,
port ``5000``. It will also force the debug mode to ``True``.
Usage
^^^^^
Just execute with Python3 interpreter::
python3 mentat-hawat.py
Now point your browser to ``localhost``, port ``5000``::
http://localhost:5000
License
^^^^^^^
Copyright (C) since 2011 CESNET, z.s.p.o (http://www.ces.net/)
Use of this source is governed by the MIT license.
"""
__author__ = "Jan Mach <jan.mach@cesnet.cz>"
__credits__ = "Pavel Kácha <pavel.kacha@cesnet.cz>, Andrea Kropáčová <andrea.kropacova@cesnet.cz>"
if __name__ == '__main__':
import hawat
#
# Use prepared factory function to create application instance. The factory
# function takes number of arguments, that can be used to fine tune coniguration
# of the application. This is can be very usefull when extending applications`
# capabilities or for purposes of testing. Please refer to the documentation
# for more information.
#
APP = hawat.create_app(
config_object = 'hawat.config.DevelopmentConfig'
)
#
# Launch WSGI application, bind to localhost:5000 and enforce debug mode to True.
#
APP.run(
host = '127.0.0.1',
port = 5000,
debug = True
)
......@@ -15,4 +15,9 @@ import hawat
# capabilities or for purposes of testing. Please refer to the documentation
# for more information.
#
application = hawat.create_app()
application = hawat.create_app_full(
config_object = 'hawat.config.ProductionConfig',
config_file = '/etc/mentat/mentat-hawat.py.conf',
config_env = 'FLASK_CONFIG_FILE'
)
.. _section-bin-mentat-hawat:
mentat-hawat.py
================================================================================
Web interface for Mentat system - local development server
This command will launch built-in development HTTP server and bind it to ``localhost``,
port ``5000``. It will also force the debug mode to ``True``.
Usage
^^^^^
Just execute with Python3 interpreter::
python3 mentat-hawat.py
Now point your browser to ``localhost``, port ``5000``::
http://localhost:5000
......@@ -198,6 +198,65 @@ targets::
(venv) $ make deps-webui-upgrade
Running development web server
````````````````````````````````````````````````````````````````````````````````
The web interface for this project is written in excellent `Flask <http://flask.pocoo.org/>`__
microframework, that comes with built-in webserver for development. It can be
launched in following ways::
# A: You may use the Flask built-in command in a following way:
(venv) $ FLASK_APP=hawat FLASK_ENV=development FLASK_CONFIG=development FLASK_CONFIG_FILE=$(realpath ./hawat.local.conf) flask run
# B: You may custom command line interface to launch webserver in development
# mode and with development configuration:
(venv) $ FLASK_ENV=development FLASK_CONFIG=development FLASK_CONFIG_FILE=$(realpath ./hawat.local.conf) hawat-cli run
# C: Use following makefile target to do the same as the three above with less
# typing:
(venv) $ make run-webui-dev
There are following environment variables you may use to tweak the application
launch according to your needs:
* ``FLASK_DEBUG``
This configuration controls state of the internal debugger independently on the
``FLASK_ENV`` setting. It is a boolean value and should be either ``True`` or
``False``. Default value is ``False``.
* ``FLASK_ENV``
This configuration controls application environment setting. This is a string
value and should be either ``development`` or ``production``. Default value is
``production``.
* ``FLASK_CONFIG``
This configuration controls the name of the configuration class from :py:mod:`mydojo.config`
module that will be used to configure the application. Valid value is one of the
:py:attr:`mydojo.config.CONFIG_MAP`. Default value is ``default``.
* ``FLASK_CONFIG_FILE``
This configuration controls the name of the configuration file that will be used
to further configure the application. Values in this file are applied last and
will override anything in the configuration classes from :py:mod:`mydojo.config`.
Default value is empty. It must point to existing file if set, otherwise an exception
will be raised. Please use absolute path to the file to avoid any surprises.
.. note::
The ``FLASK_CONFIG_FILE`` is especially handy for customizing the local
application configuration during development process or during deployment.
For more information please study following resources:
* `Flask: Command Line Interface <http://flask.pocoo.org/docs/1.0/cli/>`__
* `Flask: Configuration Handling <http://flask.pocoo.org/docs/1.0/config/>`__
* `Flask API: Configuration <http://flask.pocoo.org/docs/1.0/api/#configuration>`__
Documentation
````````````````````````````````````````````````````````````````````````````````
......
SECRET_KEY = 'local-secret-key'
HAWAT_LOG_DEFAULT_LEVEL = 'debug'
HAWAT_LOG_FILE = '/var/tmp/hawat.dev.log'
HAWAT_LOG_FILE_LEVEL = 'debug'
......@@ -78,5 +78,14 @@ __author__ = "Jan Mach <jan.mach@cesnet.cz>"
__credits__ = "Pavel Kácha <pavel.kacha@cesnet.cz>, Andrea Kropáčová <andrea.kropacova@cesnet.cz>"
# Expose main application factory to current namespace
from .app import create_app
import click
from flask.cli import FlaskGroup
# Expose main application factories to current namespace
from .app import create_app, create_app_full
@click.group(cls = FlaskGroup, create_app = create_app)
def cli():
"""Command line interface for the Hawat application."""
......@@ -49,6 +49,7 @@ import mentat.idea.jsondict
import hawat.base
import hawat.const
import hawat.config
import hawat.acl
import hawat.log
import hawat.db
......@@ -56,6 +57,9 @@ import hawat.events
from hawat.models.user import GuiUserModel
APP_NAME = 'hawat'
"""Name of the application as a constant for Flask."""
RE_COUNTRY_CODE = re.compile('^[a-zA-Z]{2,3}$')
"""Regular expression for validating language/country codes."""
......@@ -63,6 +67,69 @@ RE_COUNTRY_CODE = re.compile('^[a-zA-Z]{2,3}$')
#-------------------------------------------------------------------------------
def create_app_full(
config_dict = None,
config_object = 'hawat.config.ProductionConfig',
config_file = None,
config_env = 'FLASK_CONFIG_FILE'):
"""
Factory function for building Hawat application. This function takes number of
optional arguments, that can be used to create a very customized instance of
Hawat application. This can be very usefull when extending applications`
capabilities or for purposes of testing. Each of these arguments has default
value for the most common application setup, so for disabling it entirely it
is necessary to provide ``None`` as a value.
:param dict config_dict: Initial default configurations.
:param str config_object: Name of the class or module containing configurations.
:param str config_file: Name of the file containing additional configurations.
:param str config_env: Name of the environment variable pointing to file containing configurations.
:return: Hawat application
:rtype: hawat.base.HawatApp
"""
app = hawat.base.HawatApp(APP_NAME)
if config_dict and isinstance(config_dict, dict):
app.config.update(config_dict)
if config_object:
app.config.from_object(config_object)
if config_file:
app.config.from_pyfile(config_file)
if config_env and os.getenv(config_env, None):
app.config.from_envvar(config_env)
_setup_app_logging(app)
_setup_app_mailer(app)
_setup_app_core(app)
_setup_app_db(app)
_setup_app_eventdb(app)
_setup_app_auth(app)
_setup_app_acl(app)
_setup_app_babel(app)
_setup_app_menu(app)
_setup_app_blueprints(app)
return app
def create_app():
"""
Factory function for building Hawat application. This function does not take
any arguments, any necessary customizations must be done using environment
variables.
:return: Hawat application
:rtype: hawat.base.HawatApp
"""
config_name = os.getenv('FLASK_CONFIG', 'default')
return create_app_full(
config_object = hawat.config.CONFIG_MAP[config_name]
)
#-------------------------------------------------------------------------------
def _setup_app_logging(app):
"""
Setup logging to file and via email for given Hawat application. Logging
......@@ -819,52 +886,3 @@ def _setup_app_blueprints(app):
app.register_blueprints()
return app
#-------------------------------------------------------------------------------
def create_app(
config_dict = None,
config_object = 'hawat.config.ProductionConfig',
config_file = '/etc/mentat/mentat-hawat.py.conf',
config_env = 'HAWAT_CONFIG_FILE'):
"""
Factory function for building Hawat application. This function takes number of
optional arguments, that can be used to create a very customized instance of
Hawat application. This can be very usefull when extending applications`
capabilities or for purposes of testing. Each of these arguments has default
value for the most common application setup, so for disabling it entirely it
is necessary to provide ``None`` as a value.
:param dict config_dict: Initial default configurations.
:param str config_object: Name of the class or module containing configurations.
:param str config_file: Name of the file containing configurations.
:param str config_env: Name of the environment variable pointing to file containing configurations.
:return: Hawat application
:rtype: hawat.base.HawatApp
"""
app = hawat.base.HawatApp('hawat')
if config_dict and isinstance(config_dict, dict):
app.config.update(config_dict)
if config_object:
app.config.from_object(config_object)
if config_file:
app.config.from_pyfile(config_file, silent = True)
if config_env:
app.config.from_envvar(config_env, silent = True)
_setup_app_logging(app)
_setup_app_mailer(app)
_setup_app_core(app)
_setup_app_db(app)
_setup_app_eventdb(app)
_setup_app_auth(app)
_setup_app_acl(app)
_setup_app_babel(app)
_setup_app_menu(app)
_setup_app_blueprints(app)
return app
......@@ -303,3 +303,12 @@ class TestingConfig(Config): # pylint: disable=locally-disabled,too-few-public-
TESTING = True
"""Overwritten default value from :py:const:`hawat.config.Config.TESTING`"""
CONFIG_MAP = {
'development': DevelopmentConfig,
'production': ProductionConfig,
'testing': TestingConfig,
'default': ProductionConfig
}
"""Configuration map for easy mapping of configuration aliases to config objects."""
......@@ -120,11 +120,11 @@ setup(
#
# Resources:
# http://flask.pocoo.org/docs/1.0/cli/#custom-commands
#entry_points={
# 'console_scripts': [
# 'hawat-cli=hawat:cli'
# ],
#},
entry_points={
'console_scripts': [
'hawat-cli=hawat:cli'
],
},
include_package_data = True,
zip_safe = False
)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment