Script to create a flask project skeleton in my desired format. Configs from file, basic SQLAlchemy with default sqlite3 db, Makefile, app blueprint separation, etc.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

272 lines
7.5 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. # Create the blueprint for a new flask project
  2. if [[ -z $1 ]]; then
  3. echo "[FlaskCreate] Syntax Error: flask-create.sh <project_name> <parent_directory:default cwd>"
  4. exit;
  5. fi
  6. PROJECT_NAME=$1
  7. PROJECT_ROOT=$2
  8. if [[ -z $PROJECT_ROOT ]]; then
  9. PROJECT_ROOT=$(pwd)
  10. fi
  11. echo "-=[FlaskCreate]=-";
  12. echo "Project Name: $PROJECT_NAME";
  13. echo "Project Root: $PROJECT_ROOT/$PROJECT_NAME";
  14. echo "Start a new Flask project? (y/n)";
  15. read START_CONFIRM;
  16. if [[ $START_CONFIRM != y && $START_CONFIRM != Y ]]; then
  17. exit;
  18. fi
  19. PROJECT_FOLDER=$PROJECT_ROOT/$PROJECT_NAME
  20. echo "";
  21. echo "[FlaskCreate] Creating directory $PROJECT_FOLDER...";
  22. mkdir $PROJECT_FOLDER;
  23. mkdir $PROJECT_FOLDER/data;
  24. mkdir $PROJECT_FOLDER/$PROJECT_NAME;
  25. touch $PROJECT_FOLDER/uwsgi.ini;
  26. echo "[FlaskCreate] Generating uwsgi config...";
  27. echo "[uwsgi]
  28. module = wsgi:application
  29. master = true
  30. processes = 4
  31. socket = $PROJECT_NAME.sock
  32. chmod-scoket = 660
  33. vacuum = true
  34. die-on-term = true
  35. " > $PROJECT_FOLDER/uwsgi.ini;
  36. touch $PROJECT_FOLDER/start.py;
  37. echo "from $PROJECT_NAME import create_app
  38. app = create_app()
  39. if __name__ == \"__main__\":
  40. app.run()
  41. " > $PROJECT_FOLDER/start.py;
  42. echo "[FlaskCreate] Creating Flask app module files...";
  43. touch $PROJECT_FOLDER/$PROJECT_NAME/__init__.py;
  44. echo "from flask import Flask
  45. def create_app():
  46. app = Flask(__name__)
  47. app.config.from_object('$PROJECT_NAME.default_settings')
  48. app.config.from_envvar('FLASK_SETTINGS_FILE')
  49. # Prep the database
  50. from $PROJECT_NAME.models import db
  51. app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///../data/$PROJECT_NAME.db'
  52. app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
  53. db.init_app(app)
  54. # Load our views
  55. from $PROJECT_NAME.views import default_views
  56. app.register_blueprint(default_views)
  57. # from $PROJECT_NAME.<app_name>.views import app_views
  58. # app.register_blueprint(app_views)
  59. # Load our CLI commands
  60. from $PROJECT_NAME.commands import default_cli
  61. app.cli.add_command(default_cli)
  62. # from $PROJECT_NAME.<app_name>.commands import app_cli
  63. # app.cli.add_command(app_cli)
  64. return app
  65. " > $PROJECT_FOLDER/$PROJECT_NAME/__init__.py;
  66. echo "[FlaskCreate] Generating SQLAlchemy base model...";
  67. touch $PROJECT_FOLDER/$PROJECT_NAME/models.py;
  68. echo "from flask_sqlalchemy import SQLAlchemy
  69. db = SQLAlchemy()
  70. class BaseModel(db.Model):
  71. __abstract__ = True
  72. id = db.Column(db.Integer, primary_key=True)
  73. created_at = db.Column(db.DateTime)
  74. " > $PROJECT_FOLDER/$PROJECT_NAME/models.py;
  75. echo "[FlaskCreate] Generating basic CLI commands...";
  76. touch $PROJECT_FOLDER/$PROJECT_NAME/commands.py;
  77. echo "import click
  78. from flask.cli import AppGroup
  79. from $PROJECT_NAME.models import db
  80. default_cli = AppGroup('$PROJECT_NAME')
  81. @default_cli.command('initdb')
  82. def initialize_database():
  83. from $PROJECT_NAME import models
  84. # from $PROJECT_NAME.<app_name> import models
  85. db.create_all()
  86. " > $PROJECT_FOLDER/$PROJECT_NAME/commands.py;
  87. echo "[FlaskCreate] Generating default views...";
  88. touch $PROJECT_FOLDER/$PROJECT_NAME/views.py;
  89. echo "from flask import current_app, Blueprint, render_template
  90. default_views = Blueprint('default_views', __name__, url_prefix='/')
  91. @default_views.route('/')
  92. def index():
  93. return render_template('index.html')
  94. " > $PROJECT_FOLDER/$PROJECT_NAME/views.py;
  95. echo "[FlaskCreate] Initializing default templates...";
  96. TEMPLATE_DIR=$PROJECT_FOLDER/$PROJECT_NAME/templates
  97. mkdir $TEMPLATE_DIR;
  98. touch $TEMPLATE_DIR/base.html;
  99. touch $TEMPLATE_DIR/index.html;
  100. echo " <!doctype html>
  101. <html>
  102. <head>
  103. <title>{% block title %}{% endblock %} - $PROJECT_NAME</title>
  104. <meta charset=\"utf-8\">
  105. <meta name=\"viewport\" contents=\"width=device-width, initial-scale=1\">
  106. <link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/uikit/3.2.0/css/uikit.min.css\" integrity=\"sha256-5YtK9j+Nl/245lAkSjrIs600d6edKTevi+3JYdjuHhY=\" crossorigin=\"anonymous\" />
  107. <script src=\"https://cdnjs.cloudflare.com/ajax/libs/uikit/3.2.0/js/uikit.min.js\" integrity=\"sha256-rhLALrRmAQVu/OxzVDpQaiHAEMxiRSN8h8RDydUEh2g=\" crossorigin=\"anonymous\"></script>
  108. {% block head %} {% endblock %}
  109. </head>
  110. <body>
  111. <nav class=\"uk-navbar-container\" uk-navbar>
  112. <div class=\"uk-navbar-left\">
  113. <a href=\"\" class=\"uk-navbar-item uk-logo\">$PROJECT_NAME</a>
  114. </div>
  115. <div class=\"uk-navbar-center\">
  116. <ul class=\"uk-navbar-nav\">
  117. <li class=\"uk-active\"><a href=\"\">Nav Item 1</a></li>
  118. <li><a href=\"\">Nav Item 2</a></li>
  119. <li><a href=\"\">Nav Item 3</a></li>
  120. <li><a href=\"\">Nav Item 4</a></li>
  121. </ul>
  122. </div>
  123. </nav>
  124. <div class=\"uk-container\">
  125. {% block content %}{% endblock %}
  126. </div>
  127. </body>
  128. </html>
  129. " > $TEMPLATE_DIR/base.html;
  130. echo "{% extends \"base.html\" %}
  131. {% block title %}$PROJECT_NAME Home{% endblock %}
  132. {% block content %}
  133. <div>
  134. </div>
  135. {% endblock %}
  136. {% block head %}
  137. <style>
  138. </style>
  139. {% endblock %}
  140. " > $TEMPLATE_DIR/index.html;
  141. echo "[FlaskCreate] Creating default_settings config file...";
  142. touch $PROJECT_FOLDER/$PROJECT_NAME/default_settings.py;
  143. echo "# Default Configuration
  144. SECRET_KEY = 'asecretkeyshouldchange'
  145. # Flask-SQLAlchemy
  146. SQLALCHEMY_TRACK_MODIFICATIONS = False
  147. " > $PROJECT_FOLDER/$PROJECT_NAME/default_settings.py;
  148. echo "[FlaskCreate] Creating environment config files...";
  149. mkdir $PROJECT_FOLDER/config;
  150. touch $PROJECT_FOLDER/config/prod.cfg; touch $PROJECT_FOLDER/config/dev.cfg
  151. PROD_KEY=$(echo $(od -vN 20 -An -tx1 /dev/urandom | tr -d " \n"))
  152. DEV_KEY=$(echo $(od -vN 20 -An -tx1 /dev/urandom | tr -d " \n"))
  153. echo "# Default Configuration
  154. DEBUG = True
  155. SECRET_KEY = \"$DEV_KEY\"
  156. # Flask-SQLAlchemy
  157. SQLALCHEMY_DATABASE_URI = 'sqlite:///../data/acks.db'
  158. SQLALCHEMY_TRACK_MODIFICATIONS = False
  159. " > $PROJECT_FOLDER/config/dev.cfg
  160. echo "# Default Configuration
  161. DEBUG = False
  162. SECRET_KEY = \"$PROD_KEY\"
  163. # Flask-SQLAlchemy
  164. SQLALCHEMY_DATABASE_URI = 'sqlite:///../data/acks.db'
  165. SQLALCHEMY_TRACK_MODIFICATIONS = False
  166. " > $PROJECT_FOLDER/config/prod.cfg
  167. echo "[FlaskCreate] Generating a Makefile...";
  168. touch $PROJECT_FOLDER/Makefile;
  169. echo -e ".PHONY: run debug clean
  170. bin/activate: requirements.txt
  171. \t test -f bin/activate || $(which python3) -m venv .
  172. \t bin/pip install -Ur requirements.txt
  173. \t touch bin/activate
  174. run: bin/activate
  175. \t . bin/activate; FLASK_SETTINGS_FILE=../config/prod.cfg FLASK_ENV=production FLASK_APP=start.py flask run --host=0.0.0.0
  176. debug: bin/activate
  177. \t . bin/activate; FLASK_SETTINGS_FILE=../config/dev.cfg FLASK_ENV=development FLASK_APP=start.py flask run --host=0.0.0.0
  178. clean:
  179. \t rm -rf bin/ include/ lib/ lib64/ __pycache__/ share/; rm pyvenv.cfg
  180. " > $PROJECT_FOLDER/Makefile
  181. echo "[FlaskCreate] Initializing a git repository and creating initial commit...";
  182. cd $PROJECT_FOLDER;
  183. touch $PROJECT_FOLDER/.gitignore
  184. echo "# Python
  185. *.py[co]
  186. # Vim
  187. *.swp
  188. # Virtualenv
  189. bin
  190. include
  191. lib
  192. lib64
  193. __pycache__
  194. share
  195. pyvenv.cfg
  196. # App specific
  197. data
  198. config
  199. " > $PROJECT_FOLDER/.gitignore
  200. git init $PROJECT_FOLDER &> /dev/null;
  201. git add . &> /dev/null;
  202. git commit -m "Initial commit (FlaskCreate)" &> /dev/null;
  203. echo "[FlaskCreate] Creating Python3 virtual environment...";
  204. python3 -m venv $PROJECT_FOLDER
  205. source $PROJECT_FOLDER/bin/activate
  206. echo "[FlaskCreate] Installing dependencies...";
  207. pip install flask flask-sqlalchemy &> /dev/null
  208. pip freeze > $PROJECT_FOLDER/requirements.txt;
  209. echo "[FlaskCreate] Finished. Project lives at $PROJECT_FOLDER."
  210. cd $PROJECT_FOLDER;