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

feat: use dotenv files to specify environment variables #180

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
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
11 changes: 10 additions & 1 deletion app/__init__.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import datetime
import uuid

from dotenv import load_dotenv
from flask import Flask, Blueprint
from flask_jwt_extended import JWTManager
from flask_mail import Mail
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import MetaData

from app.utils import make_403
from config import config
from app.api.response import APIResponseFactory
from flask_httpauth import HTTPBasicAuth

Expand Down Expand Up @@ -59,8 +59,17 @@ def create_app(config_name="dev"):
""" Create the application """
app = Flask( __name__)
if not isinstance(config_name, str):
from config import config
app.config.from_object(config)
else:
print("Load environment variables for config '%s'" % config_name)
# It is important to load the .env file before parsing the config file
import os
dir_path = os.path.dirname(os.path.realpath(__file__))
env_filename = os.path.join(dir_path, '..', '%s.env' % config_name)
print(".env file to be loaded : ", env_filename)
load_dotenv(env_filename, verbose=True)
from config import config
app.config.from_object(config[config_name])

app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
Expand Down
1 change: 0 additions & 1 deletion app/api/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
from app.models import User, Role

from app.utils import make_401, forbid_if_nor_teacher_nor_admin, make_400, make_200
from .. import config


@api_bp.route('/api/<api_version>/logout')
Expand Down
73 changes: 38 additions & 35 deletions config.py
Original file line number Diff line number Diff line change
@@ -1,39 +1,44 @@
import datetime
from time import time

import os
import shutil
import urllib

basedir = os.path.abspath(os.path.dirname(__file__))

def parse_var_env(var_name):
v = os.environ.get(var_name)
if v == "True":
v = True
elif v == "False":
v = False
return v


class Config(object):
ENV = "prod"
SECRET_KEY = os.environ.get('SECRET_KEY')
ENV = "production"
DEBUG = False

SECRET_KEY = parse_var_env("SECRET_KEY")

APP_URL_PREFIX = "/adele" # used to build correct iiif urls

SQLALCHEMY_DATABASE_URI = 'sqlite:////' + os.path.join(os.path.abspath(os.getcwd()), 'db', 'adele.sqlite')
SQLALCHEMY_TRACK_MODIFICATIONS = False
SQLALCHEMY_DATABASE_URI = 'sqlite:////' + os.path.join(basedir, parse_var_env('DATABASE_URI'))
SQLALCHEMY_TRACK_MODIFICATIONS = parse_var_env('SQLALCHEMY_TRACK_MODIFICATIONS') or False

DOC_PER_PAGE = 20
USERS_PER_PAGE = 10
DOC_PER_PAGE = int(parse_var_env('DOC_PER_PAGE'))
USERS_PER_PAGE = int(parse_var_env('USERS_PER_PAGE'))

CSRF_ENABLED = True
CSRF_ENABLED = parse_var_env("CSRF_ENABLED")

# Flask-Mail settings
MAIL_SERVER = 'relay.huma-num.fr'
MAIL_PORT = 25
MAIL_USE_TLS = False
MAIL_USE_SSL = False
MAIL_USERNAME = '[email protected]'

JWT_SECRET_KEY = os.getenv('JWT_SECRET_KEY')
JWT_TOKEN_LOCATION = ['cookies', 'headers']
JWT_COOKIE_CSRF_PROTECT = True
JWT_COOKIE_SECURE = True
JWT_IDENTITY_CLAIM = 'sub'
MAIL_SERVER = parse_var_env('MAIL_SERVER')
MAIL_PORT = int(parse_var_env('MAIL_PORT'))
MAIL_USE_TLS = parse_var_env("MAIL_USE_TLS")
MAIL_USE_SSL = parse_var_env("MAIL_USE_SSL")
MAIL_USERNAME = parse_var_env("MAIL_USERNAME")

