From 27d829afed68173a85998eaad0f7bc3adac19dce Mon Sep 17 00:00:00 2001 From: Todd Birchard Date: Sat, 16 Dec 2023 03:04:53 -0500 Subject: [PATCH 1/2] Added gunicorn dependency; adjusted outdated styles. --- .env.example | 6 +- .github/workflows/pythonapp.yml | 12 +- .gitignore | 4 + Makefile | 15 +- README.md | 12 +- config.py | 10 +- flask_login_tutorial/__init__.py | 6 +- flask_login_tutorial/auth.py | 28 +- flask_login_tutorial/routes.py | 8 +- .../static/dist/css/account.css | 2 +- .../static/dist/img/favicon.png | Bin 5926 -> 0 bytes .../static/dist/img/favicon@2x.png | Bin 0 -> 12827 bytes flask_login_tutorial/static/dist/img/logo.png | Bin 5457 -> 0 bytes .../static/dist/img/logo@2x.png | Bin 0 -> 12827 bytes .../static/src/less/account.less | 12 +- .../static/src/less/vars.less | 2 +- .../templates/dashboard.jinja2 | 2 +- flask_login_tutorial/templates/layout.jinja2 | 2 +- flask_login_tutorial/templates/login.jinja2 | 4 +- flask_login_tutorial/templates/signup.jinja2 | 4 +- poetry.lock | 618 ++---------------- pyproject.toml | 16 +- requirements.txt | 30 +- main.py => wsgi.py | 3 - 24 files changed, 132 insertions(+), 664 deletions(-) delete mode 100644 flask_login_tutorial/static/dist/img/favicon.png create mode 100644 flask_login_tutorial/static/dist/img/favicon@2x.png delete mode 100644 flask_login_tutorial/static/dist/img/logo.png create mode 100644 flask_login_tutorial/static/dist/img/logo@2x.png rename main.py => wsgi.py (52%) diff --git a/.env.example b/.env.example index ae68a78..159567d 100644 --- a/.env.example +++ b/.env.example @@ -1,12 +1,10 @@ ENVIRONMENT=production -FLASK_APP=main.py +FLASK_APP=wsgi.py FLASK_DEBUG=False SECRET_KEY=yoursecretkey SQLALCHEMY_DATABASE_URI=mysql+pymysql://myuser:mypassword@host.example.com:1234/mydatabase LESS_BIN=/usr/local/bin/lessc -COMPRESSOR_DEBUG=False -ASSETS_DEBUG=False -LESS_RUN_IN_DEBUG=False + diff --git a/.github/workflows/pythonapp.yml b/.github/workflows/pythonapp.yml index 9172286..f79bc01 100644 --- a/.github/workflows/pythonapp.yml +++ b/.github/workflows/pythonapp.yml @@ -15,18 +15,20 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Set up Python - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: "3.10" + cache: "pip" # caching pip dependencies - name: Install dependencies run: | - python -m pip install --upgrade pip setuptools wheel - pip install -r requirements.txt + python -m pip install --upgrade pip + pip install flake8 pytest + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - name: Lint with flake8 run: | - python3 -m pip install flake8 + # stop the build if there are Python syntax errors or undefined names flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics + # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics diff --git a/.gitignore b/.gitignore index 0ea9e3a..2c20f57 100644 --- a/.gitignore +++ b/.gitignore @@ -129,3 +129,7 @@ dmypy.json # Pyre type checker .pyre/ + +# IDEs +.vscode/ +.idea/ diff --git a/Makefile b/Makefile index faa7b78..6a0741e 100644 --- a/Makefile +++ b/Makefile @@ -32,8 +32,7 @@ $(VIRTUAL_ENV): .PHONY: run run: env - export LESS_BIN=$(shell which lessc) && \ - $(LOCAL_PYTHON) -m main + $(LOCAL_PYTHON) -m gunicorn -w 4 wsgi:app .PHONY: install install: env @@ -78,11 +77,11 @@ lint: env .PHONY: clean clean: find . -name '.coverage' -delete && \ - find . -name '*.pyc' -delete \ - find . -name '__pycache__' -delete \ - find . -name 'poetry.lock' -delete \ - find . -name '*.log' -delete \ - find . -name '.DS_Store' -delete \ + find . -name '*.pyc' -delete && \ + find . -name '__pycache__' -delete && \ + find . -name 'poetry.lock' -delete && \ + find . -name '*.log' -delete && \ + find . -name '.DS_Store' -delete && \ find . -wholename '**/*.pyc' -delete && \ find . -wholename '**/*.html' -delete && \ find . -type d -wholename '__pycache__' -exec rm -rf {} + && \ @@ -91,4 +90,4 @@ clean: find . -type d -wholename '**/.pytest_cache' -exec rm -rf {} + && \ find . -type d -wholename '**/*.log' -exec rm -rf {} + && \ find . -type d -wholename './.reports/*' -exec rm -rf {} + && \ - find . -type d -wholename '**/.webassets-cache' -exec rm -rf {} + find . -type d -wholename '**/.webassets-cache' -exec rm -rf {} + diff --git a/README.md b/README.md index d66bfdf..5e6a9e0 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Flask-Login Tutorial -![Python](https://img.shields.io/badge/Python-v^3.10-blue.svg?logo=python&longCache=true&logoColor=white&colorB=5e81ac&style=flat-square&colorA=4c566a) +![Python](https://img.shields.io/badge/Python-v3.10-blue.svg?logo=python&longCache=true&logoColor=white&colorB=5e81ac&style=flat-square&colorA=4c566a) ![Flask](https://img.shields.io/badge/Flask-v3.0.0-blue.svg?longCache=true&logo=flask&style=flat-square&logoColor=white&colorB=5e81ac&colorA=4c566a) ![Flask-Login](https://img.shields.io/badge/Flask--Login-v0.6.3-blue.svg?longCache=true&logo=flask&style=flat-square&logoColor=white&colorB=5e81ac&colorA=4c566a) ![Flask-Assets](https://img.shields.io/badge/Flask--Assets-v2.1.0-blue.svg?longCache=true&logo=flask&style=flat-square&logoColor=white&colorB=5e81ac&colorA=4c566a) @@ -22,23 +22,19 @@ Add user authentication to your Flask app. Get set up locally in two steps: -### I. Environment Variables +### Environment Variables Replace the values in **.env.example** with your values and rename this file to **.env**: -* `FLASK_APP`: Entry point of your application (should be `main.py`). -* `FLASK_DEBUG`: Whether to enable "DEBUG" logging (either `True` or `False`). * `ENVIRONMENT`: The environment to run your app in (either `development` or `production`). +* `FLASK_DEBUG`: Whether to enable "DEBUG" logging (either `True` or `False`). * `SECRET_KEY`: Randomly generated string of characters used to encrypt your app's data. * `SQLALCHEMY_DATABASE_URI`: Connection URI of a SQL database. * `LESS_BIN`: Path to your local LESS installation via `which lessc` (optional for static assets). -* `ASSETS_DEBUG`: Debug asset creation and bundling in `development` (optional). -* `LESS_RUN_IN_DEBUG`: Debug LESS while in `development` (optional). -* `COMPRESSOR_DEBUG`: Debug asset compression while in `development` (optional). *Remember never to commit secrets saved in .env files to Github.* -### II. Installation +### Installation Get up and running with `make deploy`: diff --git a/config.py b/config.py index 01da1e3..baab555 100644 --- a/config.py +++ b/config.py @@ -12,7 +12,9 @@ class Config: # General Config ENVIRONMENT = environ.get("ENVIRONMENT") - FLASK_APP = environ.get("FLASK_APP") + + # Flask Config + FLASK_APP = "wsgi.py" FLASK_DEBUG = environ.get("FLASK_DEBUG") SECRET_KEY = environ.get("SECRET_KEY") @@ -23,10 +25,10 @@ class Config: # Flask-Assets LESS_BIN = environ.get("LESS_BIN") - ASSETS_DEBUG = environ.get("ASSETS_DEBUG") - LESS_RUN_IN_DEBUG = environ.get("LESS_RUN_IN_DEBUG") + ASSETS_DEBUG = False + LESS_RUN_IN_DEBUG = False # Static Assets STATIC_FOLDER = "static" TEMPLATES_FOLDER = "templates" - COMPRESSOR_DEBUG = environ.get("COMPRESSOR_DEBUG") + COMPRESSOR_DEBUG = False diff --git a/flask_login_tutorial/__init__.py b/flask_login_tutorial/__init__.py index ff465fc..6288ce3 100644 --- a/flask_login_tutorial/__init__.py +++ b/flask_login_tutorial/__init__.py @@ -8,7 +8,7 @@ def create_app(): - """Construct the core app object.""" + """Construct application object.""" app = Flask(__name__, instance_relative_config=False) app.config.from_object("config.Config") @@ -21,8 +21,8 @@ def create_app(): from .assets import compile_static_assets # Register Blueprints - app.register_blueprint(routes.main_bp) - app.register_blueprint(auth.auth_bp) + app.register_blueprint(routes.main_blueprint) + app.register_blueprint(auth.auth_blueprint) # Create Database Models db.create_all() diff --git a/flask_login_tutorial/auth.py b/flask_login_tutorial/auth.py index cad2a8d..e3840f3 100644 --- a/flask_login_tutorial/auth.py +++ b/flask_login_tutorial/auth.py @@ -1,4 +1,6 @@ """Routes for user authentication.""" +from typing import Optional + from flask import Blueprint, flash, redirect, render_template, request, url_for from flask_login import current_user, login_user @@ -7,10 +9,10 @@ from .models import User, db # Blueprint Configuration -auth_bp = Blueprint("auth_bp", __name__, template_folder="templates", static_folder="static") +auth_blueprint = Blueprint("auth_blueprint", __name__, template_folder="templates", static_folder="static") -@auth_bp.route("/signup", methods=["GET", "POST"]) +@auth_blueprint.route("/signup", methods=["GET", "POST"]) def signup(): """ User sign-up page. @@ -27,7 +29,7 @@ def signup(): db.session.add(user) db.session.commit() # Create new user login_user(user) # Log in as newly created user - return redirect(url_for("main_bp.dashboard")) + return redirect(url_for("main_blueprint.dashboard")) flash("A user already exists with that email address.") return render_template( "signup.jinja2", @@ -38,7 +40,7 @@ def signup(): ) -@auth_bp.route("/login", methods=["GET", "POST"]) +@auth_blueprint.route("/login", methods=["GET", "POST"]) def login(): """ Log-in page for registered users. @@ -48,7 +50,7 @@ def login(): """ # Bypass if user is logged in if current_user.is_authenticated: - return redirect(url_for("main_bp.dashboard")) + return redirect(url_for("main_blueprint.dashboard")) form = LoginForm() # Validate login attempt if form.validate_on_submit(): @@ -56,9 +58,9 @@ def login(): if user and user.check_password(password=form.password.data): login_user(user) next_page = request.args.get("next") - return redirect(next_page or url_for("main_bp.dashboard")) + return redirect(next_page or url_for("main_blueprint.dashboard")) flash("Invalid username/password combination") - return redirect(url_for("auth_bp.login")) + return redirect(url_for("auth_blueprint.login")) return render_template( "login.jinja2", form=form, @@ -69,8 +71,14 @@ def login(): @login_manager.user_loader -def load_user(user_id): - """Check if user is logged-in upon page load.""" +def load_user(user_id: int) -> Optional[User]: + """ + Check if user is logged-in upon page load. + + :param int user_id: User ID from session cookie. + + :returns: bool + """ if user_id is not None: return User.query.get(user_id) return None @@ -80,4 +88,4 @@ def load_user(user_id): def unauthorized(): """Redirect unauthorized users to Login page.""" flash("You must be logged in to view that page.") - return redirect(url_for("auth_bp.login")) + return redirect(url_for("auth_blueprint.login")) diff --git a/flask_login_tutorial/routes.py b/flask_login_tutorial/routes.py index 1f6d3b8..b1df297 100644 --- a/flask_login_tutorial/routes.py +++ b/flask_login_tutorial/routes.py @@ -3,10 +3,10 @@ from flask_login import current_user, login_required, logout_user # Blueprint Configuration -main_bp = Blueprint("main_bp", __name__, template_folder="templates", static_folder="static") +main_blueprint = Blueprint("main_blueprint", __name__, template_folder="templates", static_folder="static") -@main_bp.route("/", methods=["GET"]) +@main_blueprint.route("/", methods=["GET"]) @login_required def dashboard(): """Logged-in User Dashboard.""" @@ -19,9 +19,9 @@ def dashboard(): ) -@main_bp.route("/logout") +@main_blueprint.route("/logout") @login_required def logout(): """User log-out logic.""" logout_user() - return redirect(url_for("auth_bp.login")) + return redirect(url_for("auth_blueprint.login")) diff --git a/flask_login_tutorial/static/dist/css/account.css b/flask_login_tutorial/static/dist/css/account.css index bb26463..5710675 100644 --- a/flask_login_tutorial/static/dist/css/account.css +++ b/flask_login_tutorial/static/dist/css/account.css @@ -1 +1 @@ -.signup-page,.login-page{background:#e1eaf5}.signup-page .form-wrapper,.login-page .form-wrapper{background:white;width:370px;max-width:470px;margin:80px auto 0;box-shadow:0 0 5px rgba(65,67,144,0.15);padding:50px}@media(max-width:600px){.signup-page .form-wrapper,.login-page .form-wrapper{width:100%;margin:15px auto;padding:30px}}.signup-page .form-wrapper .logo,.login-page .form-wrapper .logo{text-align:center;margin:0 auto 20px}.signup-page .form-wrapper .logo img,.login-page .form-wrapper .logo img{width:30px;margin:auto}@media(max-width:600px){.signup-page .form-wrapper .logo img,.login-page .form-wrapper .logo img{width:25px}}.signup-page .form-wrapper .alert-warning,.login-page .form-wrapper .alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba;font-weight:300;font-size:.8em;margin:30px 0;display:flex;align-items:center;justify-content:space-between}@media(max-width:600px){.signup-page .form-wrapper .alert-warning,.login-page .form-wrapper .alert-warning{padding:10px 15px}}.signup-page .form-wrapper .alert-warning .close,.login-page .form-wrapper .alert-warning .close{color:#856404;font-weight:300;order:1;outline:none!important;transition:all .3s ease-out}.signup-page .form-wrapper .alert,.login-page .form-wrapper .alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem;font-family:'Poppins',sans-serif}.signup-page .form-wrapper .alert button.close,.login-page .form-wrapper .alert button.close{padding:0;background-color:transparent;border:0;-webkit-appearance:none;float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.4}.signup-page .form-wrapper .alert button.close:hover,.login-page .form-wrapper .alert button.close:hover{cursor:pointer}.signup-page .form-wrapper h1,.login-page .form-wrapper h1{font-size:1.5rem;color:#5f6988;font-weight:300;border-bottom:1px solid #dee2ef;padding-bottom:5px;margin-bottom:20px;font-family:'Poppins',sans-serif}@media(max-width:600px){.signup-page .form-wrapper h1,.login-page .form-wrapper h1{font-size:1.3rem}}.signup-page .form-wrapper input,.login-page .form-wrapper input{padding:10px 13px;margin-bottom:15px;width:-webkit-fill-available;width:-moz-available;border-radius:2px;border:1px solid #d4d9e3;font-weight:200;color:#4d5060;font-family:'Poppins',sans-serif;transition:all .3s ease-out;font-size:.9em;outline-color:transparent;outline-style:none}@media(max-width:600px){.signup-page .form-wrapper input,.login-page .form-wrapper input{font-size:.9em}}.signup-page .form-wrapper input::placeholder,.login-page .form-wrapper input::placeholder{color:#d4d9e3}.signup-page .form-wrapper input:hover,.login-page .form-wrapper input:hover{border-color:#5eb9d7;background:#d9f6ff}.signup-page .form-wrapper input:hover::placeholder,.login-page .form-wrapper input:hover::placeholder{color:#5eb9d7}.signup-page .form-wrapper input:focus,.login-page .form-wrapper input:focus{background:white;border-color:#5eb9d7;box-shadow:unset}.signup-page .form-wrapper input:focus::placeholder,.login-page .form-wrapper input:focus::placeholder{color:#d4d9e3}.signup-page .form-wrapper fieldset,.login-page .form-wrapper fieldset{border:none;padding:0;margin:0}.signup-page .form-wrapper label,.login-page .form-wrapper label{font-size:.9em;color:#5f6988;margin-bottom:5px;display:block;font-weight:300;font-family:'Poppins',sans-serif}.signup-page .form-wrapper input[type="submit"],.login-page .form-wrapper input[type="submit"]{background:#5eb9d7;color:white;border-radius:2px;margin-top:15px;font-weight:400;border:1px solid #5eb9d7;transition:all .3s ease-out}.signup-page .form-wrapper input[type="submit"]:hover,.login-page .form-wrapper input[type="submit"]:hover{cursor:pointer;background:white;color:#5eb9d7}.signup-page .form-wrapper .errors,.login-page .form-wrapper .errors{margin-top:-11px;margin-bottom:1rem;list-style:none;padding:0;font-size:.9em;color:#b75353}.signup-page .login-signup,.login-page .login-signup{text-align:center;font-weight:300;font-size:.8em;font-family:'Poppins',sans-serif;margin-top:20px}.signup-page .login-signup a,.login-page .login-signup a{color:#5eb9d7;font-weight:500} \ No newline at end of file +.signup-page,.login-page{background:#e1eaf5}@media(max-width:600px){.signup-page,.login-page{width:100%;margin:0}}.signup-page .form-wrapper,.login-page .form-wrapper{background:white;width:370px;max-width:470px;margin:80px auto 0;box-shadow:0 0 5px rgba(65,67,144,0.15);padding:50px}@media(max-width:600px){.signup-page .form-wrapper,.login-page .form-wrapper{width:auto;margin:0;padding:30px}}.signup-page .form-wrapper .logo,.login-page .form-wrapper .logo{text-align:center;margin:0 auto 20px}.signup-page .form-wrapper .logo img,.login-page .form-wrapper .logo img{width:50px;margin:auto}@media(max-width:600px){.signup-page .form-wrapper .logo img,.login-page .form-wrapper .logo img{width:40px}}.signup-page .form-wrapper .alert-warning,.login-page .form-wrapper .alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba;font-weight:300;font-size:.8em;margin:30px 0;display:flex;align-items:center;justify-content:space-between}@media(max-width:600px){.signup-page .form-wrapper .alert-warning,.login-page .form-wrapper .alert-warning{padding:10px 15px}}.signup-page .form-wrapper .alert-warning .close,.login-page .form-wrapper .alert-warning .close{color:#856404;font-weight:300;order:1;outline:none!important;transition:all .3s ease-out}.signup-page .form-wrapper .alert,.login-page .form-wrapper .alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem;font-family:'Poppins',sans-serif}.signup-page .form-wrapper .alert button.close,.login-page .form-wrapper .alert button.close{padding:0;background-color:transparent;border:0;-webkit-appearance:none;float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.4}.signup-page .form-wrapper .alert button.close:hover,.login-page .form-wrapper .alert button.close:hover{cursor:pointer}.signup-page .form-wrapper h1,.login-page .form-wrapper h1{font-size:1.5rem;color:#5f6988;font-weight:300;border-bottom:1px solid #dee2ef;padding-bottom:5px;margin-bottom:20px;font-family:'Poppins',sans-serif}@media(max-width:600px){.signup-page .form-wrapper h1,.login-page .form-wrapper h1{font-size:1.3rem}}.signup-page .form-wrapper input,.login-page .form-wrapper input{padding:10px 13px;margin-bottom:15px;width:-webkit-fill-available;width:-moz-available;border-radius:2px;border:1px solid #d4d9e3;font-weight:200;color:#4d5060;font-family:'Poppins',sans-serif;transition:all .3s ease-out;font-size:.9em;outline-color:transparent;outline-style:none}@media(max-width:600px){.signup-page .form-wrapper input,.login-page .form-wrapper input{font-size:.9em}}.signup-page .form-wrapper input::placeholder,.login-page .form-wrapper input::placeholder{color:#828895}.signup-page .form-wrapper input:hover,.login-page .form-wrapper input:hover{border-color:#0297f6;background:#d9f6ff}.signup-page .form-wrapper input:hover::placeholder,.login-page .form-wrapper input:hover::placeholder{color:#0297f6}.signup-page .form-wrapper input:focus,.login-page .form-wrapper input:focus{background:white;border-color:#0297f6;box-shadow:unset}.signup-page .form-wrapper input:focus::placeholder,.login-page .form-wrapper input:focus::placeholder{color:#d4d9e3}.signup-page .form-wrapper fieldset,.login-page .form-wrapper fieldset{border:none;padding:0;margin:0}.signup-page .form-wrapper label,.login-page .form-wrapper label{font-size:.9em;color:#5f6988;margin-bottom:5px;display:block;font-weight:300;font-family:'Poppins',sans-serif}.signup-page .form-wrapper input[type="submit"],.login-page .form-wrapper input[type="submit"]{background:#0297f6;color:white;border-radius:2px;margin-top:15px;font-weight:400;border:1px solid #0297f6;transition:all .3s ease-out}.signup-page .form-wrapper input[type="submit"]:hover,.login-page .form-wrapper input[type="submit"]:hover{cursor:pointer;background:white;color:#0297f6}.signup-page .form-wrapper .errors,.login-page .form-wrapper .errors{margin-top:-11px;margin-bottom:1rem;list-style:none;padding:0;font-size:.9em;color:#b75353}.signup-page .login-signup,.login-page .login-signup{text-align:center;font-weight:300;font-size:.8em;font-family:'Poppins',sans-serif;margin-top:20px}.signup-page .login-signup a,.login-page .login-signup a{color:#0297f6;font-weight:500} \ No newline at end of file diff --git a/flask_login_tutorial/static/dist/img/favicon.png b/flask_login_tutorial/static/dist/img/favicon.png deleted file mode 100644 index 7ba45c387497cb16fd74764b97f53aa407acb6db..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5926 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 diff --git a/flask_login_tutorial/static/dist/img/favicon@2x.png b/flask_login_tutorial/static/dist/img/favicon@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..61bdc1349f9e6fcc98008cd75980fd9ca0f61d06 GIT binary patch literal 12827 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 HJMzB(cPsZJ literal 0 HcmV?d00001 diff --git a/flask_login_tutorial/static/dist/img/logo.png b/flask_login_tutorial/static/dist/img/logo.png deleted file mode 100644 index d5474a63906cb77086a5c3944cd5b23b58f99a23..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5457 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 HJMzB(cPsZJ literal 0 HcmV?d00001 diff --git a/flask_login_tutorial/static/src/less/account.less b/flask_login_tutorial/static/src/less/account.less index 70e4350..bc0573d 100644 --- a/flask_login_tutorial/static/src/less/account.less +++ b/flask_login_tutorial/static/src/less/account.less @@ -3,6 +3,10 @@ .signup-page, .login-page { background: @background-color; + @media (max-width: 600px) { + width: 100%; + margin: 0; + } .form-wrapper { background: white; @@ -13,8 +17,8 @@ padding: 50px; @media (max-width: 600px) { - width: 100%; - margin: 15px auto; + width: auto; + margin: 0; padding: 30px; } @@ -23,11 +27,11 @@ margin: 0 auto 20px; img { - width: 30px; + width: 50px; margin: auto; @media (max-width: 600px) { - width: 25px; + width: 40px; } } } diff --git a/flask_login_tutorial/static/src/less/vars.less b/flask_login_tutorial/static/src/less/vars.less index ca8914f..320e560 100644 --- a/flask_login_tutorial/static/src/less/vars.less +++ b/flask_login_tutorial/static/src/less/vars.less @@ -1,5 +1,5 @@ // Colors -@theme-color: #5eb9d7; +@theme-color: #0297f6; @background-color: #e1eaf5; @box-shadow: 0 0 5px rgba(65, 67, 144, 0.15); @header-color: #5f6988; diff --git a/flask_login_tutorial/templates/dashboard.jinja2 b/flask_login_tutorial/templates/dashboard.jinja2 index 9ec01c4..d8536f2 100644 --- a/flask_login_tutorial/templates/dashboard.jinja2 +++ b/flask_login_tutorial/templates/dashboard.jinja2 @@ -10,7 +10,7 @@ {% if current_user.is_authenticated %}

