├── .github └── workflows │ └── codeql-analysis.yml ├── .gitignore ├── Dockerfile ├── LICENSE ├── README.md ├── app.py ├── check_format.py ├── format.py ├── keep_alive.py ├── requirements.txt ├── static └── main.css └── templates ├── 404.html ├── 500.html └── calculator.html /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | name: CodeQL 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | pull_request: 7 | branches: [main] 8 | schedule: 9 | - cron: "31 14 * * 1" 10 | 11 | jobs: 12 | analyze: 13 | name: Analyze 14 | runs-on: ubuntu-latest 15 | permissions: 16 | actions: read 17 | contents: read 18 | security-events: write 19 | 20 | strategy: 21 | fail-fast: false 22 | matrix: 23 | language: ["python"] 24 | 25 | steps: 26 | - name: Checkout repository 27 | uses: actions/checkout@v2 28 | 29 | - name: Initialize CodeQL 30 | uses: github/codeql-action/init@v1 31 | with: 32 | languages: ${{ matrix.language }} 33 | 34 | - name: Autobuild 35 | uses: github/codeql-action/autobuild@v1 36 | 37 | - name: Perform CodeQL Analysis 38 | uses: github/codeql-action/analyze@v1 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyo 2 | *.pyc 3 | *cfg 4 | **/env/ 5 | **/__pycache__/ 6 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.10 2 | WORKDIR /opt/app 3 | COPY . /opt/app 4 | RUN pip install -r requirements.txt 5 | EXPOSE 3000 6 | CMD ["python3", "app.py"] -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Eliaz Bobadilla 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Flask WebApp Calc 2 | 3 | [](https://github.com/UltiRequiem/flask-calculator/blob/main/LICENSE) 4 | [](https://github.com/psf/black) 5 | [](https://github.com/UltiRequiem/flask-calculator) 6 |  7 |  8 | 9 | A simple calculator made with Flask. 10 | 11 | [](https://flask-calculator.ultirequiem.repl.co) 12 | 13 | ## Demo 14 | 15 | Here is a working live demo: https://flask-calculator.ultirequiem.repl.co 16 | it runs in [Repl.it](https://repl.it). 17 | 18 | ## Development setup 19 | 20 | 1. Clone the proyect 21 | 22 | ```bash 23 | git clone https://github.com/UltiRequiem/flask-calculator.git ; cd flask-calculator 24 | ``` 25 | 26 | 2. Create a virtual environment 27 | 28 | ```bash 29 | python3 -m venv env;source env/bin/activate 30 | ``` 31 | 32 | 3. Install the dependencies 33 | 34 | ```bash 35 | pip install -r requirements.txt 36 | ``` 37 | 38 | ## License 39 | 40 | This project is licensed under the [MIT](./LICENSE) License. 41 | -------------------------------------------------------------------------------- /app.py: -------------------------------------------------------------------------------- 1 | from flask import render_template, request 2 | from keep_alive import keep_alive, app 3 | 4 | 5 | @app.route("/") 6 | def main(): 7 | return render_template("calculator.html") 8 | 9 | 10 | @app.route("/calculate", methods=["POST"]) 11 | def calculate(): 12 | number_one = request.form["number_one"] 13 | number_two = request.form["number_two"] 14 | operation = request.form["operation"] 15 | 16 | if operation == "add": 17 | result = float(number_one) + float(number_two) 18 | return render_template("calculator.html", result=result) 19 | 20 | elif operation == "subtract": 21 | result = float(number_one) - float(number_two) 22 | return render_template("calculator.html", result=result) 23 | 24 | elif operation == "multiply": 25 | result = float(number_one) * float(number_two) 26 | return render_template("calculator.html", result=result) 27 | 28 | elif operation == "divide": 29 | result = float(number_one) / float(number_two) 30 | return render_template("calculator.html", result=result) 31 | 32 | else: 33 | return render_template("calculator.html") 34 | 35 | 36 | @app.errorhandler(404) 37 | def not_found(error): 38 | return render_template("404.html", error=error) 39 | 40 | 41 | @app.errorhandler(500) 42 | def server_error(error): 43 | return render_template("500.html", error=error) 44 | 45 | 46 | if __name__ == "__main__": 47 | keep_alive() 48 | -------------------------------------------------------------------------------- /check_format.py: -------------------------------------------------------------------------------- 1 | from os import system 2 | 3 | files = ["app.py", "keep_alive.py"] 4 | 5 | 6 | def check_format(): 7 | for i in files: 8 | system(f"pycodestyle --show-source --show-pep8 --format=default {i}") 9 | 10 | 11 | if __name__ == "__main__": 12 | check_format() 13 | print("All done!") 14 | -------------------------------------------------------------------------------- /format.py: -------------------------------------------------------------------------------- 1 | from os import system 2 | 3 | files = ["app.py", "keep_alive.py"] 4 | 5 | 6 | def format(): 7 | for i in files: 8 | system(f"autopep8 --in-place --aggressive {i}") 9 | 10 | 11 | if __name__ == "__main__": 12 | format() 13 | print("All done!") 14 | -------------------------------------------------------------------------------- /keep_alive.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | from threading import Thread 3 | 4 | app = Flask("") 5 | 6 | 7 | def run(): 8 | app.run(host="0.0.0.0", port=3000) 9 | 10 | 11 | def keep_alive(): 12 | t = Thread(target=run) 13 | t.start() 14 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | click==7.1.2 2 | Flask==2.3.2 3 | itsdangerous==1.1.0 4 | Jinja2==3.1.6 5 | MarkupSafe==1.1.1 6 | Werkzeug==2.2.3 7 | -------------------------------------------------------------------------------- /static/main.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css?family=Montserrat:400,600,700,900"); 2 | 3 | body { 4 | width: 100%; 5 | height: 750px; 6 | display: flex; 7 | flex-direction: column; 8 | justify-content: center; 9 | align-items: center; 10 | font-family: "Montserrat", sans-serif; 11 | background-color: #ebedef; 12 | padding: 0; 13 | margin: 0; 14 | } 15 | -------------------------------------------------------------------------------- /templates/404.html: -------------------------------------------------------------------------------- 1 |
{{ error }}
4 |{{ error }}
4 |