JWT_SECRET_KEY = parse_var_env('JWT_SECRET_KEY')
JWT_TOKEN_LOCATION = [location.strip() for location in parse_var_env('JWT_TOKEN_LOCATION').split(',')]
JWT_COOKIE_CSRF_PROTECT = parse_var_env("JWT_COOKIE_CSRF_PROTECT")
JWT_COOKIE_SECURE =parse_var_env("JWT_COOKIE_SECURE")
JWT_IDENTITY_CLAIM = parse_var_env("JWT_IDENTITY_CLAIM")

# JWT_ACCESS_TOKEN_EXPIRES = datetime.timedelta(seconds=int(os.getenv(('JWT_ACCESS_TOKEN_EXPIRES'))))

Expand All @@ -44,28 +49,26 @@ def init_app(app):

class DevelopmentConfig(Config):
ENV = 'development'
DEBUG = True

SECRET_KEY = 'you-will-never-guess-but-please-change-me!'
@staticmethod
def init_app(app):
print('THIS APP IS IN PRE-PROD MODE. YOU SHOULD NOT SEE THIS IN PRODUCTION.')

APP_URL_PREFIX = "" # used to build correct iiif urls

JWT_COOKIE_CSRF_PROTECT = False
JWT_COOKIE_SECURE = False
class LocalConfig(Config):
ENV = 'development'
DEBUG = True

@staticmethod
def init_app(app):
app.debug = True
print('THIS APP IS IN LOCAL DEV MODE. YOU SHOULD NOT SEE THIS IN PRODUCTION.')


class TestConfig(Config):
ENV = 'test'
DEBUG = True

DB_PATH = os.path.join(basedir, "tests", "data")
SQLALCHEMY_DATABASE_URI = 'sqlite:////' + os.path.join(os.path.abspath(os.getcwd()), DB_PATH, 'adele.test.sqlite')

SECRET_KEY = 'you-will-never-guess-but-please-change-me'