Hi {{ current_user.name }}!

- Log out + Log out {% endif %} {% endblock %} diff --git a/flask_login_tutorial/templates/layout.jinja2 b/flask_login_tutorial/templates/layout.jinja2 index 543862f..273ab0c 100644 --- a/flask_login_tutorial/templates/layout.jinja2 +++ b/flask_login_tutorial/templates/layout.jinja2 @@ -8,7 +8,7 @@ - + diff --git a/flask_login_tutorial/templates/login.jinja2 b/flask_login_tutorial/templates/login.jinja2 index aee4be7..a49461e 100644 --- a/flask_login_tutorial/templates/login.jinja2 +++ b/flask_login_tutorial/templates/login.jinja2 @@ -8,7 +8,7 @@
{% for message in get_flashed_messages() %} @@ -50,7 +50,7 @@
diff --git a/flask_login_tutorial/templates/signup.jinja2 b/flask_login_tutorial/templates/signup.jinja2 index 46768a9..8057a65 100644 --- a/flask_login_tutorial/templates/signup.jinja2 +++ b/flask_login_tutorial/templates/signup.jinja2 @@ -8,7 +8,7 @@
{% for message in get_flashed_messages() %} @@ -79,7 +79,7 @@
{% endblock %} diff --git a/poetry.lock b/poetry.lock index c17d9b5..d6583c3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,69 +1,34 @@ # This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. -[[package]] -name = "aadict" -version = "0.2.3" -description = "An auto-attribute dict (and a couple of other useful dict functions)" -optional = false -python-versions = "*" -files = [ - {file = "aadict-0.2.3.tar.gz", hash = "sha256:a77328ac55dbb5735da99441870251befe135f687ab707a7a178561363b27704"}, -] - -[package.dependencies] -six = ">=1.6.0" - -[[package]] -name = "annotated-types" -version = "0.6.0" -description = "Reusable constraint types to use with typing.Annotated" -optional = false -python-versions = ">=3.8" -files = [ - {file = "annotated_types-0.6.0-py3-none-any.whl", hash = "sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43"}, - {file = "annotated_types-0.6.0.tar.gz", hash = "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d"}, -] - -[[package]] -name = "asset" -version = "0.6.13" -description = "A package resource and symbol loading helper library." -optional = false -python-versions = "*" -files = [ - {file = "asset-0.6.13.tar.gz", hash = "sha256:ec56cbf77931cb74d063848531db782f6f0fe1272d1f47f322c15efd0fa732ea"}, -] - -[package.dependencies] -aadict = ">=0.2.2" -globre = ">=0.1.5" -six = ">=1.10.0" - [[package]] name = "black" -version = "23.11.0" +version = "23.12.0" description = "The uncompromising code formatter." optional = false python-versions = ">=3.8" files = [ - {file = "black-23.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dbea0bb8575c6b6303cc65017b46351dc5953eea5c0a59d7b7e3a2d2f433a911"}, - {file = "black-23.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:412f56bab20ac85927f3a959230331de5614aecda1ede14b373083f62ec24e6f"}, - {file = "black-23.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d136ef5b418c81660ad847efe0e55c58c8208b77a57a28a503a5f345ccf01394"}, - {file = "black-23.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:6c1cac07e64433f646a9a838cdc00c9768b3c362805afc3fce341af0e6a9ae9f"}, - {file = "black-23.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cf57719e581cfd48c4efe28543fea3d139c6b6f1238b3f0102a9c73992cbb479"}, - {file = "black-23.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:698c1e0d5c43354ec5d6f4d914d0d553a9ada56c85415700b81dc90125aac244"}, - {file = "black-23.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:760415ccc20f9e8747084169110ef75d545f3b0932ee21368f63ac0fee86b221"}, - {file = "black-23.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:58e5f4d08a205b11800332920e285bd25e1a75c54953e05502052738fe16b3b5"}, - {file = "black-23.11.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:45aa1d4675964946e53ab81aeec7a37613c1cb71647b5394779e6efb79d6d187"}, - {file = "black-23.11.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4c44b7211a3a0570cc097e81135faa5f261264f4dfaa22bd5ee2875a4e773bd6"}, - {file = "black-23.11.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a9acad1451632021ee0d146c8765782a0c3846e0e0ea46659d7c4f89d9b212b"}, - {file = "black-23.11.0-cp38-cp38-win_amd64.whl", hash = "sha256:fc7f6a44d52747e65a02558e1d807c82df1d66ffa80a601862040a43ec2e3142"}, - {file = "black-23.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7f622b6822f02bfaf2a5cd31fdb7cd86fcf33dab6ced5185c35f5db98260b055"}, - {file = "black-23.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:250d7e60f323fcfc8ea6c800d5eba12f7967400eb6c2d21ae85ad31c204fb1f4"}, - {file = "black-23.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5133f5507007ba08d8b7b263c7aa0f931af5ba88a29beacc4b2dc23fcefe9c06"}, - {file = "black-23.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:421f3e44aa67138ab1b9bfbc22ee3780b22fa5b291e4db8ab7eee95200726b07"}, - {file = "black-23.11.0-py3-none-any.whl", hash = "sha256:54caaa703227c6e0c87b76326d0862184729a69b73d3b7305b6288e1d830067e"}, - {file = "black-23.11.0.tar.gz", hash = "sha256:4c68855825ff432d197229846f971bc4d6666ce90492e5b02013bcaca4d9ab05"}, + {file = "black-23.12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:67f19562d367468ab59bd6c36a72b2c84bc2f16b59788690e02bbcb140a77175"}, + {file = "black-23.12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:bbd75d9f28a7283b7426160ca21c5bd640ca7cd8ef6630b4754b6df9e2da8462"}, + {file = "black-23.12.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:593596f699ca2dcbbbdfa59fcda7d8ad6604370c10228223cd6cf6ce1ce7ed7e"}, + {file = "black-23.12.0-cp310-cp310-win_amd64.whl", hash = "sha256:12d5f10cce8dc27202e9a252acd1c9a426c83f95496c959406c96b785a92bb7d"}, + {file = "black-23.12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e73c5e3d37e5a3513d16b33305713237a234396ae56769b839d7c40759b8a41c"}, + {file = "black-23.12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ba09cae1657c4f8a8c9ff6cfd4a6baaf915bb4ef7d03acffe6a2f6585fa1bd01"}, + {file = "black-23.12.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ace64c1a349c162d6da3cef91e3b0e78c4fc596ffde9413efa0525456148873d"}, + {file = "black-23.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:72db37a2266b16d256b3ea88b9affcdd5c41a74db551ec3dd4609a59c17d25bf"}, + {file = "black-23.12.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fdf6f23c83078a6c8da2442f4d4eeb19c28ac2a6416da7671b72f0295c4a697b"}, + {file = "black-23.12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:39dda060b9b395a6b7bf9c5db28ac87b3c3f48d4fdff470fa8a94ab8271da47e"}, + {file = "black-23.12.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7231670266ca5191a76cb838185d9be59cfa4f5dd401b7c1c70b993c58f6b1b5"}, + {file = "black-23.12.0-cp312-cp312-win_amd64.whl", hash = "sha256:193946e634e80bfb3aec41830f5d7431f8dd5b20d11d89be14b84a97c6b8bc75"}, + {file = "black-23.12.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bcf91b01ddd91a2fed9a8006d7baa94ccefe7e518556470cf40213bd3d44bbbc"}, + {file = "black-23.12.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:996650a89fe5892714ea4ea87bc45e41a59a1e01675c42c433a35b490e5aa3f0"}, + {file = "black-23.12.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bdbff34c487239a63d86db0c9385b27cdd68b1bfa4e706aa74bb94a435403672"}, + {file = "black-23.12.0-cp38-cp38-win_amd64.whl", hash = "sha256:97af22278043a6a1272daca10a6f4d36c04dfa77e61cbaaf4482e08f3640e9f0"}, + {file = "black-23.12.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ead25c273adfad1095a8ad32afdb8304933efba56e3c1d31b0fee4143a1e424a"}, + {file = "black-23.12.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c71048345bdbced456cddf1622832276d98a710196b842407840ae8055ade6ee"}, + {file = "black-23.12.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81a832b6e00eef2c13b3239d514ea3b7d5cc3eaa03d0474eedcbbda59441ba5d"}, + {file = "black-23.12.0-cp39-cp39-win_amd64.whl", hash = "sha256:6a82a711d13e61840fb11a6dfecc7287f2424f1ca34765e70c909a35ffa7fb95"}, + {file = "black-23.12.0-py3-none-any.whl", hash = "sha256:a7c07db8200b5315dc07e331dda4d889a56f6bf4db6a9c2a526fa3166a81614f"}, + {file = "black-23.12.0.tar.gz", hash = "sha256:330a327b422aca0634ecd115985c1c7fd7bdb5b5a2ef8aa9888a82e2ebe9437a"}, ] [package.dependencies] @@ -77,7 +42,7 @@ typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} [package.extras] colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.7.4)"] +d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] uvloop = ["uvloop (>=0.15.2)"] @@ -92,127 +57,6 @@ files = [ {file = "blinker-1.7.0.tar.gz", hash = "sha256:e6820ff6fa4e4d1d8e2747c2283749c3f547e4fee112b98555cdcdae32996182"}, ] -[[package]] -name = "cerberus" -version = "1.3.5" -description = "Lightweight, extensible schema and data validation tool for Pythondictionaries." -optional = false -python-versions = "*" -files = [ - {file = "Cerberus-1.3.5-py3-none-any.whl", hash = "sha256:7649a5815024d18eb7c6aa5e7a95355c649a53aacfc9b050e9d0bf6bfa2af372"}, - {file = "Cerberus-1.3.5.tar.gz", hash = "sha256:81011e10266ef71b6ec6d50e60171258a5b134d69f8fb387d16e4936d0d47642"}, -] - -[[package]] -name = "certifi" -version = "2023.11.17" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.6" -files = [ - {file = "certifi-2023.11.17-py3-none-any.whl", hash = "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474"}, - {file = "certifi-2023.11.17.tar.gz", hash = "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1"}, -] - -[[package]] -name = "charset-normalizer" -version = "3.3.2" -description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, - {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, -] - [[package]] name = "click" version = "8.1.7" @@ -248,17 +92,6 @@ files = [ {file = "cssmin-0.2.0.tar.gz", hash = "sha256:e012f0cc8401efcf2620332339011564738ae32be8c84b2e43ce8beaec1067b6"}, ] -[[package]] -name = "distlib" -version = "0.3.7" -description = "Distribution utilities" -optional = false -python-versions = "*" -files = [ - {file = "distlib-0.3.7-py2.py3-none-any.whl", hash = "sha256:2e24928bc811348f0feb63014e97aaae3037f2cf48712d51ae61df7fd6075057"}, - {file = "distlib-0.3.7.tar.gz", hash = "sha256:9dafe54b34a028eafd95039d5e5d4851a13734540f1331060d31c9916e7147a8"}, -] - [[package]] name = "dnspython" version = "2.4.2" @@ -278,16 +111,6 @@ idna = ["idna (>=2.1,<4.0)"] trio = ["trio (>=0.14,<0.23)"] wmi = ["wmi (>=1.5.1,<2.0.0)"] -[[package]] -name = "docopt" -version = "0.6.2" -description = "Pythonic argument parser, that will make you smile" -optional = false -python-versions = "*" -files = [ - {file = "docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"}, -] - [[package]] name = "email-validator" version = "2.1.0.post1" @@ -405,16 +228,6 @@ wtforms = "*" [package.extras] email = ["email-validator"] -[[package]] -name = "globre" -version = "0.1.5" -description = "A glob matching library, providing an interface similar to the \"re\" module." -optional = false -python-versions = "*" -files = [ - {file = "globre-0.1.5.tar.gz", hash = "sha256:ee214204f237e9114b8f61eeb61c2abd1e665ca3b59e5a6a0b070971c0bb12e2"}, -] - [[package]] name = "greenlet" version = "3.0.2" @@ -486,6 +299,26 @@ files = [ docs = ["Sphinx"] test = ["objgraph", "psutil"] +[[package]] +name = "gunicorn" +version = "21.2.0" +description = "WSGI HTTP Server for UNIX" +optional = false +python-versions = ">=3.5" +files = [ + {file = "gunicorn-21.2.0-py3-none-any.whl", hash = "sha256:3213aa5e8c24949e792bcacfc176fef362e7aac80b76c56f6b5122bf350722f0"}, + {file = "gunicorn-21.2.0.tar.gz", hash = "sha256:88ec8bff1d634f98e61b9f65bc4bf3cd918a90806c6f5c48bc5603849ec81033"}, +] + +[package.dependencies] +packaging = "*" + +[package.extras] +eventlet = ["eventlet (>=0.24.1)"] +gevent = ["gevent (>=1.4.0)"] +setproctitle = ["setproctitle"] +tornado = ["tornado (>=0.2)"] + [[package]] name = "idna" version = "3.6" @@ -499,23 +332,17 @@ files = [ [[package]] name = "isort" -version = "5.13.0" +version = "5.13.2" description = "A Python utility / library to sort Python imports." optional = false python-versions = ">=3.8.0" files = [ - {file = "isort-5.13.0-py3-none-any.whl", hash = "sha256:15e0e937819b350bc256a7ae13bb25f4fe4f8871a0bc335b20c3627dba33f458"}, - {file = "isort-5.13.0.tar.gz", hash = "sha256:d67f78c6a1715f224cca46b29d740037bdb6eea15323a133e897cda15876147b"}, + {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, + {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, ] -[package.dependencies] -pip-api = "*" -pipreqs = "*" -requirementslib = "*" - [package.extras] colors = ["colorama (>=0.4.6)"] -plugins = ["setuptools"] [[package]] name = "itsdangerous" @@ -555,20 +382,6 @@ files = [ {file = "jsmin-3.0.1.tar.gz", hash = "sha256:c0959a121ef94542e807a674142606f7e90214a2b3d1eb17300244bbb5cc2bfc"}, ] -[[package]] -name = "lessc" -version = "0.1.3" -description = "A Python less compiler" -optional = false -python-versions = "*" -files = [ - {file = "lessc-0.1.3.tar.gz", hash = "sha256:97a12f5f04731c9e77b5e14106ae07a77409081c901000fbec88e4a0a2e6de82"}, -] - -[package.dependencies] -asset = ">=0.6.12" -six = ">=1.10.0" - [[package]] name = "lesscpy" version = "0.15.1" @@ -696,60 +509,6 @@ files = [ {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, ] -[[package]] -name = "pep517" -version = "0.13.1" -description = "Wrappers to build Python packages using PEP 517 hooks" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pep517-0.13.1-py3-none-any.whl", hash = "sha256:31b206f67165b3536dd577c5c3f1518e8fbaf38cbc57efff8369a392feff1721"}, - {file = "pep517-0.13.1.tar.gz", hash = "sha256:1b2fa2ffd3938bb4beffe5d6146cbcb2bda996a5a4da9f31abffd8b24e07b317"}, -] - -[package.dependencies] -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} - -[[package]] -name = "pip" -version = "23.3.1" -description = "The PyPA recommended tool for installing Python packages." -optional = false -python-versions = ">=3.7" -files = [ - {file = "pip-23.3.1-py3-none-any.whl", hash = "sha256:55eb67bb6171d37447e82213be585b75fe2b12b359e993773aca4de9247a052b"}, - {file = "pip-23.3.1.tar.gz", hash = "sha256:1fcaa041308d01f14575f6d0d2ea4b75a3e2871fe4f9c694976f908768e14174"}, -] - -[[package]] -name = "pip-api" -version = "0.0.30" -description = "An unofficial, importable pip API" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pip-api-0.0.30.tar.gz", hash = "sha256:a05df2c7aa9b7157374bcf4273544201a0c7bae60a9c65bcf84f3959ef3896f3"}, - {file = "pip_api-0.0.30-py3-none-any.whl", hash = "sha256:2a0314bd31522eb9ffe8a99668b0d07fee34ebc537931e7b6483001dbedcbdc9"}, -] - -[package.dependencies] -pip = "*" - -[[package]] -name = "pipreqs" -version = "0.4.13" -description = "Pip requirements.txt generator based on imports in project" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pipreqs-0.4.13-py2.py3-none-any.whl", hash = "sha256:e522b9ed54aa3e8b7978ff251ab7a9af2f75d2cd8de4c102e881b666a79a308e"}, - {file = "pipreqs-0.4.13.tar.gz", hash = "sha256:a17f167880b6921be37533ce4c81ddc6e22b465c107aad557db43b1add56a99b"}, -] - -[package.dependencies] -docopt = "*" -yarg = "*" - [[package]] name = "platformdirs" version = "4.1.0" @@ -765,25 +524,6 @@ files = [ docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"] test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"] -[[package]] -name = "plette" -version = "0.4.4" -description = "Structured Pipfile and Pipfile.lock models." -optional = false -python-versions = ">=3.7" -files = [ - {file = "plette-0.4.4-py2.py3-none-any.whl", hash = "sha256:42d68ce8c6b966874b68758d87d7f20fcff2eff0d861903eea1062126be4d98f"}, - {file = "plette-0.4.4.tar.gz", hash = "sha256:06b8c09eb90293ad0b8101cb5c95c4ea53e9b2b582901845d0904ff02d237454"}, -] - -[package.dependencies] -cerberus = {version = "*", optional = true, markers = "extra == \"validation\""} -tomlkit = "*" - -[package.extras] -tests = ["pytest", "pytest-cov", "pytest-xdist"] -validation = ["cerberus"] - [[package]] name = "ply" version = "3.11" @@ -806,142 +546,6 @@ files = [ {file = "pycodestyle-2.11.1.tar.gz", hash = "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f"}, ] -[[package]] -name = "pydantic" -version = "2.5.2" -description = "Data validation using Python type hints" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pydantic-2.5.2-py3-none-any.whl", hash = "sha256:80c50fb8e3dcecfddae1adbcc00ec5822918490c99ab31f6cf6140ca1c1429f0"}, - {file = "pydantic-2.5.2.tar.gz", hash = "sha256:ff177ba64c6faf73d7afa2e8cad38fd456c0dbe01c9954e71038001cd15a6edd"}, -] - -[package.dependencies] -annotated-types = ">=0.4.0" -pydantic-core = "2.14.5" -typing-extensions = ">=4.6.1" - -[package.extras] -email = ["email-validator (>=2.0.0)"] - -[[package]] -name = "pydantic-core" -version = "2.14.5" -description = "" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pydantic_core-2.14.5-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:7e88f5696153dc516ba6e79f82cc4747e87027205f0e02390c21f7cb3bd8abfd"}, - {file = "pydantic_core-2.14.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4641e8ad4efb697f38a9b64ca0523b557c7931c5f84e0fd377a9a3b05121f0de"}, - {file = "pydantic_core-2.14.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:774de879d212db5ce02dfbf5b0da9a0ea386aeba12b0b95674a4ce0593df3d07"}, - {file = "pydantic_core-2.14.5-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ebb4e035e28f49b6f1a7032920bb9a0c064aedbbabe52c543343d39341a5b2a3"}, - {file = "pydantic_core-2.14.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b53e9ad053cd064f7e473a5f29b37fc4cc9dc6d35f341e6afc0155ea257fc911"}, - {file = "pydantic_core-2.14.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8aa1768c151cf562a9992462239dfc356b3d1037cc5a3ac829bb7f3bda7cc1f9"}, - {file = "pydantic_core-2.14.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eac5c82fc632c599f4639a5886f96867ffced74458c7db61bc9a66ccb8ee3113"}, - {file = "pydantic_core-2.14.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2ae91f50ccc5810b2f1b6b858257c9ad2e08da70bf890dee02de1775a387c66"}, - {file = "pydantic_core-2.14.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6b9ff467ffbab9110e80e8c8de3bcfce8e8b0fd5661ac44a09ae5901668ba997"}, - {file = "pydantic_core-2.14.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:61ea96a78378e3bd5a0be99b0e5ed00057b71f66115f5404d0dae4819f495093"}, - {file = "pydantic_core-2.14.5-cp310-none-win32.whl", hash = "sha256:bb4c2eda937a5e74c38a41b33d8c77220380a388d689bcdb9b187cf6224c9720"}, - {file = "pydantic_core-2.14.5-cp310-none-win_amd64.whl", hash = "sha256:b7851992faf25eac90bfcb7bfd19e1f5ffa00afd57daec8a0042e63c74a4551b"}, - {file = "pydantic_core-2.14.5-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:4e40f2bd0d57dac3feb3a3aed50f17d83436c9e6b09b16af271b6230a2915459"}, - {file = "pydantic_core-2.14.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ab1cdb0f14dc161ebc268c09db04d2c9e6f70027f3b42446fa11c153521c0e88"}, - {file = "pydantic_core-2.14.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aae7ea3a1c5bb40c93cad361b3e869b180ac174656120c42b9fadebf685d121b"}, - {file = "pydantic_core-2.14.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:60b7607753ba62cf0739177913b858140f11b8af72f22860c28eabb2f0a61937"}, - {file = "pydantic_core-2.14.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2248485b0322c75aee7565d95ad0e16f1c67403a470d02f94da7344184be770f"}, - {file = "pydantic_core-2.14.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:823fcc638f67035137a5cd3f1584a4542d35a951c3cc68c6ead1df7dac825c26"}, - {file = "pydantic_core-2.14.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96581cfefa9123accc465a5fd0cc833ac4d75d55cc30b633b402e00e7ced00a6"}, - {file = "pydantic_core-2.14.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a33324437018bf6ba1bb0f921788788641439e0ed654b233285b9c69704c27b4"}, - {file = "pydantic_core-2.14.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9bd18fee0923ca10f9a3ff67d4851c9d3e22b7bc63d1eddc12f439f436f2aada"}, - {file = "pydantic_core-2.14.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:853a2295c00f1d4429db4c0fb9475958543ee80cfd310814b5c0ef502de24dda"}, - {file = "pydantic_core-2.14.5-cp311-none-win32.whl", hash = "sha256:cb774298da62aea5c80a89bd58c40205ab4c2abf4834453b5de207d59d2e1651"}, - {file = "pydantic_core-2.14.5-cp311-none-win_amd64.whl", hash = "sha256:e87fc540c6cac7f29ede02e0f989d4233f88ad439c5cdee56f693cc9c1c78077"}, - {file = "pydantic_core-2.14.5-cp311-none-win_arm64.whl", hash = "sha256:57d52fa717ff445cb0a5ab5237db502e6be50809b43a596fb569630c665abddf"}, - {file = "pydantic_core-2.14.5-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:e60f112ac88db9261ad3a52032ea46388378034f3279c643499edb982536a093"}, - {file = "pydantic_core-2.14.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6e227c40c02fd873c2a73a98c1280c10315cbebe26734c196ef4514776120aeb"}, - {file = "pydantic_core-2.14.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0cbc7fff06a90bbd875cc201f94ef0ee3929dfbd5c55a06674b60857b8b85ed"}, - {file = "pydantic_core-2.14.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:103ef8d5b58596a731b690112819501ba1db7a36f4ee99f7892c40da02c3e189"}, - {file = "pydantic_core-2.14.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c949f04ecad823f81b1ba94e7d189d9dfb81edbb94ed3f8acfce41e682e48cef"}, - {file = "pydantic_core-2.14.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c1452a1acdf914d194159439eb21e56b89aa903f2e1c65c60b9d874f9b950e5d"}, - {file = "pydantic_core-2.14.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb4679d4c2b089e5ef89756bc73e1926745e995d76e11925e3e96a76d5fa51fc"}, - {file = "pydantic_core-2.14.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cf9d3fe53b1ee360e2421be95e62ca9b3296bf3f2fb2d3b83ca49ad3f925835e"}, - {file = "pydantic_core-2.14.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:70f4b4851dbb500129681d04cc955be2a90b2248d69273a787dda120d5cf1f69"}, - {file = "pydantic_core-2.14.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:59986de5710ad9613ff61dd9b02bdd2f615f1a7052304b79cc8fa2eb4e336d2d"}, - {file = "pydantic_core-2.14.5-cp312-none-win32.whl", hash = "sha256:699156034181e2ce106c89ddb4b6504c30db8caa86e0c30de47b3e0654543260"}, - {file = "pydantic_core-2.14.5-cp312-none-win_amd64.whl", hash = "sha256:5baab5455c7a538ac7e8bf1feec4278a66436197592a9bed538160a2e7d11e36"}, - {file = "pydantic_core-2.14.5-cp312-none-win_arm64.whl", hash = "sha256:e47e9a08bcc04d20975b6434cc50bf82665fbc751bcce739d04a3120428f3e27"}, - {file = "pydantic_core-2.14.5-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:af36f36538418f3806048f3b242a1777e2540ff9efaa667c27da63d2749dbce0"}, - {file = "pydantic_core-2.14.5-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:45e95333b8418ded64745f14574aa9bfc212cb4fbeed7a687b0c6e53b5e188cd"}, - {file = "pydantic_core-2.14.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e47a76848f92529879ecfc417ff88a2806438f57be4a6a8bf2961e8f9ca9ec7"}, - {file = "pydantic_core-2.14.5-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d81e6987b27bc7d101c8597e1cd2bcaa2fee5e8e0f356735c7ed34368c471550"}, - {file = "pydantic_core-2.14.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:34708cc82c330e303f4ce87758828ef6e457681b58ce0e921b6e97937dd1e2a3"}, - {file = "pydantic_core-2.14.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:652c1988019752138b974c28f43751528116bcceadad85f33a258869e641d753"}, - {file = "pydantic_core-2.14.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e4d090e73e0725b2904fdbdd8d73b8802ddd691ef9254577b708d413bf3006e"}, - {file = "pydantic_core-2.14.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5c7d5b5005f177764e96bd584d7bf28d6e26e96f2a541fdddb934c486e36fd59"}, - {file = "pydantic_core-2.14.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:a71891847f0a73b1b9eb86d089baee301477abef45f7eaf303495cd1473613e4"}, - {file = "pydantic_core-2.14.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a717aef6971208f0851a2420b075338e33083111d92041157bbe0e2713b37325"}, - {file = "pydantic_core-2.14.5-cp37-none-win32.whl", hash = "sha256:de790a3b5aa2124b8b78ae5faa033937a72da8efe74b9231698b5a1dd9be3405"}, - {file = "pydantic_core-2.14.5-cp37-none-win_amd64.whl", hash = "sha256:6c327e9cd849b564b234da821236e6bcbe4f359a42ee05050dc79d8ed2a91588"}, - {file = "pydantic_core-2.14.5-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:ef98ca7d5995a82f43ec0ab39c4caf6a9b994cb0b53648ff61716370eadc43cf"}, - {file = "pydantic_core-2.14.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c6eae413494a1c3f89055da7a5515f32e05ebc1a234c27674a6956755fb2236f"}, - {file = "pydantic_core-2.14.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcf4e6d85614f7a4956c2de5a56531f44efb973d2fe4a444d7251df5d5c4dcfd"}, - {file = "pydantic_core-2.14.5-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6637560562134b0e17de333d18e69e312e0458ee4455bdad12c37100b7cad706"}, - {file = "pydantic_core-2.14.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:77fa384d8e118b3077cccfcaf91bf83c31fe4dc850b5e6ee3dc14dc3d61bdba1"}, - {file = "pydantic_core-2.14.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16e29bad40bcf97aac682a58861249ca9dcc57c3f6be22f506501833ddb8939c"}, - {file = "pydantic_core-2.14.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:531f4b4252fac6ca476fbe0e6f60f16f5b65d3e6b583bc4d87645e4e5ddde331"}, - {file = "pydantic_core-2.14.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:074f3d86f081ce61414d2dc44901f4f83617329c6f3ab49d2bc6c96948b2c26b"}, - {file = "pydantic_core-2.14.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c2adbe22ab4babbca99c75c5d07aaf74f43c3195384ec07ccbd2f9e3bddaecec"}, - {file = "pydantic_core-2.14.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0f6116a558fd06d1b7c2902d1c4cf64a5bd49d67c3540e61eccca93f41418124"}, - {file = "pydantic_core-2.14.5-cp38-none-win32.whl", hash = "sha256:fe0a5a1025eb797752136ac8b4fa21aa891e3d74fd340f864ff982d649691867"}, - {file = "pydantic_core-2.14.5-cp38-none-win_amd64.whl", hash = "sha256:079206491c435b60778cf2b0ee5fd645e61ffd6e70c47806c9ed51fc75af078d"}, - {file = "pydantic_core-2.14.5-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:a6a16f4a527aae4f49c875da3cdc9508ac7eef26e7977952608610104244e1b7"}, - {file = "pydantic_core-2.14.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:abf058be9517dc877227ec3223f0300034bd0e9f53aebd63cf4456c8cb1e0863"}, - {file = "pydantic_core-2.14.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:49b08aae5013640a3bfa25a8eebbd95638ec3f4b2eaf6ed82cf0c7047133f03b"}, - {file = "pydantic_core-2.14.5-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c2d97e906b4ff36eb464d52a3bc7d720bd6261f64bc4bcdbcd2c557c02081ed2"}, - {file = "pydantic_core-2.14.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3128e0bbc8c091ec4375a1828d6118bc20404883169ac95ffa8d983b293611e6"}, - {file = "pydantic_core-2.14.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:88e74ab0cdd84ad0614e2750f903bb0d610cc8af2cc17f72c28163acfcf372a4"}, - {file = "pydantic_core-2.14.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c339dabd8ee15f8259ee0f202679b6324926e5bc9e9a40bf981ce77c038553db"}, - {file = "pydantic_core-2.14.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3387277f1bf659caf1724e1afe8ee7dbc9952a82d90f858ebb931880216ea955"}, - {file = "pydantic_core-2.14.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ba6b6b3846cfc10fdb4c971980a954e49d447cd215ed5a77ec8190bc93dd7bc5"}, - {file = "pydantic_core-2.14.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ca61d858e4107ce5e1330a74724fe757fc7135190eb5ce5c9d0191729f033209"}, - {file = "pydantic_core-2.14.5-cp39-none-win32.whl", hash = "sha256:ec1e72d6412f7126eb7b2e3bfca42b15e6e389e1bc88ea0069d0cc1742f477c6"}, - {file = "pydantic_core-2.14.5-cp39-none-win_amd64.whl", hash = "sha256:c0b97ec434041827935044bbbe52b03d6018c2897349670ff8fe11ed24d1d4ab"}, - {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:79e0a2cdbdc7af3f4aee3210b1172ab53d7ddb6a2d8c24119b5706e622b346d0"}, - {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:678265f7b14e138d9a541ddabbe033012a2953315739f8cfa6d754cc8063e8ca"}, - {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:95b15e855ae44f0c6341ceb74df61b606e11f1087e87dcb7482377374aac6abe"}, - {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:09b0e985fbaf13e6b06a56d21694d12ebca6ce5414b9211edf6f17738d82b0f8"}, - {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3ad873900297bb36e4b6b3f7029d88ff9829ecdc15d5cf20161775ce12306f8a"}, - {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:2d0ae0d8670164e10accbeb31d5ad45adb71292032d0fdb9079912907f0085f4"}, - {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:d37f8ec982ead9ba0a22a996129594938138a1503237b87318392a48882d50b7"}, - {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:35613015f0ba7e14c29ac6c2483a657ec740e5ac5758d993fdd5870b07a61d8b"}, - {file = "pydantic_core-2.14.5-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:ab4ea451082e684198636565224bbb179575efc1658c48281b2c866bfd4ddf04"}, - {file = "pydantic_core-2.14.5-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ce601907e99ea5b4adb807ded3570ea62186b17f88e271569144e8cca4409c7"}, - {file = "pydantic_core-2.14.5-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb2ed8b3fe4bf4506d6dab3b93b83bbc22237e230cba03866d561c3577517d18"}, - {file = "pydantic_core-2.14.5-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:70f947628e074bb2526ba1b151cee10e4c3b9670af4dbb4d73bc8a89445916b5"}, - {file = "pydantic_core-2.14.5-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:4bc536201426451f06f044dfbf341c09f540b4ebdb9fd8d2c6164d733de5e634"}, - {file = "pydantic_core-2.14.5-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f4791cf0f8c3104ac668797d8c514afb3431bc3305f5638add0ba1a5a37e0d88"}, - {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:038c9f763e650712b899f983076ce783175397c848da04985658e7628cbe873b"}, - {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:27548e16c79702f1e03f5628589c6057c9ae17c95b4c449de3c66b589ead0520"}, - {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c97bee68898f3f4344eb02fec316db93d9700fb1e6a5b760ffa20d71d9a46ce3"}, - {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9b759b77f5337b4ea024f03abc6464c9f35d9718de01cfe6bae9f2e139c397e"}, - {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:439c9afe34638ace43a49bf72d201e0ffc1a800295bed8420c2a9ca8d5e3dbb3"}, - {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:ba39688799094c75ea8a16a6b544eb57b5b0f3328697084f3f2790892510d144"}, - {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ccd4d5702bb90b84df13bd491be8d900b92016c5a455b7e14630ad7449eb03f8"}, - {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:81982d78a45d1e5396819bbb4ece1fadfe5f079335dd28c4ab3427cd95389944"}, - {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:7f8210297b04e53bc3da35db08b7302a6a1f4889c79173af69b72ec9754796b8"}, - {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:8c8a8812fe6f43a3a5b054af6ac2d7b8605c7bcab2804a8a7d68b53f3cd86e00"}, - {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:206ed23aecd67c71daf5c02c3cd19c0501b01ef3cbf7782db9e4e051426b3d0d"}, - {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c2027d05c8aebe61d898d4cffd774840a9cb82ed356ba47a90d99ad768f39789"}, - {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:40180930807ce806aa71eda5a5a5447abb6b6a3c0b4b3b1b1962651906484d68"}, - {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:615a0a4bff11c45eb3c1996ceed5bdaa2f7b432425253a7c2eed33bb86d80abc"}, - {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5e412d717366e0677ef767eac93566582518fe8be923361a5c204c1a62eaafe"}, - {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:513b07e99c0a267b1d954243845d8a833758a6726a3b5d8948306e3fe14675e3"}, - {file = "pydantic_core-2.14.5.tar.gz", hash = "sha256:6d30226dfc816dd0fdf120cae611dd2215117e4f9b124af8c60ab9093b6e8e71"}, -] - -[package.dependencies] -typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" - [[package]] name = "pyflakes" version = "3.1.0" @@ -982,81 +586,6 @@ files = [ [package.extras] cli = ["click (>=5.0)"] -[[package]] -name = "requests" -version = "2.31.0" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.7" -files = [ - {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, - {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, -] - -[package.dependencies] -certifi = ">=2017.4.17" -charset-normalizer = ">=2,<4" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "requirementslib" -version = "3.0.0" -description = "A tool for converting between pip-style and pipfile requirements." -optional = false -python-versions = ">=3.7" -files = [ - {file = "requirementslib-3.0.0-py2.py3-none-any.whl", hash = "sha256:67b42903d7c32f89c7047d1020c619d37cb515c475a4ae6f4e5683e1c56d7bf7"}, - {file = "requirementslib-3.0.0.tar.gz", hash = "sha256:28f8e0b1c38b34ae06de68ef115b03bbcdcdb99f9e9393333ff06ded443e3f24"}, -] - -[package.dependencies] -distlib = ">=0.2.8" -pep517 = ">=0.5.0" -pip = ">=23.1" -platformdirs = "*" -plette = {version = "*", extras = ["validation"]} -pydantic = "*" -requests = "*" -setuptools = ">=40.8" -tomlkit = ">=0.5.3" - -[package.extras] -dev = ["nox", "parver", "towncrier", "twine"] -docs = ["sphinx", "sphinx-rtd-theme"] -tests = ["coverage", "hypothesis", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "readme-renderer[md]"] - -[[package]] -name = "setuptools" -version = "69.0.2" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "setuptools-69.0.2-py3-none-any.whl", hash = "sha256:1e8fdff6797d3865f37397be788a4e3cba233608e9b509382a2777d25ebde7f2"}, - {file = "setuptools-69.0.2.tar.gz", hash = "sha256:735896e78a4742605974de002ac60562d286fa8051a7e2299445e8e8fbb01aa6"}, -] - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] - -[[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] - [[package]] name = "sqlalchemy" version = "2.0.23" @@ -1155,17 +684,6 @@ files = [ {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] -[[package]] -name = "tomlkit" -version = "0.12.3" -description = "Style preserving TOML library" -optional = false -python-versions = ">=3.7" -files = [ - {file = "tomlkit-0.12.3-py3-none-any.whl", hash = "sha256:b0a645a9156dc7cb5d3a1f0d4bab66db287fcb8e0430bdd4664a095ea16414ba"}, - {file = "tomlkit-0.12.3.tar.gz", hash = "sha256:75baf5012d06501f07bee5bf8e801b9f343e7aac5a92581f20f80ce632e6b5a4"}, -] - [[package]] name = "typing-extensions" version = "4.9.0" @@ -1177,32 +695,6 @@ files = [ {file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"}, ] -[[package]] -name = "urllib3" -version = "2.1.0" -description = "HTTP library with thread-safe connection pooling, file post, and more." -optional = false -python-versions = ">=3.8" -files = [ - {file = "urllib3-2.1.0-py3-none-any.whl", hash = "sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3"}, - {file = "urllib3-2.1.0.tar.gz", hash = "sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54"}, -] - -[package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "uwsgi" -version = "2.0.23" -description = "The uWSGI server" -optional = false -python-versions = "*" -files = [ - {file = "uwsgi-2.0.23.tar.gz", hash = "sha256:0cafda0c16f921db7fe42cfaf81b167cf884ee17350efbdd87d1ecece2d7de37"}, -] - [[package]] name = "webassets" version = "2.0" @@ -1248,21 +740,7 @@ markupsafe = "*" [package.extras] email = ["email-validator"] -[[package]] -name = "yarg" -version = "0.1.9" -description = "A semi hard Cornish cheese, also queries PyPI (PyPI client)" -optional = false -python-versions = "*" -files = [ - {file = "yarg-0.1.9-py2.py3-none-any.whl", hash = "sha256:4f9cebdc00fac946c9bf2783d634e538a71c7d280a4d806d45fd4dc0ef441492"}, - {file = "yarg-0.1.9.tar.gz", hash = "sha256:55695bf4d1e3e7f756496c36a69ba32c40d18f821e38f61d028f6049e5e15911"}, -] - -[package.dependencies] -requests = "*" - [metadata] lock-version = "2.0" python-versions = ">=3.10,<4.0" -content-hash = "d858cb5225973b3bcb4e6cd7827a2c5baebb9cae23beff99c9c95f1f8eaa0530" +content-hash = "7560fd8fc3615a40e0ddfd8a5c8de806c1f0f303c67a996dbac05591b2325ee6" diff --git a/pyproject.toml b/pyproject.toml index 024c8ec..eb0be45 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [tool.poetry] name = "flask_login_tutorial" version = "0.1.2" -description = "Tutorial for building user-based Flask applications" +description = "Tutorial for building Flask applications with user authorization & login." authors = ["Todd Birchard "] maintainers = ["Todd Birchard "] license = "MIT" @@ -13,6 +13,7 @@ keywords = ["Flask", "Flask-Login", "Authentication", "Users", "Accounts"] [tool.poetry.dependencies] python = ">=3.10,<4.0" +flask = "*" flask_sqlalchemy = "*" flask_login = "*" flask_assets = "*" @@ -20,22 +21,20 @@ pymysql = "*" flask_wtf = "*" python-dotenv = "*" email_validator = "*" -uWSGI = "*" -Flask = "*" -lessc = "*" lesscpy = "*" cssmin = "*" jsmin = "*" isort = "*" black = "*" -flake8 = "^6.1.0" +flake8 = "*" +gunicorn = "*" [build-system] requires = ["poetry-core>=1.0.0"] build-backend = "poetry.masonry.api" [tool.poetry.scripts] -run = "main:app" +run = "wsgi:app" [tool.poetry.urls] issues = "https://github.com/toddbirchard/flasklogin-tutorial/issues" @@ -45,5 +44,10 @@ line-length = 120 target-version = ['py310'] src_paths = ["flask_login_tutorial", "config", "main"] +[tool.isort] +profile = "black" +multi_line_output = 3 +src_paths = ["flask_login_tutorial", "config", "wsgi"] + [tool.pylint.'MESSAGES CONTROL'] disable = "C0103,C0301,W0703,W0621" diff --git a/requirements.txt b/requirements.txt index 106bafe..0668ae5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,17 +1,9 @@ -aadict==0.2.3 ; python_version >= "3.10" and python_version < "4.0" -annotated-types==0.6.0 ; python_version >= "3.10" and python_version < "4.0" -asset==0.6.13 ; python_version >= "3.10" and python_version < "4.0" -black==23.11.0 ; python_version >= "3.10" and python_version < "4.0" +black==23.12.0 ; python_version >= "3.10" and python_version < "4.0" blinker==1.7.0 ; python_version >= "3.10" and python_version < "4.0" -cerberus==1.3.5 ; python_version >= "3.10" and python_version < "4.0" -certifi==2023.11.17 ; python_version >= "3.10" and python_version < "4.0" -charset-normalizer==3.3.2 ; python_version >= "3.10" and python_version < "4.0" click==8.1.7 ; python_version >= "3.10" and python_version < "4.0" colorama==0.4.6 ; python_version >= "3.10" and python_version < "4.0" and platform_system == "Windows" cssmin==0.2.0 ; python_version >= "3.10" and python_version < "4.0" -distlib==0.3.7 ; python_version >= "3.10" and python_version < "4.0" dnspython==2.4.2 ; python_version >= "3.10" and python_version < "4.0" -docopt==0.6.2 ; python_version >= "3.10" and python_version < "4.0" email-validator==2.1.0.post1 ; python_version >= "3.10" and python_version < "4.0" flake8==6.1.0 ; python_version >= "3.10" and python_version < "4.0" flask-assets==2.1.0 ; python_version >= "3.10" and python_version < "4.0" @@ -19,44 +11,28 @@ flask-login==0.6.3 ; python_version >= "3.10" and python_version < "4.0" flask-sqlalchemy==3.1.1 ; python_version >= "3.10" and python_version < "4.0" flask-wtf==1.2.1 ; python_version >= "3.10" and python_version < "4.0" flask==3.0.0 ; python_version >= "3.10" and python_version < "4.0" -globre==0.1.5 ; python_version >= "3.10" and python_version < "4.0" greenlet==3.0.2 ; python_version >= "3.10" and python_version < "4.0" and (platform_machine == "aarch64" or platform_machine == "ppc64le" or platform_machine == "x86_64" or platform_machine == "amd64" or platform_machine == "AMD64" or platform_machine == "win32" or platform_machine == "WIN32") +gunicorn==21.2.0 ; python_version >= "3.10" and python_version < "4.0" idna==3.6 ; python_version >= "3.10" and python_version < "4.0" -isort==5.13.0 ; python_version >= "3.10" and python_version < "4.0" +isort==5.13.2 ; python_version >= "3.10" and python_version < "4.0" itsdangerous==2.1.2 ; python_version >= "3.10" and python_version < "4.0" jinja2==3.1.2 ; python_version >= "3.10" and python_version < "4.0" jsmin==3.0.1 ; python_version >= "3.10" and python_version < "4.0" -lessc==0.1.3 ; python_version >= "3.10" and python_version < "4.0" lesscpy==0.15.1 ; python_version >= "3.10" and python_version < "4.0" markupsafe==2.1.3 ; python_version >= "3.10" and python_version < "4.0" mccabe==0.7.0 ; python_version >= "3.10" and python_version < "4.0" mypy-extensions==1.0.0 ; python_version >= "3.10" and python_version < "4.0" packaging==23.2 ; python_version >= "3.10" and python_version < "4.0" pathspec==0.12.1 ; python_version >= "3.10" and python_version < "4.0" -pep517==0.13.1 ; python_version >= "3.10" and python_version < "4.0" -pip-api==0.0.30 ; python_version >= "3.10" and python_version < "4.0" -pip==23.3.1 ; python_version >= "3.10" and python_version < "4.0" -pipreqs==0.4.13 ; python_version >= "3.10" and python_version < "4.0" platformdirs==4.1.0 ; python_version >= "3.10" and python_version < "4.0" -plette[validation]==0.4.4 ; python_version >= "3.10" and python_version < "4.0" ply==3.11 ; python_version >= "3.10" and python_version < "4.0" pycodestyle==2.11.1 ; python_version >= "3.10" and python_version < "4.0" -pydantic-core==2.14.5 ; python_version >= "3.10" and python_version < "4.0" -pydantic==2.5.2 ; python_version >= "3.10" and python_version < "4.0" pyflakes==3.1.0 ; python_version >= "3.10" and python_version < "4.0" pymysql==1.1.0 ; python_version >= "3.10" and python_version < "4.0" python-dotenv==1.0.0 ; python_version >= "3.10" and python_version < "4.0" -requests==2.31.0 ; python_version >= "3.10" and python_version < "4.0" -requirementslib==3.0.0 ; python_version >= "3.10" and python_version < "4.0" -setuptools==69.0.2 ; python_version >= "3.10" and python_version < "4.0" -six==1.16.0 ; python_version >= "3.10" and python_version < "4.0" sqlalchemy==2.0.23 ; python_version >= "3.10" and python_version < "4.0" tomli==2.0.1 ; python_version >= "3.10" and python_version < "3.11" -tomlkit==0.12.3 ; python_version >= "3.10" and python_version < "4.0" typing-extensions==4.9.0 ; python_version >= "3.10" and python_version < "4.0" -urllib3==2.1.0 ; python_version >= "3.10" and python_version < "4.0" -uwsgi==2.0.23 ; python_version >= "3.10" and python_version < "4.0" webassets==2.0 ; python_version >= "3.10" and python_version < "4.0" werkzeug==3.0.1 ; python_version >= "3.10" and python_version < "4.0" wtforms==3.1.1 ; python_version >= "3.10" and python_version < "4.0" -yarg==0.1.9 ; python_version >= "3.10" and python_version < "4.0" diff --git a/main.py b/wsgi.py similarity index 52% rename from main.py rename to wsgi.py index 0f5d612..a508723 100644 --- a/main.py +++ b/wsgi.py @@ -2,6 +2,3 @@ from flask_login_tutorial import create_app app = create_app() - -if __name__ == "__main__": - app.run(host="0.0.0.0", load_dotenv=True, port=8083) From 0c997a03cded0bf8336a115a529571f0d43fc67b Mon Sep 17 00:00:00 2001 From: Todd Birchard Date: Sat, 16 Dec 2023 15:19:56 -0500 Subject: [PATCH 2/2] Password hashing update; minor style tweaks. --- flask_login_tutorial/models.py | 2 +- .../static/dist/css/account.css | 2 +- .../static/src/less/account.less | 33 +++++++++---------- .../static/src/less/vars.less | 12 +++++++ 4 files changed, 29 insertions(+), 20 deletions(-) diff --git a/flask_login_tutorial/models.py b/flask_login_tutorial/models.py index 6c453d7..ba32e0f 100644 --- a/flask_login_tutorial/models.py +++ b/flask_login_tutorial/models.py @@ -20,7 +20,7 @@ class User(UserMixin, db.Model): def set_password(self, password): """Create hashed password.""" - self.password = generate_password_hash(password, method="sha256") + self.password = generate_password_hash(password) def check_password(self, password): """Check hashed password.""" diff --git a/flask_login_tutorial/static/dist/css/account.css b/flask_login_tutorial/static/dist/css/account.css index 5710675..b3163e0 100644 --- a/flask_login_tutorial/static/dist/css/account.css +++ b/flask_login_tutorial/static/dist/css/account.css @@ -1 +1 @@ -.signup-page,.login-page{background:#e1eaf5}@media(max-width:600px){.signup-page,.login-page{width:100%;margin:0}}.signup-page .form-wrapper,.login-page .form-wrapper{background:white;width:370px;max-width:470px;margin:80px auto 0;box-shadow:0 0 5px rgba(65,67,144,0.15);padding:50px}@media(max-width:600px){.signup-page .form-wrapper,.login-page .form-wrapper{width:auto;margin:0;padding:30px}}.signup-page .form-wrapper .logo,.login-page .form-wrapper .logo{text-align:center;margin:0 auto 20px}.signup-page .form-wrapper .logo img,.login-page .form-wrapper .logo img{width:50px;margin:auto}@media(max-width:600px){.signup-page .form-wrapper .logo img,.login-page .form-wrapper .logo img{width:40px}}.signup-page .form-wrapper .alert-warning,.login-page .form-wrapper .alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba;font-weight:300;font-size:.8em;margin:30px 0;display:flex;align-items:center;justify-content:space-between}@media(max-width:600px){.signup-page .form-wrapper .alert-warning,.login-page .form-wrapper .alert-warning{padding:10px 15px}}.signup-page .form-wrapper .alert-warning .close,.login-page .form-wrapper .alert-warning .close{color:#856404;font-weight:300;order:1;outline:none!important;transition:all .3s ease-out}.signup-page .form-wrapper .alert,.login-page .form-wrapper .alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem;font-family:'Poppins',sans-serif}.signup-page .form-wrapper .alert button.close,.login-page .form-wrapper .alert button.close{padding:0;background-color:transparent;border:0;-webkit-appearance:none;float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.4}.signup-page .form-wrapper .alert button.close:hover,.login-page .form-wrapper .alert button.close:hover{cursor:pointer}.signup-page .form-wrapper h1,.login-page .form-wrapper h1{font-size:1.5rem;color:#5f6988;font-weight:300;border-bottom:1px solid #dee2ef;padding-bottom:5px;margin-bottom:20px;font-family:'Poppins',sans-serif}@media(max-width:600px){.signup-page .form-wrapper h1,.login-page .form-wrapper h1{font-size:1.3rem}}.signup-page .form-wrapper input,.login-page .form-wrapper input{padding:10px 13px;margin-bottom:15px;width:-webkit-fill-available;width:-moz-available;border-radius:2px;border:1px solid #d4d9e3;font-weight:200;color:#4d5060;font-family:'Poppins',sans-serif;transition:all .3s ease-out;font-size:.9em;outline-color:transparent;outline-style:none}@media(max-width:600px){.signup-page .form-wrapper input,.login-page .form-wrapper input{font-size:.9em}}.signup-page .form-wrapper input::placeholder,.login-page .form-wrapper input::placeholder{color:#828895}.signup-page .form-wrapper input:hover,.login-page .form-wrapper input:hover{border-color:#0297f6;background:#d9f6ff}.signup-page .form-wrapper input:hover::placeholder,.login-page .form-wrapper input:hover::placeholder{color:#0297f6}.signup-page .form-wrapper input:focus,.login-page .form-wrapper input:focus{background:white;border-color:#0297f6;box-shadow:unset}.signup-page .form-wrapper input:focus::placeholder,.login-page .form-wrapper input:focus::placeholder{color:#d4d9e3}.signup-page .form-wrapper fieldset,.login-page .form-wrapper fieldset{border:none;padding:0;margin:0}.signup-page .form-wrapper label,.login-page .form-wrapper label{font-size:.9em;color:#5f6988;margin-bottom:5px;display:block;font-weight:300;font-family:'Poppins',sans-serif}.signup-page .form-wrapper input[type="submit"],.login-page .form-wrapper input[type="submit"]{background:#0297f6;color:white;border-radius:2px;margin-top:15px;font-weight:400;border:1px solid #0297f6;transition:all .3s ease-out}.signup-page .form-wrapper input[type="submit"]:hover,.login-page .form-wrapper input[type="submit"]:hover{cursor:pointer;background:white;color:#0297f6}.signup-page .form-wrapper .errors,.login-page .form-wrapper .errors{margin-top:-11px;margin-bottom:1rem;list-style:none;padding:0;font-size:.9em;color:#b75353}.signup-page .login-signup,.login-page .login-signup{text-align:center;font-weight:300;font-size:.8em;font-family:'Poppins',sans-serif;margin-top:20px}.signup-page .login-signup a,.login-page .login-signup a{color:#0297f6;font-weight:500} \ No newline at end of file +.signup-page,.login-page{background:#e1eaf5}@media(max-width:600px){.signup-page,.login-page{width:100%;margin:0}}.signup-page .form-wrapper,.login-page .form-wrapper{background:white;width:370px;max-width:470px;margin:80px auto 0;box-shadow:0 0 5px rgba(65,67,144,0.15);padding:50px}@media(max-width:600px){.signup-page .form-wrapper,.login-page .form-wrapper{width:auto;margin:0;padding:30px 10vw;max-width:unset}}.signup-page .form-wrapper .logo,.login-page .form-wrapper .logo{text-align:center;margin:0 auto 20px}.signup-page .form-wrapper .logo img,.login-page .form-wrapper .logo img{width:50px;margin:auto}.signup-page .form-wrapper .alert-warning,.login-page .form-wrapper .alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba;font-weight:300;font-size:1em;margin:30px 0;display:flex;align-items:center;justify-content:space-between}@media(max-width:600px){.signup-page .form-wrapper .alert-warning,.login-page .form-wrapper .alert-warning{padding:10px 15px}}.signup-page .form-wrapper .alert-warning .close,.login-page .form-wrapper .alert-warning .close{color:#856404;font-weight:300;order:1;outline:none!important;transition:all .3s ease-out}.signup-page .form-wrapper .alert,.login-page .form-wrapper .alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem;font-family:'Poppins',sans-serif}.signup-page .form-wrapper .alert button.close,.login-page .form-wrapper .alert button.close{padding:0;background-color:transparent;border:0;-webkit-appearance:none;float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.4}.signup-page .form-wrapper .alert button.close:hover,.login-page .form-wrapper .alert button.close:hover{cursor:pointer}.signup-page .form-wrapper h1,.login-page .form-wrapper h1{font-size:1.9em;color:#5f6988;font-weight:300;border-bottom:1px solid #dee2ef;padding-bottom:5px;margin-bottom:20px;font-family:'Poppins',sans-serif}@media(max-width:600px){.signup-page .form-wrapper h1,.login-page .form-wrapper h1{font-size:1.3rem}}.signup-page .form-wrapper input,.login-page .form-wrapper input{padding:10px 13px;margin-bottom:15px;width:-webkit-fill-available;width:-moz-available;border-radius:2px;border:1px solid #d4d9e3;font-weight:200;font-size:1.1em;color:#4d5060;font-family:'Poppins',sans-serif;transition:all .3s ease-out;outline-color:transparent;outline-style:none}@media(max-width:600px){.signup-page .form-wrapper input,.login-page .form-wrapper input{font-size:1em}}.signup-page .form-wrapper input::placeholder,.login-page .form-wrapper input::placeholder{color:#828895}.signup-page .form-wrapper input:hover,.login-page .form-wrapper input:hover{border-color:#0297f6;background:#d9f6ff}.signup-page .form-wrapper input:hover::placeholder,.login-page .form-wrapper input:hover::placeholder{color:#0297f6}.signup-page .form-wrapper input:focus,.login-page .form-wrapper input:focus{background:white;border-color:#0297f6;box-shadow:unset}.signup-page .form-wrapper input:focus::placeholder,.login-page .form-wrapper input:focus::placeholder{color:#d4d9e3}.signup-page .form-wrapper fieldset,.login-page .form-wrapper fieldset{border:none;padding:0;margin:0}.signup-page .form-wrapper label,.login-page .form-wrapper label{font-size:.9em;color:#5f6988;margin-bottom:5px;display:block;font-weight:300;font-family:'Poppins',sans-serif}.signup-page .form-wrapper input[type="submit"],.login-page .form-wrapper input[type="submit"]{background:#0297f6;color:white;border-radius:2px;margin-top:15px;font-weight:400;border:1px solid #0297f6;transition:all .3s ease-out}.signup-page .form-wrapper input[type="submit"]:hover,.login-page .form-wrapper input[type="submit"]:hover{cursor:pointer;background:white;color:#0297f6}.signup-page .form-wrapper .errors,.login-page .form-wrapper .errors{margin-top:-11px;margin-bottom:1rem;list-style:none;padding:0;font-size:.9em;color:#b75353}.signup-page .login-signup,.login-page .login-signup{text-align:center;font-weight:300;font-size:1em;font-family:'Poppins',sans-serif;margin-top:20px}.signup-page .login-signup a,.login-page .login-signup a{color:#0297f6;font-weight:500} \ No newline at end of file diff --git a/flask_login_tutorial/static/src/less/account.less b/flask_login_tutorial/static/src/less/account.less index bc0573d..1b5eb4d 100644 --- a/flask_login_tutorial/static/src/less/account.less +++ b/flask_login_tutorial/static/src/less/account.less @@ -19,7 +19,8 @@ @media (max-width: 600px) { width: auto; margin: 0; - padding: 30px; + padding: 30px 10vw; + max-width: unset; } .logo { @@ -29,19 +30,15 @@ img { width: 50px; margin: auto; - - @media (max-width: 600px) { - width: 40px; - } } } .alert-warning { - color: #856404; - background-color: #fff3cd; - border-color: #ffeeba; + color: @alert-warning-text-color; + background-color: @alert-warning-bg-color; + border-color: @alert-warning-border-color; font-weight: 300; - font-size: .8em; + font-size: 1em; margin: 30px 0; display: flex; align-items: center; @@ -51,7 +48,7 @@ } .close { - color: #856404; + color: @alert-warning-text-color; font-weight: 300; order: 1; outline: none !important; @@ -87,7 +84,7 @@ } h1 { - font-size: 1.5rem; + font-size: 1.9em; color: @header-color; font-weight: 300; border-bottom: 1px solid #dee2ef; @@ -107,16 +104,16 @@ width: -webkit-fill-available; width: -moz-available; border-radius: 2px; - border: 1px solid #d4d9e3; + border: 1px solid @input-field-border-color; font-weight: 200; - color: #4d5060; + font-size: 1.1em; + color: @input-field-font-color; font-family: @body-font; transition: @transition; - font-size: .9em; outline-color: transparent; outline-style: none; @media (max-width: 600px) { - font-size: .9em; + font-size: 1em; } &::placeholder { @@ -125,7 +122,7 @@ &:hover { border-color: @theme-color; - background: #d9f6ff; + background: @input-field-hover-color; &::placeholder { color: @theme-color; @@ -138,7 +135,7 @@ box-shadow: unset; &::placeholder { - color: #d4d9e3; + color: @input-field-placeholder-color; } } } @@ -187,7 +184,7 @@ .login-signup { text-align: center; font-weight: 300; - font-size: 0.8em; + font-size: 1em; font-family: @body-font; margin-top: 20px; diff --git a/flask_login_tutorial/static/src/less/vars.less b/flask_login_tutorial/static/src/less/vars.less index 320e560..7665f2c 100644 --- a/flask_login_tutorial/static/src/less/vars.less +++ b/flask_login_tutorial/static/src/less/vars.less @@ -4,6 +4,18 @@ @box-shadow: 0 0 5px rgba(65, 67, 144, 0.15); @header-color: #5f6988; +// Form Colors +@input-field-border-color: #d4d9e3; +@input-field-font-color: #4d5060; +@input-field-hover-color: #d9f6ff; +@input-field-placeholder-color: #d4d9e3; + +// Alert Colors +@alert-warning-text-color: #856404; +@alert-warning-bg-color: #fff3cd; +@alert-warning-border-color: #ffeeba; + + // Fonts @body-font: 'Poppins', sans-serif;