├── static ├── styles.css ├── index.html └── app.js ├── requirements.txt ├── README.md ├── server.py ├── LICENSE └── .gitignore /static/styles.css: -------------------------------------------------------------------------------- 1 | .done-true { 2 | text-decoration: line-through; 3 | color: grey; 4 | } -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | click==6.7 2 | Flask==0.12.2 3 | itsdangerous==0.24 4 | Jinja2==2.10 5 | MarkupSafe==1.0 6 | Werkzeug==0.14.1 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # angularjs-flask 2 | 3 | --- 4 | 5 | > :warning: Warning! [AngularJS](https://angularjs.org) is considered outdated nowadays - Feel free to still use this boilerplate, although I recommend using [Angular](https://angular.io/) (2+) instead 6 | 7 | --- 8 | 9 | some lovely boilerplate for an angularjs + python flask web app 10 | 11 | ## Getting Started 12 | 13 | 1. Make a new Python virtual environment using: `python -m virtualenv venv` or `python3 -m venv venv` 14 | 2. Source into the new virtual env: `source venv/bin/activate` 15 | 3. Install requirements: `pip install -r requirements.txt` 16 | 4. Run server: `python server.py` 17 | 18 | -------------------------------------------------------------------------------- /server.py: -------------------------------------------------------------------------------- 1 | from flask import Flask, send_from_directory, jsonify 2 | 3 | app = Flask(__name__, template_folder='static', static_folder='static') 4 | 5 | 6 | @app.route("/") 7 | def index(): 8 | return send_from_directory(app.static_folder, "index.html") 9 | 10 | 11 | @app.route('/static/') 12 | def get_assets(path): 13 | return send_from_directory(app.static_folder, path) 14 | 15 | 16 | @app.route("/api/example-todos", methods=['GET']) 17 | def example_todos(): 18 | return jsonify([ 19 | { 20 | "text": "learn Python Flask", 21 | "done": False 22 | }, 23 | { 24 | "text": "build a Python Flask app", 25 | "done": False 26 | } 27 | ]) 28 | 29 | 30 | if __name__ == '__main__': 31 | app.config.update( 32 | DEBUG=True, 33 | TEMPLATES_AUTO_RELOAD=True 34 | ) 35 | app.run() 36 | -------------------------------------------------------------------------------- /static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |

Todo

13 |
14 | {{remaining()}} of {{todos.length}} remaining 15 | archive ] 16 | 24 |
25 | 26 | 27 |
28 |
29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 James Vickery 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /static/app.js: -------------------------------------------------------------------------------- 1 | var app = angular.module('todoApp', []); 2 | 3 | app.controller('TodoListController', function ($scope, $http) { 4 | 5 | $scope.todos = [{ 6 | text: 'learn AngularJS', 7 | done: true 8 | }, 9 | { 10 | text: 'build an AngularJS app', 11 | done: false 12 | } 13 | ]; 14 | 15 | $http({ 16 | method: 'GET', 17 | url: '/api/example-todos' 18 | }).then(function successCallback(response) { 19 | $scope.todos = $scope.todos.concat(response.data); 20 | }, 21 | function errorCallback(response) { 22 | console.log("Error loading example todos"); 23 | }); 24 | 25 | 26 | $scope.addTodo = function () { 27 | $scope.todos.push({ 28 | text: $scope.todoText, 29 | done: false 30 | }); 31 | $scope.todoText = ''; 32 | }; 33 | 34 | $scope.remaining = function () { 35 | var count = 0; 36 | angular.forEach($scope.todos, function (todo) { 37 | count += todo.done ? 0 : 1; 38 | }); 39 | return count; 40 | }; 41 | 42 | $scope.archive = function () { 43 | var oldTodos = $scope.todos; 44 | $scope.todos = []; 45 | angular.forEach(oldTodos, function (todo) { 46 | if (!todo.done) $scope.todos.push(todo); 47 | }); 48 | }; 49 | }); -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # JetBrains 2 | .idea/ 3 | 4 | # Byte-compiled / optimized / DLL files 5 | __pycache__/ 6 | *.py[cod] 7 | *$py.class 8 | 9 | # C extensions 10 | *.so 11 | 12 | # Distribution / packaging 13 | .Python 14 | env/ 15 | build/ 16 | develop-eggs/ 17 | dist/ 18 | downloads/ 19 | eggs/ 20 | .eggs/ 21 | lib/ 22 | lib64/ 23 | parts/ 24 | sdist/ 25 | var/ 26 | wheels/ 27 | *.egg-info/ 28 | .installed.cfg 29 | *.egg 30 | 31 | # PyInstaller 32 | # Usually these files are written by a python script from a template 33 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 34 | *.manifest 35 | *.spec 36 | 37 | # Installer logs 38 | pip-log.txt 39 | pip-delete-this-directory.txt 40 | 41 | # Unit test / coverage reports 42 | htmlcov/ 43 | .tox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | .hypothesis/ 51 | 52 | # Translations 53 | *.mo 54 | *.pot 55 | 56 | # Django stuff: 57 | *.log 58 | local_settings.py 59 | 60 | # Flask stuff: 61 | instance/ 62 | .webassets-cache 63 | 64 | # Scrapy stuff: 65 | .scrapy 66 | 67 | # Sphinx documentation 68 | docs/_build/ 69 | 70 | # PyBuilder 71 | target/ 72 | 73 | # Jupyter Notebook 74 | .ipynb_checkpoints 75 | 76 | # pyenv 77 | .python-version 78 | 79 | # celery beat schedule file 80 | celerybeat-schedule 81 | 82 | # SageMath parsed files 83 | *.sage.py 84 | 85 | # dotenv 86 | .env 87 | 88 | # virtualenv 89 | .venv 90 | venv/ 91 | venv*/ 92 | ENV/ 93 | 94 | # Spyder project settings 95 | .spyderproject 96 | .spyproject 97 | 98 | # Rope project settings 99 | .ropeproject 100 | 101 | # mkdocs documentation 102 | /site 103 | 104 | # mypy 105 | .mypy_cache/ 106 | --------------------------------------------------------------------------------