MAIL_USERNAME = '[email protected]'
USER_EMAIL_SENDER_NAME = 'Adele'
USER_EMAIL_SENDER_EMAIL = '[email protected]'
MAIL_SERVER = 'smtp.chartes.psl.eu'
Expand All @@ -79,7 +82,6 @@ class TestConfig(Config):
def init_app(app):
print("APP STARTED FROM TEST CONFIG\n")
app.testing = True
app.debug = False
"""
path = os.path.join(TestConfig.DB_PATH, 'adele.sqlite')
print("** fetching new db **")
Expand All @@ -91,6 +93,7 @@ def init_app(app):


config = {
"local": LocalConfig,
"dev": DevelopmentConfig,
"prod": Config,
"test": TestConfig
Expand Down
24 changes: 24 additions & 0 deletions dev.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
SECRET_KEY = 'my-dev-secret-key'

APP_URL_PREFIX=""

DATABASE_URI='db/adele.sqlite'
SQLALCHEMY_TRACK_MODIFICATIONS = False

DOC_PER_PAGE = 20
USERS_PER_PAGE = 10

CSRF_ENABLED = True

# Flask-Mail settings
MAIL_SERVER = 'relay.huma-num.fr'
MAIL_PORT = 25
MAIL_USE_TLS = False
MAIL_USE_SSL = False
MAIL_USERNAME = '[email protected]'

JWT_SECRET_KEY = os.getenv('JWT_SECRET_KEY')
JWT_TOKEN_LOCATION = "cookies,headers"
JWT_COOKIE_CSRF_PROTECT = False
JWT_COOKIE_SECURE = False
JWT_IDENTITY_CLAIM = 'sub'
36 changes: 34 additions & 2 deletions flask_app.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,38 @@
import os, sys, argparse
from app import create_app

app = flask_app = create_app()

if __name__ == "__main__":
POSSIBLE_ENV_VALUES = [ "local", "dev", "prod", "test" ]

def main():
#################################################################
# Selecting the .env file to use for deployment (default = dev) #
#################################################################


# Creating a dictionary of flask_app.py options (--config=dev) and their matching environment variables files aliases (dev)
# Creating a flask_app.py --help listing these options
parser = argparse.ArgumentParser(
description='Flask app for dico-topo'
)
parser.add_argument('--config', type=str, choices=POSSIBLE_ENV_VALUES ,default='dev', help="/".join(POSSIBLE_ENV_VALUES) + ' to select the appropriate .env file to use, default=dev', metavar='')
args = parser.parse_args()
# Checking on the .env to be selected for deployment
# For server deployments, the .env name can be provided from the server configuration
server_env_config_env_var = os.environ.get('SERVER_ENV_CONFIG')
if server_env_config_env_var:
print("Server provided an .env file : ", server_env_config_env_var)
env = server_env_config_env_var
# Otherwise, check if .env file to use is provided in command line (with '--config=' option)
else:
env = args.config
print("selected_env_file : ", env)

###############################################
# Launching app with the selected environment #
###############################################
flask_app = create_app(config_name=env)
flask_app.run(debug=True, port=5000, host='0.0.0.0')

if __name__ == "__main__":
main()
24 changes: 24 additions & 0 deletions local.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
SECRET_KEY = 'my-local-secret-key'

APP_URL_PREFIX=""

DATABASE_URI='db/adele.sqlite'
SQLALCHEMY_TRACK_MODIFICATIONS = False

DOC_PER_PAGE = 20
USERS_PER_PAGE = 10

CSRF_ENABLED = True

# Flask-Mail settings
MAIL_SERVER = 'relay.huma-num.fr'
MAIL_PORT = 25
MAIL_USE_TLS = False
MAIL_USE_SSL = False
MAIL_USERNAME = '[email protected]'

JWT_SECRET_KEY = 'my-local-jwt-secret-key'
JWT_TOKEN_LOCATION = 'cookies, headers'
JWT_COOKIE_CSRF_PROTECT = False
JWT_COOKIE_SECURE = False
JWT_IDENTITY_CLAIM = 'sub'
24 changes: 24 additions & 0 deletions prod.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
SECRET_KEY = ${SECRET_KEY}

APP_URL_PREFIX=/adele

DATABASE_URI='db/adele.sqlite'
SQLALCHEMY_TRACK_MODIFICATIONS = False

DOC_PER_PAGE = 20
USERS_PER_PAGE = 10

CSRF_ENABLED = True

# Flask-Mail settings
MAIL_SERVER = 'relay.huma-num.fr'
MAIL_PORT = 25
MAIL_USE_TLS = False
MAIL_USE_SSL = False
MAIL_USERNAME = '[email protected]'

JWT_SECRET_KEY = ${JWT_SECRET_KEY}
JWT_TOKEN_LOCATION = 'cookies,headers'
JWT_COOKIE_CSRF_PROTECT = True
JWT_COOKIE_SECURE = True
JWT_IDENTITY_CLAIM = 'sub'
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@ idna==2.6
imagesize==1.0.0
itsdangerous==2.0.1
Jinja2==3.0.1
lxml==4.6.5
lxml==
Mako==1.0.7
MarkupSafe==2.0.1
python-dotenv==0.19.2
nose==1.3.7
packaging==17.1
passlib==1.7.1
Expand Down
24 changes: 24 additions & 0 deletions test.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
SECRET_KEY = 'my-test-secret-key'

APP_URL_PREFIX=/adele

DATABASE_URI='tests/data/adele.test.sqlite'
SQLALCHEMY_TRACK_MODIFICATIONS = False

DOC_PER_PAGE = 20
USERS_PER_PAGE = 10

CSRF_ENABLED = True

# Flask-Mail settings
MAIL_SERVER = 'smtp.chartes.psl.eu'
MAIL_PORT = 465
MAIL_USE_TLS = False
MAIL_USE_SSL = 1
MAIL_USERNAME = '[email protected]'

JWT_SECRET_KEY = 'my-test-jwt-secret-key'
JWT_TOKEN_LOCATION = 'cookies,headers'
JWT_COOKIE_CSRF_PROTECT = True
JWT_COOKIE_SECURE = True
JWT_IDENTITY_CLAIM = 'sub'