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

Support for .env #727

Merged
merged 10 commits into from
Aug 9, 2023
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
17 changes: 17 additions & 0 deletions .flaskenv
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# The settings in this file are secondary to .env, which overrides

# Assume production by default, unset debug and testing state
FLASK_DEBUG=false
FLASK_DEBUG_TB_ENABLED=false
FLASK_TESTING=false

# To only support HTTPS, set Secure Cookies to True
FLASK_SESSION_COOKIE_SECURE=true

# --- App configuration
# Default timezone when user timezone is not known
FLASK_TIMEZONE='Asia/Kolkata'
FLASK_ASSET_MANIFEST_PATH=static/build/manifest.json
# Asset base path – without a trailing slash
FLASK_ASSET_BASE_PATH=/static/build
FLASK_STATIC_SUBDOMAIN=static
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ test.db
.project
.pydevproject
.vscode
.python-version
.settings
.sass-cache
.webassets-cache
Expand Down
2 changes: 1 addition & 1 deletion hasjob/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
from .models import db # isort:skip

# Configure the app
coaster.app.init_app(app)
coaster.app.init_app(app, ['py', 'env'], env_prefix=['FLASK', 'APP_HASJOB'])
db.init_app(app)
db.app = app
migrate = Migrate(app, db)
Expand Down
2 changes: 1 addition & 1 deletion hasjob/uploads.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def process_image(requestfile, maxsize=(170, 130)):
raise UploadNotAllowed("This image is too large to process")
img.load()
if img.size[0] > maxsize[0] or img.size[1] > maxsize[1]:
img.thumbnail(maxsize, Image.ANTIALIAS)
img.thumbnail(maxsize, Image.LANCZOS)
boximg = Image.new(img.mode, maxsize, '#fff0')
boximg.paste(
img, ((boximg.size[0] - img.size[0]) // 2, (boximg.size[1] - img.size[1]) // 2)
Expand Down
70 changes: 0 additions & 70 deletions instance/settings.py
Original file line number Diff line number Diff line change
@@ -1,69 +1,5 @@
import re

#: The title of this site
SITE_TITLE = 'Job Board'
#: TypeKit code for fonts
TYPEKIT_CODE = ''
#: Google Analytics code UA-XXXXXX-X
GA_CODE = ''
#: Database backend
SQLALCHEMY_DATABASE_URI = 'sqlite:///'
#: Secret key
SECRET_KEY = 'make this something random' # nosec B105
#: Timezone
TIMEZONE = 'Asia/Kolkata'
#: Static resource subdomain (defaults to 'static')
STATIC_SUBDOMAIN = 'static'
#: Upload path
UPLOADED_LOGOS_DEST = '/tmp/uploads' # nosec B108
#: Cache settings
CACHE_TYPE = 'redis'
#: RQ settings
RQ_REDIS_URL = 'redis://localhost:6379/0'
RQ_SCHEDULER_INTERVAL = 1
#: GeoIP database file (GeoIP2 or GeoLite2 city mmdb)
#: On Ubuntu: /usr/share/GeoIP/GeoLite2-City.mmdb
#: On Homebrew: /usr/local/var/GeoIP/GeoLite2-City.mmdb
GEOIP_PATH = '/usr/share/GeoIP/GeoLite2-City.mmdb'
#: Mail settings
#: MAIL_FAIL_SILENTLY : default True
#: MAIL_SERVER : default 'localhost'
#: MAIL_PORT : default 25
#: MAIL_USE_TLS : default False
#: MAIL_USE_SSL : default False
#: MAIL_USERNAME : default None
#: MAIL_PASSWORD : default None
#: DEFAULT_MAIL_SENDER : default None
MAIL_FAIL_SILENTLY = False
MAIL_SERVER = 'localhost'
# Mail sender for crash reports and other automated mail
DEFAULT_MAIL_SENDER = 'Hasjob <test@example.com>'
MAIL_DEFAULT_SENDER = DEFAULT_MAIL_SENDER
# Mail sender for job application responses (email address only)
MAIL_SENDER = 'test@example.com'
#: Logging: recipients of error emails
ADMINS = []
#: Log file
LOGFILE = 'error.log'
#: Use SSL for some URLs
USE_SSL = False
#: Twitter integration (register as a "client" app)
TWITTER_ENABLED = False
TWITTER_CONSUMER_KEY = ''
TWITTER_CONSUMER_SECRET = '' # nosec B105
TWITTER_ACCESS_KEY = ''
TWITTER_ACCESS_SECRET = '' # nosec B105
#: Bit.ly integration for short URLs
BITLY_USER = ''
BITLY_KEY = ''
#: Access key for periodic server-only tasks
PERIODIC_KEY = ''
#: Throttle limit for email domain
THROTTLE_LIMIT = 5
#: Don't show year for dates within this many days
SHORTDATE_THRESHOLD_DAYS = 60
#: Email address to display when asking users to contact support
SUPPORT_EMAIL = 'support@hasgeek.com'
#: Words banned in the title and their error messages
BANNED_WORDS = [
[
Expand Down Expand Up @@ -119,9 +55,3 @@
"Candidates must apply via Hasjob",
)
]
#: LastUser server
LASTUSER_SERVER = 'https://hasgeek.com/'
#: LastUser client id
LASTUSER_CLIENT_ID = ''
#: LastUser client secret
LASTUSER_CLIENT_SECRET = '' # nosec B105
53 changes: 27 additions & 26 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,30 +1,31 @@
git+https://github.com/hasgeek/baseframe#egg=baseframe
bleach==6.0.0
bleach
git+https://github.com/hasgeek/coaster#egg=coaster
coverage==7.2.5
dnspython==2.3.0
Flask==2.2.5
Flask-Assets==2.0
coverage
dnspython
Flask
Flask-Assets
git+https://github.com/hasgeek/flask-lastuser#egg=Flask-Lastuser
Flask-Mail==0.9.1
Flask-Migrate==4.0.4
Flask-Redis==0.4.0
Flask-RQ2==18.3
Flask-SQLAlchemy==3.0.3
Flask-Testing==0.8.1
Flask-Mail
Flask-Migrate
Flask-Redis
Flask-RQ2
Flask-SQLAlchemy
Flask-Testing
git+https://github.com/maxcountryman/flask-uploads.git#egg=Flask-Uploads
Flask-WTF==1.1.1
geoip2==4.6.0
html2text==2020.1.16
jsmin==3.0.1
langid==1.1.6
Markdown==3.4.3
Pillow==9.5.0
premailer==3.10.0
progressbar2==4.2.0
psycopg2==2.9.6
pytz==2023.3
SQLAlchemy==2.0.12
SQLAlchemy-Utils==0.41.1
tldextract==3.4.1
tweepy==4.14.0
Flask-WTF
geoip2
gunicorn
html2text
jsmin
langid
Pillow
premailer
progressbar2
psycopg2-binary
python-dotenv
pytz
SQLAlchemy
SQLAlchemy-Utils
tldextract
tweepy
146 changes: 146 additions & 0 deletions sample.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# Sample configuration for the `.env` settings file. These values are interpeted as
# JSON, falling back to plain strings. This file must be a valid shell script, so
# values using shell glob characters '*?[]' must be enclosed in single quotes

# --- Development mode (remove these three in production)
# Coaster uses this value; Flask 2.2's deprecation warning can be ignored
FLASK_ENV=development
# Flask >=2.2 requires this value
FLASK_DEBUG=1
# Flask-DebugToolbar (optional) is useful for dev, but MUST NOT BE enabled in production
FLASK_DEBUG_TB_ENABLED=true

# --- Domain configuration (these must point to 127.0.0.1 in /etc/hosts in dev and test)
# Hasjob app's server name (Hasjob uses 'hasjob.co' in production)
FLASK_SERVER_NAME=hasjob.test:5001
# Auth cookie domain (auth cookie is shared across apps in subdomains)
FLASK_LASTUSER_COOKIE_DOMAIN=.hasjob.test
FLASK_SESSION_COOKIE_DOMAIN=.hasjob.test
# For dev, uncomment to override secure cookies, when not using HTTPS
# FLASK_SESSION_COOKIE_SECURE=false

# --- Secrets
# Secret keys with key rotation -- put older keys further down the list. Older keys will
# be used to decode tokens as fallback, but will not be used to encode. Remove old keys
# when they are considered expired
FLASK_SECRET_KEYS='["make-this-something-random", "older-secret-keys-here"]'
# Secret key for sitemap URLs submitted to Google
SITEMAP_KEY=make-this-something-random

# --- Analytics
# Google Analytics code
FLASK_GA_CODE=null
# Matomo analytics (shared config across apps; URL must have trailing slash)
FLASK_MATOMO_URL=https://...
# MATOMO_JS and MATOMO_FILE have default values; override if your installation varies
# FLASK_MATOMO_JS=matomo.js
# FLASK_MATOMO_FILE=matomo.php
# Matomo API key, used in funnel.cli.periodic.stats
FLASK_MATOMO_TOKEN=null
# Matomo site id (app-specific)
FLASK_MATOMO_ID=

# --- Statsd logging (always enabled, emits to UDP)
# Support for tagging varies between implementations:
# Etsy's statsd doesn't support tagging (default `false` merges tags into metric name)
# Telegraf uses `,` as a tag separator
# Prometheus uses `;` as a tag separator
FLASK_STATSD_TAGS=,
# Other statsd settings have default values:
# FLASK_STATSD_HOST=127.0.0.1
# FLASK_STATSD_PORT=8125
# FLASK_STATSD_MAXUDPSIZE=512
# FLASK_STATSD_IPV6=false
# Sampling rate, 0.0-1.0, default 1 logs 100%
# FLASK_STATSD_RATE=1
# FLASK_STATSD_TAGS=false
# Log all Flask requests (time to serve, response status code)
# FLASK_STATSD_REQUEST_LOG=true
# Log all WTForms validations (when using baseframe.forms.Form subclass)
# FLASK_STATSD_FORM_LOG=true

# --- Redis Queue and Redis cache (use separate dbs to isolate)
# Redis server host
REDIS_HOST=localhost
# RQ and cache
FLASK_RQ_REDIS_URL=redis://${REDIS_HOST}:6379/1
FLASK_CACHE_TYPE=flask_caching.backends.RedisCache
FLASK_CACHE_REDIS_URL=redis://${REDIS_HOST}:6379/0

# --- Database configuration
DB_HOST=localhost
FLASK_SQLALCHEMY_DATABASE_URI='postgresql:///hasjob'

# --- Email configuration
# SMTP mail server ('localhost' if Postfix is configured as a relay email server)
FLASK_MAIL_SERVER=localhost
# If not using localhost, SMTP will need authentication
# Port number (25 is default, but 587 is more likely for non-localhost)
FLASK_MAIL_PORT=25
# Port 25 uses neither TLS nor SSL. Port 587 uses TLS and port 465 uses SSL (obsolete)
FLASK_MAIL_USE_TLS=false
FLASK_MAIL_USE_SSL=false
# Authentication if using port 587 or 465
FLASK_MAIL_USERNAME=null
FLASK_MAIL_PASSWORD=null
# Default "From:" address in email
FLASK_MAIL_DEFAULT_SENDER="Hasjob <sender@example.com>"

# --- App configuration
# Support email and phone numbers (must be syntactically valid)
FLASK_SITE_SUPPORT_EMAIL=support@example.com
# Posting throttle limit
FLASK_THROTTLE_LIMIT=5

# --- GeoIP databases for IP address geolocation (used in account settings)
# Obtain a free license key from Maxmind, install geoipupdate, place the account id and
# key in GeoIP.conf and enable the GeoLite2-ASN database. The location of GeoIP.conf
# varies between Ubuntu and macOS.
# https://support.maxmind.com/hc/en-us/articles/4407111582235-Generate-a-License-Key

# Ubuntu:
# sudo add-apt-repository ppa:maxmind/ppa
# sudo apt install geoipupdate
# vim /etc/GeoIP.conf
# sudo geoipupdate -f /etc/GeoIP.conf
# FLASK_GEOIP_PATH=/usr/share/GeoIP/GeoLite2-City.mmdb

# macOS with Homebrew on Apple Silicon:
# brew install geoipupdate
# vim /opt/homebrew/etc/GeoIP.conf
# geoipupdate -f /opt/homebrew/etc/GeoIP.conf
# FLASK_GEOIP_PATH=/opt/homebrew/var/GeoIP/GeoLite2-City.mmdb

# --- Logging
# Optional path to log file, or default null to disable file logging
FLASK_LOG_FILE=null
# Optional config for file logging:
# FLASK_LOG_FILE_LEVEL accepts NOTSET, DEBUG, INFO, WARNING (default), ERROR, CRITICAL
# FLASK_LOG_FILE_DELAY (bool, default true, delays log file creation until first log)
# FLASK_LOG_FILE_ROTATE (bool, default true, controls logrotate on the basis of time)
# FLASK_LOG_FILE_ROTATE_WHEN (default "midnight", other options: S, M, H, D, W0-W6)
# FLASK_LOG_FILE_ROTATE_COUNT (count of old files to keep, default 7 for a week's worth)
# FLASK_LOG_FILE_ROTATE_UTC (default false, if set uses UTC for midnight and W0-W6)

# List of email addresses to send error reports with traceback and local var dump
# This requires SMTP config (above)
FLASK_LOG_EMAIL_TO='["webmaster@example.com"]'
# Additional options: FLASK_LOG_EMAIL_FROM, defaults to FLASK_MAIL_DEFAULT_SENDER

# Send error reports to a Telegram chat
FLASK_LOG_TELEGRAM_CHATID=null
# Use these bot API credentials (configure your bot at https://t.me/botfather)
FLASK_LOG_TELEGRAM_APIKEY=null
# Optional settings:
# FLASK_LOG_TELEGRAM_THREADID (if the chat has topic threads, use a specific thread)
# FLASK_LOG_TELEGRAM_LEVEL=NOTSET, DEBUG, INFO, WARNING (default), ERROR, CRITICAL

# --- Hasgeek app integrations
FLASK_LASTUSER_SERVER=http://funnel.test:3000
FLASK_LASTUSER_CLIENT_ID=client_id_from_funnel
FLASK_LASTUSER_CLIENT_SECRET=client_secret_from_funnel

# --- External app integrations


# --- OAuth2 login integrations
10 changes: 10 additions & 0 deletions wsgi.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
import os.path
import sys

from flask.cli import load_dotenv
from flask.helpers import get_load_dotenv
from werkzeug.middleware.proxy_fix import ProxyFix

__all__ = ['application']

sys.path.insert(0, os.path.dirname(__file__))
if get_load_dotenv():
load_dotenv()

# pylint: disable=wrong-import-position
from hasjob import app as application # isort:skip

application.wsgi_app = ProxyFix(application.wsgi_app) # type: ignore[method-assign]