develop 0f6d9c0cc937 cached
1594 files
19.0 MB
568.9k tokens
3696 symbols
1 requests
Download .txt
Showing preview only (2,250K chars total). Download the full file or copy to clipboard to get everything.
Repository: tecladocode/rest-api-sections
Branch: develop
Commit: 0f6d9c0cc937
Files: 1594
Total size: 19.0 MB

Directory structure:
gitextract_l2o0gskj/

├── .flake8
├── .github/
│   └── workflows/
│       └── algolia-scraper.yml
├── .gitignore
├── .gitmodules
├── .python-version
├── .templates/
│   ├── lecture.md
│   └── section.md
├── CONTRIBUTING.md
├── README.md
├── dependabot.yml
├── docs/
│   ├── .gitignore
│   ├── README.md
│   ├── algolia.config.json
│   ├── babel.config.js
│   ├── docs/
│   │   ├── 01_course_intro/
│   │   │   ├── 02_how_to_install_python/
│   │   │   │   └── README.md
│   │   │   ├── 03_how_to_install_ide/
│   │   │   │   └── README.md
│   │   │   ├── 04_what_is_rest_api/
│   │   │   │   └── README.md
│   │   │   ├── _category_.json
│   │   │   └── index.md
│   │   ├── 02_python_refresher/
│   │   │   ├── _category_.json
│   │   │   └── index.md
│   │   ├── 03_first_rest_api/
│   │   │   ├── 01_project_overview/
│   │   │   │   └── README.md
│   │   │   ├── 02_getting_set_up/
│   │   │   │   └── README.md
│   │   │   ├── 03_first_rest_api_endpoint/
│   │   │   │   └── README.md
│   │   │   ├── 04_what_is_json/
│   │   │   │   └── README.md
│   │   │   ├── 05_make_request_to_rest_api/
│   │   │   │   └── README.md
│   │   │   ├── 06_creating_stores/
│   │   │   │   └── README.md
│   │   │   ├── 07_creating_items/
│   │   │   │   └── README.md
│   │   │   ├── 08_return_data_from_rest_api/
│   │   │   │   └── README.md
│   │   │   ├── 09_final_code/
│   │   │   │   ├── README.md
│   │   │   │   └── end/
│   │   │   │       └── app.py
│   │   │   ├── Insomnia_section3.json
│   │   │   └── _category_.json
│   │   ├── 04_docker_intro/
│   │   │   ├── 01_what_is_docker_container/
│   │   │   │   ├── README.md
│   │   │   │   └── docker-presentation.key
│   │   │   ├── 02_run_docker_container/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   └── app.py
│   │   │   │   └── start/
│   │   │   │       └── app.py
│   │   │   ├── 03_in_depth_docker_tutorial/
│   │   │   │   └── README.md
│   │   │   ├── 04_run_with_docker_compose/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   └── docker-compose.yml
│   │   │   │   └── start/
│   │   │   │       ├── Dockerfile
│   │   │   │       └── app.py
│   │   │   ├── 05_run_commands_in_docker_containers/
│   │   │   │   └── README.md
│   │   │   ├── README.md
│   │   │   └── _category_.json
│   │   ├── 05_flask_smorest/
│   │   │   ├── 01_why_flask_smorest/
│   │   │   │   └── README.md
│   │   │   ├── 02_data_model_improvements/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   └── requirements.txt
│   │   │   │   └── start/
│   │   │   │       ├── Dockerfile
│   │   │   │       └── app.py
│   │   │   ├── 03_improvements_on_first_rest_api/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   └── requirements.txt
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       └── requirements.txt
│   │   │   ├── 04_new_endpoints_for_api/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   └── requirements.txt
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       └── requirements.txt
│   │   │   ├── 05_reload_api_docker_container/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   └── requirements.txt
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       └── requirements.txt
│   │   │   ├── 06_api_with_method_views/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   └── resources/
│   │   │   │   │       ├── __init__.py
│   │   │   │   │       ├── item.py
│   │   │   │   │       └── store.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       └── requirements.txt
│   │   │   ├── 07_marshmallow_schemas/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       ├── requirements.txt
│   │   │   │       └── resources/
│   │   │   │           ├── __init__.py
│   │   │   │           ├── item.py
│   │   │   │           └── store.py
│   │   │   ├── 08_validation_with_marshmallow/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       └── schemas.py
│   │   │   ├── 09_decorating_responses/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       └── schemas.py
│   │   │   ├── Insomnia_section5_Docker.json
│   │   │   ├── Insomnia_section5_before_Docker.json
│   │   │   └── _category_.json
│   │   ├── 06_sql_storage_sqlalchemy/
│   │   │   ├── 01_project_overview_sqlalchemy/
│   │   │   │   └── README.md
│   │   │   ├── 02_create_simple_sqlalchemy_model/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       └── schemas.py
│   │   │   ├── 03_one_to_many_relationships_sqlalchemy/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       └── schemas.py
│   │   │   ├── 04_configure_flask_sqlalchemy/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       └── schemas.py
│   │   │   ├── 05_insert_models_sqlalchemy/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       └── schemas.py
│   │   │   ├── 06_get_models_or_404/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       └── schemas.py
│   │   │   ├── 07_updating_models_sqlalchemy/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       └── schemas.py
│   │   │   ├── 08_retrieve_list_all_models/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       └── schemas.py
│   │   │   ├── 09_delete_models_sqlalchemy/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       └── schemas.py
│   │   │   ├── 10_delete_related_models_sqlalchemy/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       └── schemas.py
│   │   │   ├── 11_conclusion/
│   │   │   │   └── README.md
│   │   │   ├── Insomnia_section6.json
│   │   │   └── _category_.json
│   │   ├── 07_sqlalchemy_many_to_many/
│   │   │   ├── 01_section_changes/
│   │   │   │   └── README.md
│   │   │   ├── 02_one_to_many_review/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   └── tag.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   └── tag.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       └── schemas.py
│   │   │   ├── 03_many_to_many_relationships/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── conftest.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   └── tag.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   └── tag.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   └── tag.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   └── tag.py
│   │   │   │       └── schemas.py
│   │   │   ├── Insomnia_section7.json
│   │   │   └── _category_.json
│   │   ├── 08_flask_jwt_extended/
│   │   │   ├── 01_section_changes/
│   │   │   │   └── README.md
│   │   │   ├── 02_what_is_a_jwt/
│   │   │   │   └── README.md
│   │   │   ├── 03_how_is_jwt_used/
│   │   │   │   ├── README.md
│   │   │   │   └── how-are-jwts-used.key
│   │   │   ├── 04_flask_jwt_extended_setup/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .dockerignore
│   │   │   │   │   ├── .flake8
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── conftest.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   └── tag.py
│   │   │   │   │   ├── requirements-dev.txt
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   ├── conftest.py
│   │   │   │   │   │   │   ├── test_item.py
│   │   │   │   │   │   │   ├── test_store.py
│   │   │   │   │   │   │   └── test_tag.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   └── tag.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .dockerignore
│   │   │   │       ├── .flake8
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── conftest.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   └── tag.py
│   │   │   │       ├── requirements-dev.txt
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── __tests__/
│   │   │   │       │   │   ├── conftest.py
│   │   │   │       │   │   ├── test_item.py
│   │   │   │       │   │   ├── test_store.py
│   │   │   │       │   │   └── test_tag.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   └── tag.py
│   │   │   │       └── schemas.py
│   │   │   ├── 05_user_model_and_schema/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .dockerignore
│   │   │   │   │   ├── .flake8
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── conftest.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements-dev.txt
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   ├── conftest.py
│   │   │   │   │   │   │   ├── test_item.py
│   │   │   │   │   │   │   ├── test_store.py
│   │   │   │   │   │   │   └── test_tag.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   └── tag.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .dockerignore
│   │   │   │       ├── .flake8
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── conftest.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   └── tag.py
│   │   │   │       ├── requirements-dev.txt
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── __tests__/
│   │   │   │       │   │   ├── conftest.py
│   │   │   │       │   │   ├── test_item.py
│   │   │   │       │   │   ├── test_store.py
│   │   │   │       │   │   └── test_tag.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   └── tag.py
│   │   │   │       └── schemas.py
│   │   │   ├── 06_registering_users_rest_api/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .dockerignore
│   │   │   │   │   ├── .flake8
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── conftest.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements-dev.txt
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   ├── conftest.py
│   │   │   │   │   │   │   ├── test_item.py
│   │   │   │   │   │   │   ├── test_store.py
│   │   │   │   │   │   │   ├── test_tag.py
│   │   │   │   │   │   │   └── test_user.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .dockerignore
│   │   │   │       ├── .flake8
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── conftest.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── requirements-dev.txt
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── __tests__/
│   │   │   │       │   │   ├── conftest.py
│   │   │   │       │   │   ├── test_item.py
│   │   │   │       │   │   ├── test_store.py
│   │   │   │       │   │   └── test_tag.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   └── tag.py
│   │   │   │       └── schemas.py
│   │   │   ├── 07_login_users_rest_api/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .dockerignore
│   │   │   │   │   ├── .flake8
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── conftest.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements-dev.txt
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   ├── conftest.py
│   │   │   │   │   │   │   ├── test_item.py
│   │   │   │   │   │   │   ├── test_store.py
│   │   │   │   │   │   │   ├── test_tag.py
│   │   │   │   │   │   │   └── test_user.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .dockerignore
│   │   │   │       ├── .flake8
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── conftest.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── requirements-dev.txt
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── __tests__/
│   │   │   │       │   │   ├── conftest.py
│   │   │   │       │   │   ├── test_item.py
│   │   │   │       │   │   ├── test_store.py
│   │   │   │       │   │   ├── test_tag.py
│   │   │   │       │   │   └── test_user.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       └── schemas.py
│   │   │   ├── 08_protect_resources_with_jwt_required/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .dockerignore
│   │   │   │   │   ├── .flake8
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── conftest.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements-dev.txt
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   ├── conftest.py
│   │   │   │   │   │   │   ├── test_item.py
│   │   │   │   │   │   │   ├── test_store.py
│   │   │   │   │   │   │   ├── test_tag.py
│   │   │   │   │   │   │   └── test_user.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .dockerignore
│   │   │   │       ├── .flake8
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── conftest.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── requirements-dev.txt
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── __tests__/
│   │   │   │       │   │   ├── conftest.py
│   │   │   │       │   │   ├── test_item.py
│   │   │   │       │   │   ├── test_store.py
│   │   │   │       │   │   ├── test_tag.py
│   │   │   │       │   │   └── test_user.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       └── schemas.py
│   │   │   ├── 09_jwt_claims_and_authorization/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .dockerignore
│   │   │   │   │   ├── .flake8
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── conftest.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements-dev.txt
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   ├── conftest.py
│   │   │   │   │   │   │   ├── test_item.py
│   │   │   │   │   │   │   ├── test_store.py
│   │   │   │   │   │   │   ├── test_tag.py
│   │   │   │   │   │   │   └── test_user.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .dockerignore
│   │   │   │       ├── .flake8
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── conftest.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── requirements-dev.txt
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── __tests__/
│   │   │   │       │   │   ├── conftest.py
│   │   │   │       │   │   ├── test_item.py
│   │   │   │       │   │   ├── test_store.py
│   │   │   │       │   │   ├── test_tag.py
│   │   │   │       │   │   └── test_user.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       └── schemas.py
│   │   │   ├── 10_logout_users_rest_api/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .dockerignore
│   │   │   │   │   ├── .flake8
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── blocklist.py
│   │   │   │   │   ├── conftest.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements-dev.txt
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   ├── conftest.py
│   │   │   │   │   │   │   ├── test_item.py
│   │   │   │   │   │   │   ├── test_store.py
│   │   │   │   │   │   │   ├── test_tag.py
│   │   │   │   │   │   │   └── test_user.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .dockerignore
│   │   │   │       ├── .flake8
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── conftest.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── requirements-dev.txt
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── __tests__/
│   │   │   │       │   │   ├── conftest.py
│   │   │   │       │   │   ├── test_item.py
│   │   │   │       │   │   ├── test_store.py
│   │   │   │       │   │   ├── test_tag.py
│   │   │   │       │   │   └── test_user.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       └── schemas.py
│   │   │   ├── 11_insomnia_request_chaining/
│   │   │   │   └── README.md
│   │   │   ├── 12_token_refreshing_flask_jwt_extended/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .dockerignore
│   │   │   │   │   ├── .flake8
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── blocklist.py
│   │   │   │   │   ├── conftest.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements-dev.txt
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   ├── conftest.py
│   │   │   │   │   │   │   ├── test_item.py
│   │   │   │   │   │   │   ├── test_store.py
│   │   │   │   │   │   │   ├── test_tag.py
│   │   │   │   │   │   │   └── test_user.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   └── schemas.py
│   │   │   │   ├── end_video/
│   │   │   │   │   ├── .dockerignore
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── blocklist.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .dockerignore
│   │   │   │       ├── .flake8
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── blocklist.py
│   │   │   │       ├── conftest.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── requirements-dev.txt
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── __tests__/
│   │   │   │       │   │   ├── conftest.py
│   │   │   │       │   │   ├── test_item.py
│   │   │   │       │   │   ├── test_store.py
│   │   │   │       │   │   ├── test_tag.py
│   │   │   │       │   │   └── test_user.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       └── schemas.py
│   │   │   ├── Insomnia_section8_before_chaining.json
│   │   │   ├── Insomnia_section8_chaining.json
│   │   │   └── _category_.json
│   │   ├── 09_flask_migrate/
│   │   │   ├── 01_why_use_database_migrations/
│   │   │   │   └── README.md
│   │   │   ├── 02_add_flask_migrate_to_app/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .dockerignore
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── blocklist.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .dockerignore
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── blocklist.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       └── schemas.py
│   │   │   ├── 03_initialize_database_flask_db_init/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .dockerignore
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── .python-version
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── blocklist.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── migrations/
│   │   │   │   │   │   ├── README
│   │   │   │   │   │   ├── alembic.ini
│   │   │   │   │   │   ├── env.py
│   │   │   │   │   │   ├── script.py.mako
│   │   │   │   │   │   └── versions/
│   │   │   │   │   │       └── c575166f6192_.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .dockerignore
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── blocklist.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       └── schemas.py
│   │   │   ├── 04_change_models_generate_alembic_migration/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .dockerignore
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── .python-version
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── blocklist.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── migrations/
│   │   │   │   │   │   ├── README
│   │   │   │   │   │   ├── alembic.ini
│   │   │   │   │   │   ├── env.py
│   │   │   │   │   │   ├── script.py.mako
│   │   │   │   │   │   └── versions/
│   │   │   │   │   │       ├── bcc005bc255c_.py
│   │   │   │   │   │       └── c575166f6192_.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .dockerignore
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── .python-version
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── blocklist.py
│   │   │   │       ├── db.py
│   │   │   │       ├── migrations/
│   │   │   │       │   ├── README
│   │   │   │       │   ├── alembic.ini
│   │   │   │       │   ├── env.py
│   │   │   │       │   ├── script.py.mako
│   │   │   │       │   └── versions/
│   │   │   │       │       └── c575166f6192_.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       └── schemas.py
│   │   │   ├── 05_manually_review_modify_migrations/
│   │   │   │   └── README.md
│   │   │   └── _category_.json
│   │   ├── 10_git_crash_course/
│   │   │   ├── README.md
│   │   │   └── _category_.json
│   │   ├── 11_deploy_to_render/
│   │   │   ├── 01_section_overview/
│   │   │   │   └── README.md
│   │   │   ├── 02_create_render_web_service/
│   │   │   │   └── README.md
│   │   │   ├── 03_docker_with_gunicorn/
│   │   │   │   └── README.md
│   │   │   ├── 04_deploy_postgresql_database/
│   │   │   │   └── README.md
│   │   │   ├── 05_environment_variables_and_migrations/
│   │   │   │   └── README.md
│   │   │   ├── 06_run_everything_docker_compose/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── .gitignore
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── blocklist.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── docker-compose.yml
│   │   │   │   │   ├── docker-entrypoint.sh
│   │   │   │   │   ├── migrations/
│   │   │   │   │   │   ├── README
│   │   │   │   │   │   ├── alembic.ini
│   │   │   │   │   │   ├── env.py
│   │   │   │   │   │   ├── script.py.mako
│   │   │   │   │   │   └── versions/
│   │   │   │   │   │       ├── 07006e31e788_.py
│   │   │   │   │   │       ├── 8ca023a4a4b0_.py
│   │   │   │   │   │       └── bb5da1e68550_.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── .gitignore
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── README.md
│   │   │   │       ├── app.py
│   │   │   │       ├── blocklist.py
│   │   │   │       ├── db.py
│   │   │   │       ├── docker-entrypoint.sh
│   │   │   │       ├── migrations/
│   │   │   │       │   ├── README
│   │   │   │       │   ├── alembic.ini
│   │   │   │       │   ├── env.py
│   │   │   │       │   ├── script.py.mako
│   │   │   │       │   └── versions/
│   │   │   │       │       ├── 07006e31e788_.py
│   │   │   │       │       ├── 8ca023a4a4b0_.py
│   │   │   │       │       └── bb5da1e68550_.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       └── schemas.py
│   │   │   ├── Insomnia_section11.json
│   │   │   └── _category_.json
│   │   ├── 12_task_queues_emails/
│   │   │   ├── 01_send_emails_python_mailgun/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── .gitignore
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── blocklist.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── docker-entrypoint.sh
│   │   │   │   │   ├── migrations/
│   │   │   │   │   │   ├── README
│   │   │   │   │   │   ├── alembic.ini
│   │   │   │   │   │   ├── env.py
│   │   │   │   │   │   ├── script.py.mako
│   │   │   │   │   │   └── versions/
│   │   │   │   │   │       ├── 07006e31e788_.py
│   │   │   │   │   │       ├── 8ca023a4a4b0_.py
│   │   │   │   │   │       └── bb5da1e68550_.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── .gitignore
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── README.md
│   │   │   │       ├── app.py
│   │   │   │       ├── blocklist.py
│   │   │   │       ├── db.py
│   │   │   │       ├── docker-entrypoint.sh
│   │   │   │       ├── migrations/
│   │   │   │       │   ├── README
│   │   │   │       │   ├── alembic.ini
│   │   │   │       │   ├── env.py
│   │   │   │       │   ├── script.py.mako
│   │   │   │       │   └── versions/
│   │   │   │       │       ├── 07006e31e788_.py
│   │   │   │       │       ├── 8ca023a4a4b0_.py
│   │   │   │       │       └── bb5da1e68550_.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       └── schemas.py
│   │   │   ├── 02_send_email_user_registration/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── .gitignore
│   │   │   │   │   ├── .python-version
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── blocklist.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── docker-entrypoint.sh
│   │   │   │   │   ├── migrations/
│   │   │   │   │   │   ├── README
│   │   │   │   │   │   ├── alembic.ini
│   │   │   │   │   │   ├── env.py
│   │   │   │   │   │   ├── script.py.mako
│   │   │   │   │   │   └── versions/
│   │   │   │   │   │       ├── 07006e31e788_.py
│   │   │   │   │   │       ├── 8ca023a4a4b0_.py
│   │   │   │   │   │       ├── bb5da1e68550_.py
│   │   │   │   │   │       └── d8e0f80631fb_.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── .gitignore
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── README.md
│   │   │   │       ├── app.py
│   │   │   │       ├── blocklist.py
│   │   │   │       ├── db.py
│   │   │   │       ├── docker-entrypoint.sh
│   │   │   │       ├── migrations/
│   │   │   │       │   ├── README
│   │   │   │       │   ├── alembic.ini
│   │   │   │       │   ├── env.py
│   │   │   │       │   ├── script.py.mako
│   │   │   │       │   └── versions/
│   │   │   │       │       ├── 07006e31e788_.py
│   │   │   │       │       ├── 8ca023a4a4b0_.py
│   │   │   │       │       └── bb5da1e68550_.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       └── schemas.py
│   │   │   ├── 03_what_is_task_queue/
│   │   │   │   └── README.md
│   │   │   ├── 04_populate_rq_task_queue/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── .gitignore
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── blocklist.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── docker-entrypoint.sh
│   │   │   │   │   ├── migrations/
│   │   │   │   │   │   ├── README
│   │   │   │   │   │   ├── alembic.ini
│   │   │   │   │   │   ├── env.py
│   │   │   │   │   │   ├── script.py.mako
│   │   │   │   │   │   └── versions/
│   │   │   │   │   │       ├── 07006e31e788_.py
│   │   │   │   │   │       ├── 8ca023a4a4b0_.py
│   │   │   │   │   │       ├── bb5da1e68550_.py
│   │   │   │   │   │       └── d8e0f80631fb_.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── schemas.py
│   │   │   │   │   └── tasks.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── .gitignore
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── README.md
│   │   │   │       ├── app.py
│   │   │   │       ├── blocklist.py
│   │   │   │       ├── db.py
│   │   │   │       ├── docker-entrypoint.sh
│   │   │   │       ├── migrations/
│   │   │   │       │   ├── README
│   │   │   │       │   ├── alembic.ini
│   │   │   │       │   ├── env.py
│   │   │   │       │   ├── script.py.mako
│   │   │   │       │   └── versions/
│   │   │   │       │       ├── 07006e31e788_.py
│   │   │   │       │       ├── 8ca023a4a4b0_.py
│   │   │   │       │       ├── bb5da1e68550_.py
│   │   │   │       │       └── d8e0f80631fb_.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       └── schemas.py
│   │   │   ├── 05_rq_background_worker/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── .gitignore
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── blocklist.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── docker-entrypoint.sh
│   │   │   │   │   ├── migrations/
│   │   │   │   │   │   ├── README
│   │   │   │   │   │   ├── alembic.ini
│   │   │   │   │   │   ├── env.py
│   │   │   │   │   │   ├── script.py.mako
│   │   │   │   │   │   └── versions/
│   │   │   │   │   │       ├── 07006e31e788_.py
│   │   │   │   │   │       ├── 8ca023a4a4b0_.py
│   │   │   │   │   │       ├── bb5da1e68550_.py
│   │   │   │   │   │       └── d8e0f80631fb_.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── schemas.py
│   │   │   │   │   └── tasks.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── .gitignore
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── README.md
│   │   │   │       ├── app.py
│   │   │   │       ├── blocklist.py
│   │   │   │       ├── db.py
│   │   │   │       ├── docker-entrypoint.sh
│   │   │   │       ├── migrations/
│   │   │   │       │   ├── README
│   │   │   │       │   ├── alembic.ini
│   │   │   │       │   ├── env.py
│   │   │   │       │   ├── script.py.mako
│   │   │   │       │   └── versions/
│   │   │   │       │       ├── 07006e31e788_.py
│   │   │   │       │       ├── 8ca023a4a4b0_.py
│   │   │   │       │       ├── bb5da1e68550_.py
│   │   │   │       │       └── d8e0f80631fb_.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── schemas.py
│   │   │   │       └── tasks.py
│   │   │   ├── 06_sending_html_emails/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── .gitignore
│   │   │   │   │   ├── .python-version
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── blocklist.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── docker-entrypoint.sh
│   │   │   │   │   ├── migrations/
│   │   │   │   │   │   ├── README
│   │   │   │   │   │   ├── alembic.ini
│   │   │   │   │   │   ├── env.py
│   │   │   │   │   │   ├── script.py.mako
│   │   │   │   │   │   └── versions/
│   │   │   │   │   │       ├── 07006e31e788_.py
│   │   │   │   │   │       ├── 8ca023a4a4b0_.py
│   │   │   │   │   │       ├── bb5da1e68550_.py
│   │   │   │   │   │       └── d8e0f80631fb_.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── schemas.py
│   │   │   │   │   ├── tasks.py
│   │   │   │   │   └── templates/
│   │   │   │   │       └── email/
│   │   │   │   │           ├── action.html
│   │   │   │   │           └── action.original.html
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── .gitignore
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── README.md
│   │   │   │       ├── app.py
│   │   │   │       ├── blocklist.py
│   │   │   │       ├── db.py
│   │   │   │       ├── docker-entrypoint.sh
│   │   │   │       ├── migrations/
│   │   │   │       │   ├── README
│   │   │   │       │   ├── alembic.ini
│   │   │   │       │   ├── env.py
│   │   │   │       │   ├── script.py.mako
│   │   │   │       │   └── versions/
│   │   │   │       │       ├── 07006e31e788_.py
│   │   │   │       │       ├── 8ca023a4a4b0_.py
│   │   │   │       │       ├── bb5da1e68550_.py
│   │   │   │       │       └── d8e0f80631fb_.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── schemas.py
│   │   │   │       └── tasks.py
│   │   │   ├── 07_deploy_background_worker_render/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── .gitignore
│   │   │   │   │   ├── .python-version
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── blocklist.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── docker-entrypoint.sh
│   │   │   │   │   ├── migrations/
│   │   │   │   │   │   ├── README
│   │   │   │   │   │   ├── alembic.ini
│   │   │   │   │   │   ├── env.py
│   │   │   │   │   │   ├── script.py.mako
│   │   │   │   │   │   └── versions/
│   │   │   │   │   │       ├── 07006e31e788_.py
│   │   │   │   │   │       ├── 8ca023a4a4b0_.py
│   │   │   │   │   │       ├── bb5da1e68550_.py
│   │   │   │   │   │       └── d8e0f80631fb_.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── schemas.py
│   │   │   │   │   ├── settings.py
│   │   │   │   │   ├── tasks.py
│   │   │   │   │   └── templates/
│   │   │   │   │       └── email/
│   │   │   │   │           ├── action.html
│   │   │   │   │           └── action.original.html
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── .gitignore
│   │   │   │       ├── .python-version
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── README.md
│   │   │   │       ├── app.py
│   │   │   │       ├── blocklist.py
│   │   │   │       ├── db.py
│   │   │   │       ├── docker-entrypoint.sh
│   │   │   │       ├── migrations/
│   │   │   │       │   ├── README
│   │   │   │       │   ├── alembic.ini
│   │   │   │       │   ├── env.py
│   │   │   │       │   ├── script.py.mako
│   │   │   │       │   └── versions/
│   │   │   │       │       ├── 07006e31e788_.py
│   │   │   │       │       ├── 8ca023a4a4b0_.py
│   │   │   │       │       ├── bb5da1e68550_.py
│   │   │   │       │       └── d8e0f80631fb_.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── schemas.py
│   │   │   │       ├── tasks.py
│   │   │   │       └── templates/
│   │   │   │           └── email/
│   │   │   │               ├── action.html
│   │   │   │               └── action.original.html
│   │   │   ├── Insomnia_section12.json
│   │   │   └── _category_.json
│   │   └── Insomnia_all_sections.json
│   ├── docusaurus.config.js
│   ├── package.json
│   ├── sidebars.js
│   └── src/
│       ├── components/
│       │   ├── HomepageFeatures/
│       │   │   ├── index.js
│       │   │   └── styles.module.css
│       │   ├── LockedVideoEmbed/
│       │   │   └── index.js
│       │   └── VideoEmbed/
│       │       └── index.js
│       ├── css/
│       │   └── custom.css
│       └── pages/
│           ├── index.js
│           ├── index.module.css
│           └── insomnia-files.md
└── project/
    ├── 01-first-rest-api/
    │   └── app.py
    ├── 02-first-rest-api-docker/
    │   ├── Dockerfile
    │   └── app.py
    ├── 03-items-stores-smorest/
    │   ├── .flaskenv
    │   ├── Dockerfile
    │   ├── app.py
    │   ├── db.py
    │   ├── requirements.txt
    │   ├── resources/
    │   │   ├── __init__.py
    │   │   ├── item.py
    │   │   └── store.py
    │   └── schemas.py
    ├── 04-items-stores-smorest-sqlalchemy/
    │   ├── .flaskenv
    │   ├── Dockerfile
    │   ├── app.py
    │   ├── db.py
    │   ├── models/
    │   │   ├── __init__.py
    │   │   ├── item.py
    │   │   └── store.py
    │   ├── requirements.txt
    │   ├── resources/
    │   │   ├── __init__.py
    │   │   ├── item.py
    │   │   └── store.py
    │   └── schemas.py
    ├── 05-add-many-to-many/
    │   ├── .flaskenv
    │   ├── Dockerfile
    │   ├── app.py
    │   ├── conftest.py
    │   ├── db.py
    │   ├── models/
    │   │   ├── __init__.py
    │   │   ├── item.py
    │   │   ├── item_tags.py
    │   │   ├── store.py
    │   │   └── tag.py
    │   ├── requirements.txt
    │   ├── resources/
    │   │   ├── __init__.py
    │   │   ├── __tests__/
    │   │   │   ├── conftest.py
    │   │   │   ├── test_item.py
    │   │   │   ├── test_store.py
    │   │   │   └── test_tag.py
    │   │   ├── item.py
    │   │   ├── store.py
    │   │   └── tag.py
    │   └── schemas.py
    ├── 06-add-db-migrations/
    │   ├── .flaskenv
    │   ├── .python-version
    │   ├── Dockerfile
    │   ├── app.py
    │   ├── conftest.py
    │   ├── db.py
    │   ├── migrations/
    │   │   ├── README
    │   │   ├── alembic.ini
    │   │   ├── env.py
    │   │   ├── script.py.mako
    │   │   └── versions/
    │   │       ├── 5acd69659946_.py
    │   │       └── a40bdfbd7a9d_.py
    │   ├── models/
    │   │   ├── __init__.py
    │   │   ├── item.py
    │   │   ├── item_tags.py
    │   │   ├── store.py
    │   │   └── tag.py
    │   ├── requirements.txt
    │   ├── resources/
    │   │   ├── __init__.py
    │   │   ├── __tests__/
    │   │   │   ├── conftest.py
    │   │   │   ├── test_item.py
    │   │   │   ├── test_store.py
    │   │   │   └── test_tag.py
    │   │   ├── item.py
    │   │   ├── store.py
    │   │   └── tag.py
    │   └── schemas.py
    ├── using-flask-restful/
    │   ├── .flaskenv
    │   ├── Flask-JWT-Extended.postman_collection.json
    │   ├── Stores_REST_API_2022-01-14.json
    │   ├── app.py
    │   ├── blocklist.py
    │   ├── db.py
    │   ├── models/
    │   │   ├── __init__.py
    │   │   ├── item.py
    │   │   ├── item_tags.py
    │   │   ├── store.py
    │   │   ├── tag.py
    │   │   └── user.py
    │   ├── requirements.txt
    │   └── resources/
    │       ├── __init__.py
    │       ├── item.py
    │       ├── store.py
    │       ├── tag.py
    │       └── user.py
    ├── using-flask-restx/
    │   ├── .flaskenv
    │   ├── Flask-JWT-Extended.postman_collection.json
    │   ├── Stores_REST_API_2022-01-14.json
    │   ├── app.py
    │   ├── blocklist.py
    │   ├── db.py
    │   ├── models/
    │   │   ├── __init__.py
    │   │   ├── item.py
    │   │   ├── item_tags.py
    │   │   ├── store.py
    │   │   ├── tag.py
    │   │   └── user.py
    │   ├── requirements.txt
    │   └── resources/
    │       ├── __init__.py
    │       ├── item.py
    │       ├── store.py
    │       ├── tag.py
    │       └── user.py
    └── using-flask-smorest/
        ├── .flaskenv
        ├── Flask-JWT-Extended.postman_collection.json
        ├── Stores_REST_API_2022-01-14.json
        ├── app.py
        ├── blocklist.py
        ├── db.py
        ├── models/
        │   ├── __init__.py
        │   ├── item.py
        │   ├── item_tags.py
        │   ├── store.py
        │   ├── tag.py
        │   └── user.py
        ├── requirements.txt
        ├── resources/
        │   ├── __init__.py
        │   ├── item.py
        │   ├── store.py
        │   ├── tag.py
        │   └── user.py
        └── schemas.py

================================================
FILE CONTENTS
================================================

================================================
FILE: .flake8
================================================
[flake8]
max-line-length = 88
exclude = .git,__pycache__
max-complexity = 10

================================================
FILE: .github/workflows/algolia-scraper.yml
================================================
name: Run Algolia Scraper

on:
  push:
    branches: ["master", "develop"]
  pull_request:
    branches: ["master", "develop"]

permissions:
  contents: read

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: darrenjennings/algolia-docsearch-action@master
        with:
          algolia_application_id: "1BEGBIP9SH"
          algolia_api_key: ${{ secrets.ALGOLIA_API_KEY }}
          file: "docs/algolia.config.json"


================================================
FILE: .gitignore
================================================
.vscode/
*.pyc
.idea/
__pycache__/
*.db
.DS_Store
venv/
.venv/
docs/docs/.nota/config.ini
section-start-code.zip
section-end-code.zip

================================================
FILE: .gitmodules
================================================
[submodule "Flask-Smorest Docker"]
	path = project/using-flask-smorest-docker
	url = https://github.com/tecladocode/rest-api-smorest-docker

================================================
FILE: .python-version
================================================
3.10.0


================================================
FILE: .templates/lecture.md
================================================
---
title: The lecture title goes here
description: A brief description of the lecture goes here.
---

- [ ] Set metadata above
- [ ] Start writing!
- [ ] Create `start` folder
- [ ] Create `end` folder
- [ ] Write TL;DR
- [ ] Create per-file diff between `end` and `start` (use "Compare Folders")



# Lecture Title




================================================
FILE: .templates/section.md
================================================
---
name: "Section name here"
---

# Section name here

Description of the section goes here.

================================================
FILE: CONTRIBUTING.md
================================================
# How to contribute to this course

## E-book contributions

### How to run the e-book

Clone the repo and navigate to the `docs` folder.

There, run:

```
npm install
```

Then you can run the e-book with:

```
npm run start
```

If you make any changes to the e-book, please keep changes as simple as possible and create a PR with your changes into the `develop` branch.

If you are making larger changes, please create a Discussion first and let's talk about it!

### Making changes to projects

All the finished projects that we cover in the course are in the `projects` folder. Making changes to these projects is done very carefully, especially after recording.

Please start a Discussion before making any changes, as doing so can make the experience for students confusing (if the videos and e-book are different).


================================================
FILE: README.md
================================================
# REST APIs with Flask and Python

<p align="center">
 <img src="assets/course-image.png" alt="REST APIs with Flask and Python (Udemy banner image)"></a>
</p>

<div align="center">

[![Udemy rating 4.6/5](https://img.shields.io/badge/udemy-4.6%2F5-brightgreen)](https://go.tecla.do/rest-apis-ebook) ![GitHub last commit](https://img.shields.io/github/last-commit/tecladocode/rest-apis-flask-python/develop) ![Python 3.10](https://img.shields.io/badge/python-3.10-yellow) [![Discord](https://img.shields.io/discord/614395983807250433)](https://discord.gg/78Nvd3p) [![Twitter Follow](https://img.shields.io/twitter/follow/jslvtr?style=social) ](https://twitter.com/jslvtr)

</div>

---

<p align = "center">💡 A full course to teach you how to use Flask and Python to make REST APIs using multiple Flask extensions and PostgreSQL.</p>

## Getting started

Enrol in the course by going to [this link](https://go.tecla.do/rest-apis-ebook).

Then you can come back here to download the repository. This repository contains the code that we develop in each section of the course.

If you are familiar with Git, you can use Git to download it. Otherwise, you can download it as a zip file:

![Download repo as a zip file](assets/download-repo-zip.png)

Next, start taking the course at the beginning! You can use the downloaded code files to support you while you go through the course.

I also **strongly recommend** you code while you take the course. A good strategy is:

1. Watch the video intently, optionally while taking notes.
2. Watch again, more quickly, while typing the code together with me.
3. Once you're done with the video, play about with the code. Make changes, break things, then fix them, and try to thoroughly understand everything the code does.

If you do this for the entire course, I guarantee you will learn how to make REST APIs using Flask and Python well and quickly. You'll still be using Google and searching for stuff every day, but so does everyone else!

## Section 2: A Full Python Refresher

This section (only available on Udemy) helps programmers who are new to Python get acquainted with the language. It is not a complete-beginner Python course!

## Section 3: Your first REST API

The code in this section includes a simple Flask app that accepts and returns JSON data.

## Section 4: Docker

Introduction to Docker to run your REST APIs. We talk about images, containers, and how to run applications.

## Section 5: Flask-Smorest

We introduce the Flask-Smorest extension, a library that greatly simplifies writing REST APIs using Flask. It also provides things like automated documentation generation.

## Section 6: Flask-SQLAlchemy

The code in this section extends the previous section by replacing the data storage in Python lists with SQLAlchemy, an ORM (Object-Relational Mapping which simplifies connecting to and interacting with a database.

## Section 7: Many-to-many relationships

In this section we talk about many-to-many relationships using SQLAlchemy.

## Section 8: Authentication with Flask-JWT-Extended

Learn how to perform user authentication using JWTs and the Flask-JWT-Extended library. Here we talk about access token JWTs, as well as refresh tokens, JWT claims, blocklists, password hashing, and more.

## Section 9: Flask-Migrate

After deploying your apps, making changes to the database can be really tricky because you have to log in to the database server and manually update the database tables using SQL commands.

Flask-Migrate and the Alembic libraries simplify this job by creating migration scripts.

## Section 10: Git Crash Course

A quick and intense course on Git and GitHub for code sharing.

## Section 11: Deploying to Render.com

Learn how to get your code running in the cloud and make it publicly accessible. In this section we use Render.com for deployments and we also deploy a PostgreSQL database.

================================================
FILE: dependabot.yml
================================================
version: 2
updates:
  - package-ecosystem: "npm"
    directory: "/docs"
    schedule:
      interval: "weekly"
      # Check for npm updates on Sundays
      day: "sunday"
    target-branch: "develop"
    # Labels on pull requests for security and version updates
    labels:
      - "npm dependencies"


================================================
FILE: docs/.gitignore
================================================
# Dependencies
/node_modules

# Production
/build

# Generated files
.docusaurus
.cache-loader

# Misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*


================================================
FILE: docs/README.md
================================================
# Website

This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator.

### Installation

```
$ npm install
```

### Local Development

```
$ npm run start
```

This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.

### Build

```
$ npm run build
```

This command generates static content into the `build` directory and can be served using any static contents hosting service.

### Deployment

Using SSH:

```
$ USE_SSH=true npm run deploy
```

Not using SSH:

```
$ GIT_USER=<Your GitHub username> npm run deploy
```

If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.


================================================
FILE: docs/algolia.config.json
================================================
{
    "index_name": "docusaurus-2",
    "start_urls": [
        "https://rest-apis-flask.teclado.com/"
    ],
    "sitemap_urls": [
        "https://rest-apis-flask.teclado.com/sitemap.xml"
    ],
    "sitemap_alternate_links": true,
    "stop_urls": [
        "/tests"
    ],
    "selectors": {
        "lvl0": {
        "selector": "(//ul[contains(@class,'menu__list')]//a[contains(@class, 'menu__link menu__link--sublist menu__link--active')]/text() | //nav[contains(@class, 'navbar')]//a[contains(@class, 'navbar__link--active')]/text())[last()]",
        "type": "xpath",
        "global": true,
        "default_value": "Documentation"
        },
        "lvl1": "header h1",
        "lvl2": "article h2",
        "lvl3": "article h3",
        "lvl4": "article h4",
        "lvl5": "article h5, article td:first-child",
        "lvl6": "article h6",
        "text": "article p, article pre, article li, article td:last-child"
    },
    "strip_chars": " .,;:#",
    "custom_settings": {
        "separatorsToIndex": "_",
        "attributesForFaceting": [
        "language",
        "version",
        "type",
        "docusaurus_tag"
        ],
        "attributesToRetrieve": [
        "hierarchy",
        "content",
        "anchor",
        "url",
        "url_without_anchor",
        "type"
        ]
    },
    "conversation_id": [
        "833762294"
    ]
}

================================================
FILE: docs/babel.config.js
================================================
module.exports = {
  presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
};


================================================
FILE: docs/docs/01_course_intro/02_how_to_install_python/README.md
================================================
---
title: How to install Python
description: A brief description of the lecture goes here.
ctslug: how-to-install-python
---

# How to install Python on your computer

In this lecture I'll guide you through installing Python on your computer. If have already installed Python, feel free to skip to the next lecture!

## On Windows

To install Python, download the latest version of Python  from https://www.python.org. At the time of writing, that was Python 3.10.4.

:::caution Add to PATH
As you go through the installer, make sure to check "Add Python to PATH".
:::

Once Python is installed, you can execute the program `cmd.exe`. This is a command-line interface to your computer. Here, just type the word `python` and that will start the Python program.

At all points during the course, you can always type `python name_of_file.py` and that will execute the code of a file called `name_of_file.py`

If you have multiple versions of Python installed, such as a version you installed a while ago, you'll need to use the complete path to Python in order to run it. Usually it'll look something like this:

```
C:\\Users\\yourname\\AppData\\Local\\Programs\\Python\\Python39-32\\python.exe
```

When you use an IDE, such as [Visual Studio Code](../how_to_install_ide/), you can use the integrated terminal instead of `cmd.exe`.

## On Mac

To install Python, download the latest version of Python  from https://www.python.org. At the time of writing, that was Python 3.10.4.

Once Python is installed, you can execute the program `Terminal.app`. This is a command-line interface to your computer. Here, just type the word `python3.9` and that will start the Python program.

At all points during the course, you can always type `python3.9 name_of_file.py` and that will execute the code of a file called `name_of_file.py`.

================================================
FILE: docs/docs/01_course_intro/03_how_to_install_ide/README.md
================================================
---
title: How to install an IDE
description: What IDE should you use? How do you install it? Let me show you in this quick guide.
ctslug: how-to-install-an-ide
---

# How to install an IDE

An IDE is an Integrated Development Environment. If you've got experience coding, I'm sure you've used an IDE at some point or another.

IDEs are text editors that let you modify your code. However, as the name says, they do a bit more than just that.

Often we can use IDEs to run our code, connect to databases, use a debugger, or a whole host of other things!

Throughout this course I use Visual Studio Code. It's a very powerful IDE that you can get for free at https://code.visualstudio.com/. If you get VS Code, I've got a blog post on how to set it up for Python development: https://blog.tecladocode.com/how-to-set-up-visual-studio-code-for-python-development/

## Opening Projects

Whenever you work using an IDE, you should open separate projects in separate windows:

- 👍 When you start a section of the course, make a folder for that section and open it with VSCode. Now VSCode treats that as a "project" folder.
- 👎 Make a folder for the entire course and open it with VSCode. Inside it, make a folder for each section. VSCode will treat the top-level course folder as the "project", and your experience will be a bit more difficult.

I've noticed some students like opening their "projects" folder with the IDE, so that they can work on all their projects in one window. This is likely to cause problems due to how Python looks for code files to use and import (more on that when you get to the "Imports" section of the Python Refresher!).

So don't be afraid to have many different project folders, each one with their own virtual environment and dependencies. That's normal and will make it much easier to work with!

================================================
FILE: docs/docs/01_course_intro/04_what_is_rest_api/README.md
================================================
---
title: "What is a REST API?"
description: "There's a lot of confusion around what is and isn't a REST API. Let's take a look!"
ctslug: what-is-an-rest-api
---

# What is a REST API?

## What is an API?

API stands for "Application Programming Interface", but that's not an overly helpful name!

The most important part of the term is "Interface". Just as the interface to a car is the parts we humans interact with (steering wheel, pedals, gear stick), the interface to an application is the code that another application can interact with.

This way, any part of an application that can be "called" or "executed" from another application, is part of that application's API.

For example, let's say you make a simple Python library to save data to a database. This is what the library looks like:

```py
def save_to_db(what_to_save):
    pass


def get_from_db(query):
    pass
```

Assume that the functions are implemented and they do something!

This "library" has an API: the `save_to_db` and `get_from_db` functions. These are the functions that the library makes available to other programs (or parts of programs), which those other programs should use to save and get data from a database.

If you look at it this way, almost everything in programming has at least an "interface".

As another example, when you code a class, it has an interface: the public attributes and methods.

So the key to an API is that it has to be publicly callable, and it allows the _client_ (whoever calls it) to interact with the program that offers the API.

### An API with Flask

When we make Flask apps, we also have some public functions that can be called. Our public functions are each associated to an endpoint, such as `/store`.

That way a client (such as another Python program, or even a web browser) can access the `/store` endpoint of our application, and we can run some code and return a value.

If our Flask app is hosted at `http://my-flask-app.com`, then accessing `http://my-flask-app.com/store` would execute the function associated with the `/store` endpoint in our app, and the client would receive the data returned by the associated function.

That data might look like this:

```json
{
    "stores": [
        {
            "name": "My Store",
            "items": [
                {
                    "name": "my item",
                    "price": 15.99
                }
            ]
        }
    ]
}
```

### The purpose of APIs

We've learned that we can make a Flask app and expose certain functions to the public by using endpoints. Clients can then make requests (we'll learn how later), and get data.

Clients can also send data, which the Flask functions can use.

But _why_? If you want to use certain functions, why not just code them in your application?

There's one main reason: so two or more clients can use the API without having to duplicate the logic that the API offers inside their own code.

Let's say you want to build a weather app.

You could try to install sensors at the top of your house, connect them directly to the computer running your code, and then offer weather info based on what the sensors say...

Or you could request weather data from the OpenWeatherMap API, just as tens of thousands of other devices do.

Much easier, and all you have to do is make a request to the API!

### What is a client?

An API client can be any device, such as a web app or a mobile app.

### Making an API for your own consumption

Many software companies make APIs that only they use (so they aren't fully public).

Here's an example. You're making a multiplayer mobile game, and you need to store information about the moves that your character is making.

In your mobile app code, you could connect to a central database and store the moves there. Apps in other mobile devices would also connect to the central database and store (and read) the moves from there.

But what happens when you want to expand your app to other devices? Let's say, iOS and Android?

Then you've got to duplicate your database logic in two places: the two app codebases. The problem is compounded if you want to expand to computers, consoles, etc.

It's easier to have an API which exposes certain functions that let your app save and retrieve data from a database, and have all your devices use that same API.

It will be much simpler, and when you want to make database changes you most likely won't have to change the code of each mobile app.

## What is REST?

Now that you know what an API is, a slightly more difficult question to answer is "What is a REST API?".

A REST API is just an API that follows specific conventions and has specific characteristics.

REST APIs deal in resources, so every individual "thing" that can be named is a resource. For example, stores, items, tags, users, or less concrete things like temporal services or collections of other resources.

The main characteristics (or constraints) of a REST API are:

1. **Uniform interface**. Whichever way clients should access a certain resource should also be the way the access other resources. Clients should have a single way to retrieve resources.
2. **Client-server**. Clients should know the endpoints of the API, but they should not be coupled to the development of the API. A client or a server may be swapped out for a different implementation without the other noticing.
3. **Stateless**. The server (API) doesn't store anything about previous client requests. Each client request is treated as a brand new client. If the client needs the server to personalize the response, then the client must send the server whatever information the server needs in order to do so.
4. **Cacheable**. The client or server must be able to cache the resources returned by the API. This is a very general constraint, but it's an important one.
5. **Layered system**. REST APIs may be developed as multiple layers, where each layer interacts [only with the layer above and below it](https://excalidraw.com/#json=or3Umoigss4yIeuKg3cO8,qH6uDDCXc7DSjweqNvlmzw).

If you'd like to read a very complete and exhaustive guide about everything that a REST API is, check out [this guide](https://restfulapi.net/).

## The API we'll build in this course

In this course we'll build a REST API to expose interactions with stores, items, tags, and users. The API will allow clients to:

- Create and retrieve information about stores.
- Create, retrieve, search for, update, and delete items in those stores.
- Create tags and link them to items; and search for items with specific tags.
- Add user authentication to the client apps using the API.

The API will have the endpoints shown below.

:::info What do the locks mean?
It's usually important in APIs that only certain people have access to certain endpoints. For example, paying customers may have access to certain endpoints while free users may not.

We'll deal with user authentication in a later section, but that's what the locks (🔒) mean below.

- One 🔒 means the user will need to have authenticated within the last few days to make a request.
- Two 🔒🔒 means the user will need to have authenticated within the last few minutes to make a request.
- No locks means anybody can make a request.
:::

### Users

| Method         | Endpoint          | Description                                           |
| -------------- | ----------------- | ----------------------------------------------------- |
| `POST`         | `/register`       | Create user accounts given an `email` and `password`. |
| `POST`         | `/login`          | Get a JWT given an `email` and `password`.            |
| 🔒 <br/> `POST` | `/logout`         | Revoke a JWT.                                         |
| 🔒 <br/> `POST` | `/refresh`        | Get a fresh JWT given a refresh JWT.                  |
| `GET`          | `/user/{user_id}` | (dev-only) Get info about a user given their ID.      |
| `DELETE`       | `/user/{user_id}` | (dev-only) Delete a user given their ID.              |


### Stores

| Method   | Endpoint      | Description                              |
| -------- | ------------- | ---------------------------------------- |
| `GET`    | `/store`      | Get a list of all stores.                |
| `POST`   | `/store`      | Create a store.                          |
| `GET`    | `/store/{id}` | Get a single store, given its unique id. |
| `DELETE` | `/store/{id}` | Delete a store, given its unique id.     |

### Items

| Method           | Endpoint     | Description                                                                                         |
| ---------------- | ------------ | --------------------------------------------------------------------------------------------------- |
| 🔒 <br/> `GET`    | `/item`      | Get a list of all items in all stores.                                                              |
| 🔒🔒 <br/> `POST`  | `/item`      | Create a new item, given its name and price in the body of the request.                             |
| 🔒 <br/> `GET`    | `/item/{id}` | Get information about a specific item, given its unique id.                                         |
| `PUT`            | `/item/{id}` | Update an item given its unique id. The item name or price can be given in the body of the request. |
| 🔒 <br/> `DELETE` | `/item/{id}` | Delete an item given its unique id.                                                                 |

### Tags

| Method   | Endpoint              | Description                                             |
| -------- | --------------------- | ------------------------------------------------------- |
| `GET`    | `/store/{id}/tag`     | Get a list of tags in a store.                          |
| `POST`   | `/store/{id}/tag`     | Create a new tag.                                       |
| `POST`   | `/item/{id}/tag/{id}` | Link an item in a store with a tag from the same store. |
| `DELETE` | `/item/{id}/tag/{id}` | Unlink a tag from an item.                              |
| `GET`    | `/tag/{id}`           | Get information about a tag given its unique id.        |
| `DELETE` | `/tag/{id}`           | Delete a tag, which must have no associated items.      |

As you can see, we've got a lot to build!

We'll start building REST APIs in section 3, "Your first REST API". Here we'll create a simpler version of the REST API detailed above, without tags or user authentication.

Then, over the following sections, we'll improve on this REST API. We'll add:

- Flask extensions to simplify our code.
- Use Docker to run the API more reliably.
- Use PostgreSQL for data storage.
- Add user authentication.
- Add item tagging.
- Add an admin panel so changing data manually is a bit easier.
- And much more!


================================================
FILE: docs/docs/01_course_intro/_category_.json
================================================
{
    "label": "Course Introduction",
    "position": 1
}


================================================
FILE: docs/docs/01_course_intro/index.md
================================================
---
id: intro
---

# REST APIs with Flask and Python

import VideoEmbed from "@site/src/components/VideoEmbed";

<div style={{ maxWidth: "720px", margin: "3rem auto", boxShadow: "0 5px 15px 0 rgba(0, 0, 0, 0.15)" }}>
<VideoEmbed url="https://customer-zmitazl0ztnd2pvm.cloudflarestream.com/1c4db6119cf0c6e682a88a737af146eb/iframe?poster=https%3A%2F%2Fcustomer-zmitazl0ztnd2pvm.cloudflarestream.com%2F1c4db6119cf0c6e682a88a737af146eb%2Fthumbnails%2Fthumbnail.jpg%3Ftime%3D%26height%3D600" />
</div>

Hi, and welcome!

REST APIs with Flask and Python is a complete course that teaches you how to develop complete, professional REST APIs using **Flask**, **PostgreSQL**, and **Docker**.

In this website you can find the complete course notes and code. We made this to help students navigate the course more easily. Also, every single piece of code we write in the course is in the notes, with brief explanations.

We've found that really helps review the course content later on!

This is how we recommend taking the course:

- Start at the first section of the course, and watch the videos. If you're comfortable, watch them in 1.25x or 1.5x speed! This will help you understand the content holistically.
- Then, re-watch the videos slowly while coding together with me. Write every piece of code by hand, just as you see it in the videos. By the time you're done with a section, after writing all the code, you'll be very comfortable with all the content in it.
- Move onto the next section, but keep the code from each section in a different folder. That way you can then look at the full project as it was at the end of each section, and that will help you review!

I promise that if you follow this approach, you will master the content of this course within a few weeks. And you'll soon be able to code complete REST APIs using Flask and Python!

:::tip Note-taking not required
Feel free to take notes while you go through the course, but you don't need to!

This very website is a perfect set of notes for you to come back to weeks, months, or even years down the line to review what you learned in the course (and, let's be honest, find those snippets of code that you can just copy into your projects).
:::

## Course Set-up and Housekeeping

Below are some quick guides to get you started. Feel free to read through them if you need, or skip them!

After this, we have a [Python Refresher](../02_python_refresher/index.md). If you are very comfortable with Python, feel free to skip that too!

If you're skipping the Python Refresher, move onto Your First REST API.

I'll see you there!

import DocCardList from '@theme/DocCardList';
import {useCurrentSidebarCategory} from '@docusaurus/theme-common';

<DocCardList items={useCurrentSidebarCategory().items}/>


================================================
FILE: docs/docs/02_python_refresher/_category_.json
================================================
{
    "label": "Python Refresher",
    "position": 2
}


================================================
FILE: docs/docs/02_python_refresher/index.md
================================================
---
name: "A Complete Python Refresher"
---

# Python Refresher

We've included a Python Refresher section in this course to help you, in case you haven't done any Python for a while or you are coming from a different programming language.

There are no written notes for this section, but all the videos are available in the Udemy course.

If you are fully new to programming _and_ Python, this course may be a bit advanced. Feel free to read through out beginner Python e-book anyway, as it might be helpful: [https://python.tecladocode.com](https://python.tecladocode.com).


================================================
FILE: docs/docs/03_first_rest_api/01_project_overview/README.md
================================================
---
title: Project Overview
description: A first look at the project we'll build in this section.
ctslug: overview-of-your-first-rest-api
---

# Overview of your first REST API

import VideoEmbed from "@site/src/components/VideoEmbed";

<div style={{ maxWidth: "720px", margin: "3rem auto", boxShadow: "0 5px 15px 0 rgba(0, 0, 0, 0.15)" }}>
<VideoEmbed url="https://customer-zmitazl0ztnd2pvm.cloudflarestream.com/cda9c0473bdc485a36905144f13f4d3f/iframe?poster=https%3A%2F%2Fcustomer-zmitazl0ztnd2pvm.cloudflarestream.com%2Fcda9c0473bdc485a36905144f13f4d3f%2Fthumbnails%2Fthumbnail.jpg%3Ftime%3D%26height%3D600" />
</div>

In this section we'll make a simple REST API that allows us to:

- Create stores, each with a `name` and a list of stocked `items`.
- Create an item within a store, each with a `name` and a `price`.
- Retrieve a list of all stores and their items.
- Given its `name`, retrieve an individual store and all its items.
- Given a store `name`, retrieve only a list of item within it.

This is how the interaction will go!

:::tip Insomnia files
Remember to get the Insomnia files for this section or for all sections [here](/insomnia-files/)!
:::

## Create stores

Request:

```
POST /store {"name": "My Store"}
```

Response:

```
{"name": "My Store", "items": []}
```

## Create items

Request:

```
POST /store/My Store/item {"name": "Chair", "price": 175.50}
```

Response:

```
{"name": "Chair", "price": 175.50}
```

## Retrieve all stores and their items

Request:

```
GET /store
```

Response:

```
{
    "stores": [
        {
            "name": "My Store",
            "items": [
                {
                    "name": "Chair",
                    "price": 175.50
                }
            ]
        }
    ]
}
```

## Get a particular store

Request:

```
GET /store/My Store
```

Response:

```
{
    "name": "My Store",
    "items": [
        {
            "name": "Chair",
            "price": 175.50
        }
    ]
}
```

## Get only items in a store

Request:

```
GET /store/My Store/item
```

Response:

```
[
    {
        "name": "Chair",
        "price": 175.50
    }
]
```

================================================
FILE: docs/docs/03_first_rest_api/02_getting_set_up/README.md
================================================
---
title: Getting set up
description: Set up a Flask project and create the Flask app.
ctslug: getting-set-up
---

# Getting set up

import VideoEmbed from "@site/src/components/VideoEmbed";

<div style={{ maxWidth: "720px", margin: "3rem auto", boxShadow: "0 5px 15px 0 rgba(0, 0, 0, 0.15)" }}>
<VideoEmbed url="https://customer-zmitazl0ztnd2pvm.cloudflarestream.com/42b7de55034431b4c4c9420460f8df7d/iframe?poster=https%3A%2F%2Fcustomer-zmitazl0ztnd2pvm.cloudflarestream.com%2F42b7de55034431b4c4c9420460f8df7d%2Fthumbnails%2Fthumbnail.jpg%3Ftime%3D%26height%3D600" />
</div>

Create a virtual environment and activate it.
   
```
python3.10 -m venv .venv
source .venv/bin/activate
```

Install Flask.
   
```
pip install flask
```

Create a file for the Flask app (I like to call it `app.py`)
Create the Flask app.

```py title="app.py"
from flask import Flask

app = Flask(__name__)
```

Now you can run this app using the Flask Command-Line Interface (CLI):

```
flask run
```

But the app doesn't do anything yet! Let's work on our first API endpoint next.

================================================
FILE: docs/docs/03_first_rest_api/03_first_rest_api_endpoint/README.md
================================================
---
title: Your First REST API Endpoint
description: Learn how to define a REST API endpoint using Flask.
ctslug: your-first-rest-api-endpoint
---

# Your First REST API Endpoint

import LockedVideoEmbed from "@site/src/components/LockedVideoEmbed";

<LockedVideoEmbed />

Let's start off by defining where we'll store our data. In most REST APIs, you'd store your data in a database. For now, and for simplicity, we'll store it in a Python list.

Later on we'll work on making this data dynamic. For now let's use some sample data.

```py title="app.py"
from flask import Flask

app = Flask(__name__)

stores = [{"name": "My Store", "items": [{"name": "my item", "price": 15.99}]}]
```

Now that we've got the data stored, we can go ahead and make a Flask route that, when accessed, will return all our data.

```py title="app.py"
from flask import Flask

app = Flask(__name__)

stores = [{"name": "My Store", "items": [{"name": "my item", "price": 15.99}]}]


@app.get("/store")
def get_stores():
    return {"stores": stores}
```

## Anatomy of a Flask route

There are two parts to a Flask route:

- The endpoint decorator
- The function that should run

The endpoint decorator (`@app.get("/store")`) _registers_ the route's endpoint with Flask. That's the `/store` bit. That way, the Flask app knows that when it receives a request for `/store`, it should run the function.

The function's job is to do everything that it should, and at the end return _something_. In most REST APIs, we return JSON, but you can return anything that can be represented as text (e.g. XML, HTML, YAML, plain text, or almost anything else).

================================================
FILE: docs/docs/03_first_rest_api/04_what_is_json/README.md
================================================
---
title: "What is JSON?"
description: JSON is the way we normally transfer data to and from REST APIs.
ctslug: what-is-json
---

# What is JSON?

JSON is just a (usually long) string whose contents follow a specific format.

One example of JSON:

```json
{
    "key": "value",
    "another": 25,
    "listic_data": [
        1,
        3,
        7
    ],
    "sub_objects": {
        "name": "Rolf",
        "age": 25
    }
}
```

So at its core, you've got:

- Strings
- Numbers
- Booleans (`true` or `false`)
- Lists
- Objects (akin to dictionaries in Python)
  - Note that objects are not ordered, so the keys could come back in any order. This is not a problem!

At the top level of a piece of JSON you can have an object or a list. So this is also valid JSON:

```json
[
    {
        "name": "Rolf",
        "age": 25
    },
    {
        "name": "Anne",
        "age": 27
    },
    {
        "name": "Adam",
        "age": 23
    }
]
```

When we return a Python dictionary in a Flask route, Flask automatically turns it into JSON for us, so we don't have to.

Remember that "turning it into JSON" means two things:

1. Change Python keywords and values so they match the JSON standard (e.g. `True` to `true`).
2. Turn the whole thing into a single string that our API can return.

:::tip
Note that JSON can be "prettified" (as the above examples), although usually it is returned by our API "not-prettified":

```json
[{"name":"Rolf","age":25},{"name":"Anne","age":27},{"name":"Adam","age":23}]
```

This removal of newlines and spaces, believe it or not, adds up and can save a lot of bandwidth since there is less data to transfer between the API server and the client.
:::

================================================
FILE: docs/docs/03_first_rest_api/05_make_request_to_rest_api/README.md
================================================
---
title: How to interact with your REST API
description: Use Postman and Insomnia REST Client to interact with your REST API.
ctslug: how-to-interact-with-your-rest-api
---

# How to make a request to a REST API

One of the most important things about any software development is to make sure that our projects work!

So we need to be able to test our project, run it, and make sure it does what we think it does.

There are two main ways of doing this:

- With automated tests.
- With manual, exploratory testing.

Usually you'd go with exploratory first, and then you'd make automated tests based on your manual tests.

In this course we won't cover automated testing of your REST API (it's a long topic, and we've got another course on it).

However, we will cover a lot of things you can do with manual testing.

There are two tools I use for exploratory testing: Postman and Insomnia. It's up to you which one to use, but if you haven't used either one before, I recommend Insomnia.

It's a bit easier to get started with, and it's free and open source.

Start by [downloading Insomnia REST Client](https://insomnia.rest/).

Once you've opened it, create a Project. I would call it "REST APIs with Flask and Python".

![Creating the Project for this course](https://res.cloudinary.com/teclado/image/upload/v1689180715/courses/rest-apis-flask-python/creating-project_qsyxlg.png)

Then, create a new Request Collection. Call it "Stores REST API".

![Creating the Stores REST API Request Collection](https://res.cloudinary.com/teclado/image/upload/v1689180710/courses/rest-apis-flask-python/making-request-collection_lcthlv.png)

In the Request Collection, we can now add requests! Each request has a few parts:

- A **method**, such as `GET` or `POST`. The method is just a piece of data sent to the server, but _usually_ certain methods are used for certain things.
- The **URL** that you want to request. For our API, this is formed of the "Base URL" (for Flask apps, that's `http://127.0.0.1:5000`), and the endpoint (e.g. `/store`).
- The **body**, or any data that you want to send in the request. For example, when creating stores or items we might send some data.
- The **headers**, which are other pieces of data with specific names, that the server can use. For example, a header might be sent to help the server understand _who_ is making the request.

Let's create our first request, `GET /store`.

Make a new request using the Insomnia interface. First, use the dropdown to start:

![How to make a request using the Insomnia interface](https://res.cloudinary.com/teclado/image/upload/v1689180711/courses/rest-apis-flask-python/making-request_hmiptl.png)

Then enter the request name. Leave the method as `GET`:

![Enter the request name and method](https://res.cloudinary.com/teclado/image/upload/v1689180712/courses/rest-apis-flask-python/set-request-name-and-method_bc6smy.png)

Once you're done, you will see your request in the collection:

![The request is shown in the collection](https://res.cloudinary.com/teclado/image/upload/v1689180711/courses/rest-apis-flask-python/before-setting-url_qjxvyr.png)

Next up, enter the URL for your request. Here we will be requesting the `/store` endpoint. Remember to include your Base URL as well:

![Entering the full URL for the request in Insomnia](https://res.cloudinary.com/teclado/image/upload/v1689180714/courses/rest-apis-flask-python/url-set_fgp9s9.png)

Once you're done, make sure that your Flask app is running! If it isn't, remember to activate your virtual environment first and then run the app:

```
source .venv/bin/activate
flask run
```

:::caution
The Flask app will run, by default, on port 5000. If you have another (or the same) app already running, you'll get an error because the port will be "busy".

If you get an error, read it carefully and make sure that no other Flask app is running on the same port.
:::

Once your Flask app is running, you can hit "Send" on the Insomnia client, and you should see the JSON come back from your API!

![Making a request to our API using Insomnia](https://res.cloudinary.com/teclado/image/upload/v1689180712/courses/rest-apis-flask-python/after-pressing-send_okjkjq.png)

If that worked and you can see your JSON, you're good to go! You've made your first API request. Now we can continue developing our REST API, remembering to always create new Requests in Insomnia and test our code as we go along!

================================================
FILE: docs/docs/03_first_rest_api/06_creating_stores/README.md
================================================
---
title: How to create stores
description: Learn how to add data to our REST API.
ctslug: how-to-create-stores
---

# How to create stores in our REST API

To create a store, we'll receive JSON from our client (in our case, Insomnia, but it could be another Python app, JavaScript, or any other language or tool).

Our client will send us the name of the store they want to create, and we will add it to the database!

For this, we will use a `POST` method. `POST` is usually used to receive data from clients and either use it, or create resources with it.

In order to access the JSON body of a request, we will need to import `request` from `flask`. Your import list should now look like this:

```py
from flask import Flask, request
```

Then, create your endpoint:

```py title="app.py"
# highlight-start
from flask import Flask, request
# highlight-end

app = Flask(__name__)

stores = [{"name": "My Store", "items": [{"name": "my item", "price": 15.99}]}]


@app.get("/store")
def get_stores():
    return {"stores": stores}


# highlight-start
@app.post("/store")
def create_store():
    request_data = request.get_json()
    new_store = {"name": request_data["name"], "items": []}
    stores.append(new_store)
    return new_store, 201
# highlight-end
```

Here we use `request.get_json()` to retrieve the JSON content of our request.

Then we create a new dictionary that represents our store. It has a `name` and `items` (which is an empty list).

Then we append this store to our `stores` list.

Finally we return the newly created `store`. It's empty, but it serves as a **success message**, to tell our client that we have successfully created what they wanted us to create.

:::tip Returning a status code
Every response has a status code, which tells the client if the server was successful or not. You already know at least one status code: 404. This means "Not found".

The most common status code is `200`, which means "OK". That's what Flask returns by default, such as in the `get_stores()` function.

If we want to return a different status code using Flask, we can put it as the second value returned by an endpoint function. In `create_store()`, we are returning the code `201`, which means "Created".
:::

================================================
FILE: docs/docs/03_first_rest_api/07_creating_items/README.md
================================================
---
title: How to create items in each store
description: A brief description of the lecture goes here.
ctslug: how-to-create-items-in-each-store
---

# How to create items in our REST API

Next up, let's work on adding items to a store!

Here's how that's going to work:

1. The client will send us the store name where they want their new item to go.
2. They will also send us the name and price of the new item.
3. We'll go through the stores one at a time, until we find the correct one (whose name matches what the user gave us).
4. We'll append a new item dictionary to that store's `items`.

## URL parameters

There are a few ways for clients to send us data. So far, we've seen that clients can send us JSON.

But data can be included in a few other places:

- The body (as JSON, form data, plain text, or a variety of other formats).
- Inside the URL, part of it can be dynamic.
- At the end of the URL, as _query string arguments_.
- In the request headers.

For this request, the client will send us data in two of these at the same time: the body and the URL.

How does a dynamic URL look like?

Here's a couple examples:

- `/store/My Store/item`
- `/store/another-store/item`
- `/store/a/item`

In those three URLs, the "store name" was:

- `My Store`
- `another-store`
- `a`

We can use Flask to define dynamic endpoints for our routes, and then we can grab the value that the client put inside the URL.

This allows us to make URLs that make interacting with them more natural.

For example, it's nicer to make an item by going to `POST /store/My Store/item`, rather than going to `POST /add-item` and then pass in the store name in the JSON body.

To create a dynamic endpoint for our route, we do this:

```py
@app.route("/store/<string:name>/item")
```

That makes it so the route function will use a `name` parameter whose value will be what the client put in that part of the URL.

Without further ado, let's make our route for creating items within a store!

```py title="app.py"
from flask import Flask, request

app = Flask(__name__)

stores = [{"name": "My Store", "items": [{"name": "my item", "price": 15.99}]}]


@app.get("/store")
def get_stores():
    return {"stores": stores}


@app.post("/store")
def create_store():
    request_data = request.get_json()
    new_store = {"name": request_data["name"], "items": []}
    stores.append(new_store)
    return new_store, 201


# highlight-start
@app.post("/store/<string:name>/item")
def create_item(name):
    request_data = request.get_json()
    for store in stores:
        if store["name"] == name:
            new_item = {"name": request_data["name"], "price": request_data["price"]}
            store["items"].append(new_item)
            return new_item
    return {"message": "Store not found"}, 404
# highlight-end
```

:::tip Not the most efficient way
In this endpoint we're iterating over all stores in our list until we find the right one. This is very inefficient, but we'll look at better ways to do this kind of thing when we look at databases.

For now, focus on Flask, and don't worry about efficiency of our code!
:::

================================================
FILE: docs/docs/03_first_rest_api/08_return_data_from_rest_api/README.md
================================================
---
title: Get a specific store and its items
description: How to use Flask to return data from your REST API to your client.
ctslug: get-a-specific-store-and-its-items
---

# How to get a specific store and its items

The last thing we want to look at in our first REST API is returning data that uses some filtering.

Using URL parameters, we can select a specific store:

```py
@app.get("/store/<string:name>")
def get_store(name):
    for store in stores:
        if store["name"] == name:
            return store
    return {"message": "Store not found"}, 404
```

And just as we did when creating an item in a store, you can use the same endpoint (with a `GET` method), to select the items in a store:

```py
@app.get("/store/<string:name>/item")
def get_item_in_store(name):
    for store in stores:
        if store["name"] == name:
            return {"items": store["items"]}
    return {"message": "Store not found"}, 404
```


================================================
FILE: docs/docs/03_first_rest_api/09_final_code/README.md
================================================
---
title: Final code of this section
description: Overview of the project we've built and all the code in it.
ctslug: final-code-of-this-section
---

# Final code of this section

Here's everything we've written in this section!

```py title="app.py"
from flask import Flask, request

app = Flask(__name__)

stores = [
    {
        "name": "My Store",
        "items": [
            {
                "name": "Chair",
                "price": 15.99
            }
        ]
    }
]

@app.get("/store")
def get_stores():
    return {"stores": stores}


@app.post("/store")
def create_store():
    request_data = request.get_json()
    new_store = {"name": request_data["name"], "items": []}
    stores.append(new_store)
    return new_store, 201


@app.post("/store/<string:name>/item")
def create_item(name):
    request_data = request.get_json()
    for store in stores:
        if store["name"] == name:
            new_item = {"name": request_data["name"], "price": request_data["price"]}
            store["items"].append(new_item)
            return new_item, 201
    return {"message": "Store not found"}, 404


@app.get("/store/<string:name>")
def get_store(name):
    for store in stores:
        if store["name"] == name:
            return store
    return {"message": "Store not found"}, 404


@app.get("/store/<string:name>/item")
def get_item_in_store(name):
    for store in stores:
        if store["name"] == name:
            return {"items": store["items"]}
    return {"message": "Store not found"}, 404
```

================================================
FILE: docs/docs/03_first_rest_api/09_final_code/end/app.py
================================================
from flask import Flask, request

app = Flask(__name__)

stores = [{"name": "My Store", "items": [{"name": "Chair", "price": 15.99}]}]


@app.get("/store")
def get_stores():
    return {"stores": stores}


@app.post("/store")
def create_store():
    request_data = request.get_json()
    new_store = {"name": request_data["name"], "items": []}
    stores.append(new_store)
    return new_store, 201


@app.post("/store/<string:name>/item")
def create_item(name):
    request_data = request.get_json()
    for store in stores:
        if store["name"] == name:
            new_item = {"name": request_data["name"], "price": request_data["price"]}
            store["items"].append(new_item)
            return new_item, 201
    return {"message": "Store not found"}, 404


@app.get("/store/<string:name>")
def get_store(name):
    for store in stores:
        if store["name"] == name:
            return store
    return {"message": "Store not found"}, 404


@app.get("/store/<string:name>/item")
def get_item_in_store(name):
    for store in stores:
        if store["name"] == name:
            return {"items": store["items"]}
    return {"message": "Store not found"}, 404


================================================
FILE: docs/docs/03_first_rest_api/Insomnia_section3.json
================================================
{"_type":"export","__export_format":4,"__export_date":"2022-11-09T15:36:47.360Z","__export_source":"insomnia.desktop.app:v2022.6.0","resources":[{"_id":"req_e15dafc098ac4a2198304d2aead2a5b9","parentId":"fld_8b9c03412d0e463fabe784d205f1d604","modified":1666900815265,"created":1666123912423,"url":"http://127.0.0.1:5000/store/My Store/item","name":"/store/<name>/item Create item in store","description":"","method":"POST","body":{"mimeType":"application/json","text":"{\n\t\"name\": \"Table\",\n\t\"price\": 17.99\n}"},"parameters":[],"headers":[{"name":"Content-Type","value":"application/json"}],"authentication":{},"metaSortKey":-1666124423081,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"fld_8b9c03412d0e463fabe784d205f1d604","parentId":"wrk_6aa19b7d9ecd4f93a3602d257e54a163","modified":1666124528874,"created":1666124528874,"name":"Stores","description":"","environment":{},"environmentPropertyOrder":null,"metaSortKey":-1666124528874,"_type":"request_group"},{"_id":"wrk_6aa19b7d9ecd4f93a3602d257e54a163","parentId":null,"modified":1666991857781,"created":1666122928011,"name":"Section 3","description":"","scope":"collection","_type":"workspace"},{"_id":"req_697ca0714a3d4e94819411e3df0a2a17","parentId":"fld_8b9c03412d0e463fabe784d205f1d604","modified":1666900846590,"created":1666124316888,"url":"http://127.0.0.1:5000/store/My store3/item","name":"/store/<name>/item","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1666124423056,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_9451df3aae714e93a8ed529b3a1f99c2","parentId":"fld_8b9c03412d0e463fabe784d205f1d604","modified":1666124555354,"created":1666122990495,"url":"http://127.0.0.1:5000/store","name":"/store Get all store data","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1666124423031,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_6363c8d4deb74b5bbccb1e2105277dac","parentId":"fld_8b9c03412d0e463fabe784d205f1d604","modified":1666900812784,"created":1666124168137,"url":"http://127.0.0.1:5000/store/My store3","name":"/store/<name>","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1666124422956,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_0a9c4822679b4eae92dec7432fe144b8","parentId":"fld_8b9c03412d0e463fabe784d205f1d604","modified":1666900810115,"created":1666123651275,"url":"http://127.0.0.1:5000/store","name":"/store Create new store","description":"","method":"POST","body":{"mimeType":"application/json","text":"{\n\t\"name\": \"My store3\"\n}"},"parameters":[],"headers":[{"name":"Content-Type","value":"application/json"}],"authentication":{},"metaSortKey":-1666124422881,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"env_19db457230041d88ca9420d1b3c0f1f02bbcae93","parentId":"wrk_6aa19b7d9ecd4f93a3602d257e54a163","modified":1666122928025,"created":1666122928025,"name":"Base Environment","data":{},"dataPropertyOrder":null,"color":null,"isPrivate":false,"metaSortKey":1666122928025,"_type":"environment"},{"_id":"jar_19db457230041d88ca9420d1b3c0f1f02bbcae93","parentId":"wrk_6aa19b7d9ecd4f93a3602d257e54a163","modified":1666122928027,"created":1666122928027,"name":"Default Jar","cookies":[],"_type":"cookie_jar"},{"_id":"spc_c5b803a7c6514ff29573e26487d898d4","parentId":"wrk_6aa19b7d9ecd4f93a3602d257e54a163","modified":1666122928018,"created":1666122928018,"fileName":"Your First REST API","contents":"","contentType":"yaml","_type":"api_spec"}]}

================================================
FILE: docs/docs/03_first_rest_api/_category_.json
================================================
{
    "label": "Your First REST API",
    "position": 3
}


================================================
FILE: docs/docs/04_docker_intro/01_what_is_docker_container/README.md
================================================
---
ctslug: what-is-a-docker-container
description: Learn what Docker images and containers are, and how we can use them to distribute and run our applications.
---

# What are Docker images and containers?

I'm sure you have heard of the term "Virtual Machine". A virtual machine is an emulation of an Operating System. For example, if you run a Windows virtual machine on your MacOS computer, it will run a whole copy of Windows so you can run Windows programs.

This diagram shows what happens in that case:

![Virtual Machine Diagram stack](https://res.cloudinary.com/teclado/image/upload/v1689180716/courses/rest-apis-flask-python/vm.drawio_nlrxmx.png)

When you run a Virtual Machine, you can configure what hardware it has access to (e.g. 50% of the host's RAM, 2 CPU cores, etc).

Docker containers are a bit different because they don't emulate an Operating System. They use the Operating System kernel of your computer, and run as a process within the host.

Containers have their own storage and networking, but because they don't have to emulate the operating system and everything that entails, they are much more lightweight.

This diagram shows how Linux containers run in a Linux host:

![Docker Diagram stack](https://res.cloudinary.com/teclado/image/upload/v1689180716/courses/rest-apis-flask-python/docker-linux.drawio_ebvff5.png)

Looks similar, but the `docker -> container` section is much more efficient than running a VM because it **uses the host's kernel** instead of running its own.

## What is a kernel? 🍿

An Operating System is made up of two main parts:

- The **kernel**
- Files and programs that come with the operating system

The Linux kernel, for example, is used by all Linux Operating Systems (like Ubuntu, Fedora, Debian, etc.).

:::caution
Since containers use the host's kernel, you can't run a Windows Docker container natively in a MacOS host. Similarly, you can't run a Linux container natively on Windows or MacOS hosts.
:::

## How to run Linux containers on Windows or MacOS?

When you use Docker Desktop (which I'll show you in the next lecture), it runs a Linux Virtual Machine for you, which then is used to run your Linux containers.

But aren't you then doing this?

```
hardware -> macos -> hypervisor -> linux vm -> docker -> container -> container program
```

And isn't that much less efficient than just running the program in a Linux virtual machine?

Yes. Running Linux containers on MacOS or Windows is "worse" than just running the programs in a Linux VM. However, **99% of the time, you will be running Linux containers in a Linux host, which is much more efficient**.

:::tip Why do we always run Linux containers in a Linux host?
When you want to deploy your applications to share them with your users, you will almost always be running your app in a Linux server (provided by a _deployment company_, more on that later). There are a few reasons for this. Among them, Linux is free!
:::

## Why are containers more efficient than VMs?

From now on let's assume we are running native Linux containers in a Linux host, as that is by far the most common thing to do!

When you run a VM, it runs the entire operating system. However, when you run a container it uses part of the host's Operating System (called the kernel). Since the kernel is already running anyway, there is much less work for Docker to do.

As a result, containers start up faster, use fewer resources, and need much less hard disk space to run.

## Can you run an Ubuntu image when the host is Linux but not Ubuntu?

Since the Linux kernel is the same between distributions, and since Docker containers only use the host's kernel, it doesn't matter which distribution you are running as a host. You can run containers of any distribution with any other distribution as a host.

## How many containers can you run at once?

Each container uses layers to specify what files and programs they need. For example, if you run two containers which both use the same version of Python, you'll actually only need to store that Python executable once. Docker will take care of sharing the data between containers.

This is why you can run many hundreds of containers in a single host, because there is less duplication of files they use compared to virtual machines.

## What does a Docker container run?

If you want to run your Flask app in a Docker container, you need to get (or create) a Docker image that has all the dependencies your Flask app uses, except from the OS kernel:

- Python
- Dependencies from `requirements.txt`
- Possibly `nginx` or `gunicorn` (more on this when we talk about deployment)

:::info Aren't there more dependencies?
The keen-eyed among you may be thinking: if all you have is the kernel and nothing else, aren't there more dependencies?

For example, Python _needs_ the C programming language to run. So shouldn't we need C in our container also?

Yes!

When we build our Docker image, we will be building it _on top of_ other, pre-built, existing images. Those images come with the lower-level requirements such as compilers, the C language, and most utilities and programs we need.
:::

## What is a Docker image?

A Docker image is a snapshot of source code, libraries, dependencies, tools, and everything else (except the Operating System kernel!) that a container needs to run.

There are many pre-built images that you can use. For example, some come with Ubuntu (a Linux distribution). Others come with Ubuntu and Python already installed. You can also make your own images that already have Flask installed (as well as other dependencies your app needs).

:::info Comes with Ubuntu?
In the last lecture I mentioned that Docker containers use the host OS kernel, so why does the container need Ubuntu?

Remember that operating systems are kernel + programs/libraries. Although the container uses the host kernel, we may still need a lot of programs/libraries that Ubuntu ships with. An example might be a C language compiler!
:::

This is how you define a Docker image. I'll guide you through how to do this in the next lecture, but bear with me for a second:

```dockerfile
FROM python:3.10
EXPOSE 5000
WORKDIR /app
RUN pip install flask
COPY . .
CMD ["flask", "run", "--host", "0.0.0.0"]
```

This is a `Dockerfile`, a definition of how to create a Docker image. Once you have this file, you can ask Docker to create the Docker image. Then, after creating the Docker image, you can ask Docker to run it as a container.

```
Dockerfile ---build--> docker image ---run--> docker container
```

In this `Dockerfile` you can see the first line: `FROM python:3.10`. This tells Docker to first download the `python:3.10` image (an image someone else already created), and once that image is created, run the following commands.

:::info What's in the Python image?
The `python:3.10` image is also built using a `Dockerfile`! You can see the `Dockerfile` for it [here](https://github.com/docker-library/python/blob/master/3.10/bookworm/Dockerfile).

You can see it comes `FROM` another image. There is usually a chain of these, images built upon other images, until you reach the base image. In this case, the [base image](https://github.com/docker-library/buildpack-deps/blob/master/debian/bookworm/Dockerfile) is running Debian (a Linux distribution).

<details>
<summary>Where is the base image!?</summary>
<div>
<div>

If you really want to go deep, you will be able to find...

- The [`python3.10:bookworm`](https://github.com/docker-library/python/blob/master/3.10/bookworm/Dockerfile) image builds on `buildpack-deps:bookworm`
- [`buildpack-deps:bookworm`](https://github.com/docker-library/buildpack-deps/blob/master/debian/bookworm/Dockerfile) builds on `buildpack-deps:bookworm-scm`
- [`buildpack-deps:bookworm-scm`](https://github.com/docker-library/buildpack-deps/blob/master/debian/bookworm/scm/Dockerfile) builds on `buildpack-deps:bookworm-curl`
- [`buildpack-deps:bookworm-curl`](https://github.com/docker-library/buildpack-deps/blob/master/debian/bookworm/curl/Dockerfile) builds on `debian:bookworm`
- [`debian:bookworm`](https://github.com/debuerreotype/docker-debian-artifacts/blob/f7257ef5b83f6b64385edddeae2d2ba7d1b34935/bookworm/Dockerfile) looks really weird!

Eventually, the base image has to physically include the files that make up the operating system. In that last image, that's the Debian OS files that the maintainers have deemed necessary for the `bookworm` image.

</div>
</div>
</details>

So, why the chain?

Three main reasons:

1. So you don't have to write a super long and complex `Dockerfile` which contains everything you need.
2. So pre-published images can be shared online, and all you have to do is download them.
3. So when your own images use the same base image, Docker in your computer only downloads the base image once, saving you a lot of disk space.
:::

Back to our `Dockerfile`. The commands after `FROM...` are specific to our use case, and do things like install requirements, copy our source code into the image, and tell Docker what command to run when we start a container from this image.

This separation between images and containers is interesting because once the image is created you can ship it across the internet and:

- Share it with other developers.
- Deploy it to servers.

Plus once you've downloaded the image (which can take a while), starting a container from it is almost instant since there's very little work to do.


================================================
FILE: docs/docs/04_docker_intro/02_run_docker_container/README.md
================================================
---
ctslug: how-to-run-a-docker-container
description: Learn how to run a Docker container with your REST API using Docker Desktop.
---

# How to run a Docker container

## Install Docker Desktop

Docker Desktop is an application to help you manage your images and containers. Download it and install it here: [https://www.docker.com/products/docker-desktop/](https://www.docker.com/products/docker-desktop/).

## Create your Docker image

Next, download the REST API code from Section 3. You can download it [here](https://www.dropbox.com/s/qs28amk2h420f2y/s03-final-code.zip?dl=0).

If you want to use the code you wrote while following the videos, that's fine! Just make sure it works by running the Flask app locally and testing it with Insomnia REST Client or Postman.

### Write the `Dockerfile`

In your project folder (i.e. the same folder as `app.py`), we're going to write the Dockerfile.

To do this, make a file called `Dockerfile`.

:::caution
Make sure the file is called `Dockerfile`, and not `Dockerfile.txt` or anything like that!
:::

Inside the `Dockerfile` we're going to write this:

```dockerfile
FROM python:3.10
EXPOSE 5000
WORKDIR /app
RUN pip install flask
COPY . .
CMD ["flask", "run", "--host", "0.0.0.0"]
```

Here's a quick breakdown of what each line does:

1. `FROM python:3.10` uses the `python:3.10` image as a base.
2. `EXPOSE 5000` is basically documentation[^1]. It tells the user of the Dockerfile that port 5000 is something the running container will use.
3. `WORKDIR /app` does it so everything we do in the Docker image will happen in the image's `/app` directory.
4. `RUN pip install flask` runs a command in the image. Here the command is `pip install flask`, which is what we need to run our app.
5. `COPY . .` is a bit cryptic! It copies everything in the current folder (so `app.py`) into the image's current folder (so `/app`).
6. `CMD ["flask", "run", "--host", "0.0.0.0"]` tells the image what command to run when you start a container. Here the command is `flask run --host=0.0.0.0`.

:::tip
We need `--host=0.0.0.0` to make Docker be able to do port forwarding, as otherwise the Flask app will only be accessible within the container, but not outside the container.
:::

Now we need to create the Docker image.

We do this with the `docker build` command in the terminal.

:::caution
Make sure to restart your terminal after installing Docker Desktop, so that you have access to the `docker` program in your terminal.
:::

Open a terminal (in VSCode that's CMD+J or CTRL+J), and run this command:

```
docker build -t rest-apis-flask-python .
```

The `-t rest-apis-flask-python` flag is optional, but tags the image, giving it a name. It can be handy for later! The final `.` at the end of the command is not a mistake; it tells the command _what_ to build. The `.` means "the current directory".

This command can take a while to run as it needs to download the `python:3.10` image first. You should see quite a lot of output while the command runs.

When the command is finished, you should see this (among other things):

```
 => [2/4] WORKDIR /app                                                                             0.4s
 => [3/4] RUN pip install flask                                                                    2.9s
 => [4/4] COPY . .                                                                                 0.0s
 => exporting to image                                                                             0.1s
 => => exporting layers                                                                            0.1s
 => => writing image sha256:d9a68a03f868e74bca48567dfc9a0b702d1618941a71b77de12ff14e908ba155       0.0s
 => => naming to docker.io/library/rest-apis-first-rest-api                                        0.0s
```

And now your image is built! You should be able to see it in the "Images" section of your Docker Desktop app.

## Run the Docker container

When we start a Docker container from this image, it will run the `flask run` command. Remember that by default, `flask run` starts a Flask app using port 5000.

But the container's ports are not accessible from outside the container by default. We need to tell Docker that when we access a certain port in our computer, those requests and responses should be forwarded to a certain port in our container.

So we'll run the container, but we must remember to forward a port (e.g. 5000) in our computer to port 5000 in the container

To do so, run this command:

```
docker run -d -p 5000:5000 rest-apis-flask-python
```

We're passing a few things to `docker run`:

1. `-d` runs the container in the background, so that you can close the terminal and the container keeps running.
2. `-p 5000:5000` maps port 5000 in your computer to port 5000 in the container.
3. `rest-apis-flask-python` is the image tag that you want to run.

You should see something like this as your output:

```
9f3c564ac64a1723069dda0e80becb70d3697d4bfcbcb626cd5add0c65df173f
```

That's the ID of the container. If you're not using Docker Desktop, you need this ID in order to stop the container later (with `docker rm 9f3c564`, that's the first few characters of the ID).

And now, if everything has worked, you should be able to access the Flask app _just as if it was running without Docker_!

:::caution Did something not work?
A common error can happen when the port that you tried to forward isn't available (e.g. because something else is already running):

```
docker: Error response from daemon: driver failed programming external connectivity on endpoint bold_goldwasser (ff58b1755c1d1d0fd6b1dd4f59ab3b903b0e68f320624c4a2495672a735039d5): Bind for 0.0.0.0:5000 failed: port is already allocated.
```

You have two options: either figure out what is running on port 5000 and shut it down before trying again, or you can change the port that you want to use in your computer:

```
docker run -dp 5001:5000 rest-apis-flask-python
```
:::

Try making requests using the URL `127.0.0.1:5000` with Insomnia REST Client or Postman, and you should see it working well!

![Insomnia REST Client successfully made a request to the API running in Docker](https://res.cloudinary.com/teclado/image/upload/v1689180719/courses/rest-apis-flask-python/running-app-docker_mkosjm.png)

[^1]: [Docker `EXPOSE` command (Official Documentation)](https://docs.docker.com/engine/reference/builder/#expose)

================================================
FILE: docs/docs/04_docker_intro/02_run_docker_container/end/Dockerfile
================================================
FROM python:3.10
EXPOSE 5000
WORKDIR /app
RUN pip install flask
COPY . .
CMD ["flask", "run", "--host", "0.0.0.0"]

================================================
FILE: docs/docs/04_docker_intro/02_run_docker_container/end/app.py
================================================
from flask import Flask, request

app = Flask(__name__)

stores = [{"name": "My Store", "items": [{"name": "Chair", "price": 15.99}]}]


@app.get("/store")
def get_stores():
    return {"stores": stores}


@app.post("/store")
def create_store():
    request_data = request.get_json()
    new_store = {"name": request_data["name"], "items": []}
    stores.append(new_store)
    return new_store, 201


@app.post("/store/<string:name>/item")
def create_item(name):
    request_data = request.get_json()
    for store in stores:
        if store["name"] == name:
            new_item = {"name": request_data["name"], "price": request_data["price"]}
            store["items"].append(new_item)
            return new_item, 201
    return {"message": "Store not found"}, 404


@app.get("/store/<string:name>")
def get_store(name):
    for store in stores:
        if store["name"] == name:
            return store
    return {"message": "Store not found"}, 404


@app.get("/store/<string:name>/item")
def get_item_in_store(name):
    for store in stores:
        if store["name"] == name:
            return {"items": store["items"]}
    return {"message": "Store not found"}, 404


================================================
FILE: docs/docs/04_docker_intro/02_run_docker_container/start/app.py
================================================
from flask import Flask, request

app = Flask(__name__)

stores = [{"name": "My Store", "items": [{"name": "Chair", "price": 15.99}]}]


@app.get("/store")
def get_stores():
    return {"stores": stores}


@app.post("/store")
def create_store():
    request_data = request.get_json()
    new_store = {"name": request_data["name"], "items": []}
    stores.append(new_store)
    return new_store, 201


@app.post("/store/<string:name>/item")
def create_item(name):
    request_data = request.get_json()
    for store in stores:
        if store["name"] == name:
            new_item = {"name": request_data["name"], "price": request_data["price"]}
            store["items"].append(new_item)
            return new_item, 201
    return {"message": "Store not found"}, 404


@app.get("/store/<string:name>")
def get_store(name):
    for store in stores:
        if store["name"] == name:
            return store
    return {"message": "Store not found"}, 404


@app.get("/store/<string:name>/item")
def get_item_in_store(name):
    for store in stores:
        if store["name"] == name:
            return {"items": store["items"]}
    return {"message": "Store not found"}, 404


================================================
FILE: docs/docs/04_docker_intro/03_in_depth_docker_tutorial/README.md
================================================
---
ctslug: in-depth-docker-tutorial
description: My notes from the official Docker tutorial.
---

# In-depth Docker Tutorial

Like I mentioned earlier on in this section, this course is not a Docker course!

You can access the official Docker tutorial (which is free and great) by running the tutorial image:

```
docker run -dp 80:80 docker/getting-started
```

Then you can access http://127.0.0.1/tutorial to launch the official tutorial.

I recommend going through this (although it uses NodeJS as an example 🤮), as it teaches you quite a few important commands and concepts, such as working with volumes and layers.

When I went through the official tutorial I took some notes, which you can see below. Remember these may differ from the official tutorial as the Docker team updates the tutorial regularly.

I hope the notes are helpful as a bit of a cheatsheet, but it doesn't beat going through the tutorial yourself and taking your own notes!

---

## How to write a simple Dockerfile for a Node app

```dockerfile
FROM node:12-alpine
# Adding build tools to make yarn install work on Apple silicon / arm64 machines
RUN apk add --no-cache python2 g++ make
WORKDIR /app
COPY . .
RUN npm install
CMD ["node", "src/index.js"]
```

Then build the image into a new container (the `.` below refers to the current directory, where Docker should find the `Dockerfile`). Optionally tag it:

```
docker build -t docker-image-tag .
```

## How to run Docker as a daemon (background)

This prints out the container ID and runs it in the background.

```
docker run -d docker-image-tag
```

## How to map ports from host machine to Docker container

This binds port 5000 of the Docker image to port 3000 of the host machine. This way you when you access `127.0.0.1:3000` with your browser, you'll access whatever the Docker image is serving in port `5000`.

Docs: https://docs.docker.com/engine/reference/commandline/run/#publish-or-expose-port--p---expose

```
docker run -p 127.0.0.1:3000:5000 docker-image-tag
```

## Working with Docker volumes

In a Docker volume, the Docker container can store data in the Docker container's filesystem, and it is actually stored in the volume (which is a location in the host machine).

This is in contrast to a Bind Mount, which is another type of volume where the Docker container reads files (i.e. is provided files to read) from the host machine. The Docker container cannot modify those files when using Bind Mounts.

| Feature                                      | Named Volumes               | Bind Mounts                     |
| -------------------------------------------- | --------------------------- | ------------------------------- |
| Host Location                                | Docker chooses              | You control                     |
| Mount Example (using `v`)                    | `my-volume:/usr/local/data` | `/path/to/data:/usr/local/data` |
| Populates new volume with container contents | Yes                         | No                              |
| Supports Volume Drivers                      | Yes                         | No                              |

### How to map a Named Volume from host to Docker container

```
docker run -v volume-name:/path/in/docker/image container-tag
```

For example for an app that needs port mapping and a volume:

```
docker run -dp 3000:3000 -v todo-db:/etc/todos getting-started
```

And to see _where_ in the host machine the data is actually stored:

```
docker volume inspect volume-name
```

> While running in Docker Desktop, the Docker commands are actually running inside a small VM on your machine. If you wanted to look at the actual contents of the Mountpoint directory, you would need to first get inside of the VM.

### How to use a Bind Mount to provide your app code to a Docker container

```
docker run -dp 3000:3000 \
    -w /app -v "$(pwd):/app" \
    node:12-alpine \
    sh -c "apk add --no-cache python2 g++ make && yarn install && yarn run dev"
```

-   `-dp 3000:3000` - same as before. Run in detached (background) mode and create a port mapping
-   `-w /app` - sets the container's present working directory where the command will run from
-   `-v "$(pwd):/app"` - bind mount (link) the host's present `getting-started/app` directory to the container's `/app` directory. Note: Docker requires absolute paths for binding mounts, so in this example we use `pwd` for printing the absolute path of the working directory, i.e. the `app` directory, instead of typing it manually
-   `node:12-alpine` - the image to use. Note that this is the base image for our app from the Dockerfile
-   `sh -c "yarn install && yarn run dev"` - the command. We're starting a shell using `sh` (alpine doesn't have `bash`) and running `yarn install` to install _all_ dependencies and then running `yarn run dev`. If we look in the `package.json`, we'll see that the `dev` script is starting `nodemon`.

Note that most of this is identical to the `Dockerfile` that you would create for your project. The only difference is the `-v "$(pwd):/app"` flag.

## How to pass environment variables to a container

Use the `-e ENV_NAME=env_value` flag with `docker run`.

:::caution Secrets in environment variables
Passing secrets like database connection strings or API keys to Docker containers can be done with environment variables, but it isn't the most secure way (the official Docker tutorial [will tell you more](https://diogomonica.com/2017/03/27/why-you-shouldnt-use-env-variables-for-secret-data/)).

Instead a better option is to use your orchestration framework's secrets management system (that's a mouthful). The two major options are [Kubernetes](https://kubernetes.io/docs/concepts/configuration/secret/) and [Swarm](https://docs.docker.com/engine/swarm/secrets/), and each have their own secrets management system. More info on this later on!
:::

## Networking between two containers

First create a network with:

```
docker network create network-name
```

Then pass the `--network network-name` flag to `docker run`.

You can also pass `--network-alias` to `docker run` to give the container you are running a DNS name within the network.

Then create your containers and pass the network to them. For example, this starts up a MySQL image on `linux/amd64`. It also creates a volume and passes in two environment variables which the image uses for configuring MySQL:

```
docker run -d \
    --network network-name --network-alias mysql --platform linux/amd64 \
    -v todo-mysql-data:/var/lib/mysql \
    -e MYSQL_ROOT_PASSWORD_FILE=/run/secrets/mysql_root_password \
    -e MYSQL_DATABASE=todos \
    mysql:5.7
```

Then you could run another container on the same network:

```
docker run -dp 3000:3000 \
  -w /app -v "$(pwd):/app" \
  --network network-name \
  -e MYSQL_HOST=mysql \
  -e MYSQL_USER=root \
  -e MYSQL_PASSWORD_FILE=/run/secrets/mysql_password \
  -e MYSQL_DB=todos \
  node:12-alpine \
  sh -c "npm install && npm run dev"
```

:::caution
In these I'm not passing the MySQL password directly as an environment variable. Instead, I'm passing the path to a file that contains the password.

That file is created by your Docker orchestration framework's secrets management system. That's a mouthful to say: you define the secret in your orchestration framework, and the framework creates a file which contains the password. That way, the password isn't stored in the environment which is a bit unsafe.

Your application (or, in this case, MySQL), would have to read the contents of the image to find the password.

More info on this when we learn about deploying our app in production!
:::

## How to run multiple containers using Docker Compose

1. Create a `docker-compose.yml` file in the root of your project.
2. Turn each of the `docker run` commands into a `service` in the `docker-compose.yml` file.
3. This is re-creating the flags passed to the `docker run` command, but in YAML format.

Example of the two `docker run`s above:

```yml
services:
  app:
    image: node:12-alpine
    command: sh -c "npm install && npm run dev"
    ports:
      - 3000:3000
    working_dir: /app
    volumes:
      - ./:/app
    environment:
      MYSQL_HOST: mysql
      MYSQL_USER: root
      MYSQL_PASSWORD_FILE: /run/secrets/mysql_password
      MYSQL_DB: todos
  mysql:
    image: mysql:5.7
    platform: linux/amd64
    volumes:
      - todo-mysql-data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD_FILE: /run/secrets/mysql_root_password
      MYSQL_DATABASE: todos

volumes:
  todo-mysql-data:
```

Then, just run `docker compose up -d` and it will start in the background!

You can see it in Docker desktop.

Tear it down and remove the containers (but not the volumes) with `docker compose down`.

## Caching in Dockerfile layers

Each layer (i.e. each line of text) in a Dockerfile uses caching.

That means that if Docker doesn't detect that a layer has changed, it won't re-run it. It'll use the last value / files that were generated for the last build.

However, it also means that if one layer changes and has to be re-built, Docker will re-build all subsequent layers.

Therefore it's best to set up your Dockerfile so that you can maximise the amount of caching and reduce the chances of a cache bust.

For example, instead of this:

```
FROM node:12-alpine
WORKDIR /app
COPY . .
RUN npm install --production
CMD ["node", "src/index.js"]
```

You might do this:

```
FROM node:12-alpine
WORKDIR /app
COPY package.json package.lock ./
RUN npm install --production
COPY . .
CMD ["node", "src/index.js"]
```

That way if the `package.json` and `package.lock` files don't change, you won't re-run `npm install`.

In the first example, if _any_ code files changed, `npm install` would run. Even if it was not needed because the requirements file didn't change.

### Ignore certain files and folders with `.dockerignore`

Some files and folders can be safely ignored when copying over to the Docker container. For example, `node_modules` or the Python virtual environment.

Create a `.dockerignore` file in the root directory of your project (where `docker-compose.yml` lives), and add this (more examples of what to add for a Python project [here](https://github.com/GoogleCloudPlatform/getting-started-python/blob/main/optional-kubernetes-engine/.dockerignore)):

```
node_modules
.venv
.env
*.pyc
__pycache__
```

:::danger Secrets in Docker images
Don't include any secrets (like database connection strings or API keys) in your code. For local development you can use a `.env` file, but don't include the `.env` file in your Docker image!

One of the benefits of Docker images is you can share them with others easily, but that's why you have to be very careful with what you include in them.
:::


================================================
FILE: docs/docs/04_docker_intro/04_run_with_docker_compose/README.md
================================================
# Run the REST API using Docker Compose

Now that we've got a Docker container for our REST API, we can set up Docker Compose to run the container.

Docker Compose is most useful to start multiple Docker containers at the same time, specifying configuration values for them and dependencies between them.

Later on, I'll show you how to use Docker Compose to start both a PostgreSQL database and the REST API. For now, we'll use it only for the REST API, to simplify starting its container up.

If you have Docker Desktop installed, you already have Docker Compose. If you want to install Docker Compose in a system without Docker Desktop, please refer to the [official installation instructions](https://docs.docker.com/compose/install/).

## How to write a `docker-compose.yml` file

Create a file called `docker-compose.yml` in the root of your project (alongside your `Dockerfile`). Inside it, add the following contents:

```yaml
services:
  web:
    build: .
    ports:
      - "5000:5000"
    volumes:
      - .:/app
```

This small file is all you need to tell Docker Compose that you have a service, called `web`, which is built using the current directory (by default, that looks for a file called `Dockerfile`).

Other settings provided are:

- `ports`, used to map a port in your local computer to one in the container. Since our container runs the Flask app on port 5000, we're targeting that port so that any traffic we access in port 5000 of our computer is sent to the container's port 5000.
- `volumes`, to map a local directory into a directory within the container. This makes it so you don't have to rebuild the image each time you make a code change.

## How to run the Docker Compose services

Simply type:

```
docker compose up
```

And that will start all your services. For now, there's just one service, but later on when we add a database, this command will start everything.

When the services are running, you'll start seeing logs appear. These are the same logs as for running the `Dockerfile` on its own, but preceded by the service name.

In our case, we'll see `web-1  |  ...` and the logs saying the service is running on `http://127.0.0.1:5000`. When you access that URL, you'll see the request logs printed in the console.

Congratulations, you've ran your first Docker Compose service!

## Rebuilding the Docker image

If you need to rebuild the Docker image of your REST API service for whatever reason (e.g. configuration changes), you can run:

```
docker compose up --build --force-recreate --no-deps web
```

More information [here](https://stackoverflow.com/a/50802581).


================================================
FILE: docs/docs/04_docker_intro/04_run_with_docker_compose/end/Dockerfile
================================================
FROM python:3.10
EXPOSE 5000
WORKDIR /app
RUN pip install flask
COPY . .
CMD ["flask", "run", "--host", "0.0.0.0"]

================================================
FILE: docs/docs/04_docker_intro/04_run_with_docker_compose/end/app.py
================================================
from flask import Flask, request

app = Flask(__name__)

stores = [{"name": "My Store", "items": [{"name": "Chair", "price": 15.99}]}]


@app.get("/store")
def get_stores():
    return {"stores": stores}


@app.post("/store")
def create_store():
    request_data = request.get_json()
    new_store = {"name": request_data["name"], "items": []}
    stores.append(new_store)
    return new_store, 201


@app.post("/store/<string:name>/item")
def create_item(name):
    request_data = request.get_json()
    for store in stores:
        if store["name"] == name:
            new_item = {"name": request_data["name"], "price": request_data["price"]}
            store["items"].append(new_item)
            return new_item, 201
    return {"message": "Store not found"}, 404


@app.get("/store/<string:name>")
def get_store(name):
    for store in stores:
        if store["name"] == name:
            return store
    return {"message": "Store not found"}, 404


@app.get("/store/<string:name>/item")
def get_item_in_store(name):
    for store in stores:
        if store["name"] == name:
            return {"items": store["items"]}
    return {"message": "Store not found"}, 404


================================================
FILE: docs/docs/04_docker_intro/04_run_with_docker_compose/end/docker-compose.yml
================================================
services:
  web:
    build: .
    ports:
      - "5000:5000"
    volumes:
      - .:/app

================================================
FILE: docs/docs/04_docker_intro/04_run_with_docker_compose/start/Dockerfile
================================================
FROM python:3.10
EXPOSE 5000
WORKDIR /app
RUN pip install flask
COPY . .
CMD ["flask", "run", "--host", "0.0.0.0"]

================================================
FILE: docs/docs/04_docker_intro/04_run_with_docker_compose/start/app.py
================================================
from flask import Flask, request

app = Flask(__name__)

stores = [{"name": "My Store", "items": [{"name": "Chair", "price": 15.99}]}]


@app.get("/store")
def get_stores():
    return {"stores": stores}


@app.post("/store")
def create_store():
    request_data = request.get_json()
    new_store = {"name": request_data["name"], "items": []}
    stores.append(new_store)
    return new_store, 201


@app.post("/store/<string:name>/item")
def create_item(name):
    request_data = request.get_json()
    for store in stores:
        if store["name"] == name:
            new_item = {"name": request_data["name"], "price": request_data["price"]}
            store["items"].append(new_item)
            return new_item, 201
    return {"message": "Store not found"}, 404


@app.get("/store/<string:name>")
def get_store(name):
    for store in stores:
        if store["name"] == name:
            return store
    return {"message": "Store not found"}, 404


@app.get("/store/<string:name>/item")
def get_item_in_store(name):
    for store in stores:
        if store["name"] == name:
            return {"items": store["items"]}
    return {"message": "Store not found"}, 404


================================================
FILE: docs/docs/04_docker_intro/05_run_commands_in_docker_containers/README.md
================================================
# How to run commands inside a Docker container

If you run your API using Docker Compose, with the `docker compose up` command, you may also want to be able to execute arbitrary shell commands in the container.

For example, later on in the course we will look at database migrations.

To execute a database migration, we need to run a specific command, `flask db mgirate`.

If we use Docker Compose, we'll need to run the command inside the running container, and not in a local terminal.

You can run any arbitrary command in a running container like so:

```bash
docker compose exec web flask db migrate
```

This command is split into 4 parts:

- `docker compose`: uses the Docker Compose part of the Docker executable
- `exec`: used to run a command in a specific Docker Compose service
- `web`: which Docker Compose service to run the command in
- `flask db migrate`: the command you want to run

That's all! Just remember while following the course, that if I run any commands in my local terminal and you are using Docker Compose, you should precede the commands with `docker compose exec web`.


================================================
FILE: docs/docs/04_docker_intro/README.md
================================================
# An Introduction to Docker

:::caution Not a Docker course
An important foreword: this is not a Docker course, and I'm not a Docker expert!

In this section, and in later sections of this course, I'll teach you what Docker is and how to use it to run and deploy your Flask apps. However, I won't teach you everything there is to know about Docker!
:::

Docker is a software framework for building, running, and managing **images** and **containers**.

In order to understand Docker, you need to clarify two questions:

- What are Docker containers, and how are they different to Virtual Machines?
- What are Docker images?

After this, you'll be ready to create your own Docker images and use those images to create and run containers.

Let's take a look at Docker containers in the next lecture!

================================================
FILE: docs/docs/04_docker_intro/_category_.json
================================================
{
    "label": "Introduction to Docker",
    "position": 4
}


================================================
FILE: docs/docs/05_flask_smorest/01_why_flask_smorest/README.md
================================================
---
ctslug: why-use-flask-smorest
---

# Why use Flask-Smorest

There are many different REST API libraries for Flask. In a previous version of this course, we used Flask-RESTful. Now, I recommend using [Flask-Smorest](https://github.com/marshmallow-code/flask-smorest).

Over the last few months, I've been trialing the major REST libraries for Flask. I've built REST APIs using Flask-RESTful, Flask-RESTX, and Flask-Smorest.

I was looking to compare the three libraries in a few key areas:

- **Ease of use and getting started**. Many REST APIs are essentially microservices, so being able to whip one up quickly and without having to go through a steep learning curve is definitely interesting.
- **Maintainability and expandability**. Although many start as microservices, sometimes we have to maintain projects for a long time. And sometimes, they grow past what we originally envisioned.
- **Activity in the library itself**. Even if a library is suitable now, if it is not actively maintained and improved, it may not be suitable in the future. We'd like to teach something that you will use for years to come.
- **Documentation and usage of best practice**. The library should help you write better code by having strong documentation and guiding you into following best practice. If possible, it should use existing, actively maintained libraries as dependencies instead of implementing their own versions of them.
- **Developer experience in production projects**. The main point here was: how easy is it to produce API documentation with the library of choice. Hundreds of students have asked me how to integrate Swagger in their APIs, so it would be great if the library we teach gave it to you out of the box.

## Flask-Smorest is the most well-rounded

It ticks all the boxes above:

- If you want, it can be super similar to Flask-RESTful (which is a compliment, really easy to get started!).
- It uses [marshmallow](https://marshmallow.readthedocs.io/en/stable/) for serialization and deserialization, which is a huge plus. Marshmallow is a very actively-maintained library which is very intuitive and unlocks very easy argument validation. Unfortunately Flask-RESTX [doesn't use marshmallow](https://flask-restx.readthedocs.io/en/latest/marshalling.html), though there are [plans to do so](https://github.com/python-restx/flask-restx/issues/59).
- It provides Swagger (with Swagger UI) and other documentations out of the box. It uses the same marshmallow schemas you use for API validation and some simple decorators in your code to generate the documentation.
- The documentation is the weakest point (compared to Flask-RESTX), but with this course we can help you navigate it. The documentation of marshmallow is superb, so that will also help.

## If you took an old version of this course...

Let me tell you about some of the key differences between a project that uses Flask-RESTful and one that uses Flask-Smorest. After reading through these differences, it should be fairly straightforward for you to look at two projects, each using one library, and compare them.

1. Flask-Smorest uses `flask.views.MethodView` classes registered under a `flask_smorest.Blueprint` instead of `flask_restful.Resource` classes.
2. Flask-Smorest uses `flask_smorest.abort` to return error responses instead of manually returning the error JSON and error code.
3. Flask-Smorest projects define marshmallow schemas that represent incoming data (for deserialization and validation) and outgoing data (for serialization). It uses these schemas to automatically validate the data and turn Python objects into JSON.

Throughout this section I'll show you how to implement these 3 points in practice, so if you've already got a REST API that uses Flask-RESTful, you'll find it really easy to migrate.

Of course, you can keep using Flask-RESTful for your existing projects, and only use Flask-Smorest for new projects. That's also an option! Flask-RESTful isn't abandoned or deprecated, so it's still a totally viable option.

================================================
FILE: docs/docs/05_flask_smorest/02_data_model_improvements/README.md
================================================
---
title: "Data model improvements"
description: "Use dictionaries instead of lists for data storage, and store stores and items separately."
ctslug: data-model-improvements
---

# Data model improvements

## Starting code from section 4

This is the "First REST API" project from Section 4:

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

<div className="codeTabContainer">
<Tabs>
<TabItem value="app" label="app.py" default>

```py title="app.py"
from flask import Flask, request

app = Flask(__name__)

stores = [
    {
        "name": "My Store",
        "items": [
            {
                "name": "Chair",
                "price": 15.99
            }
        ]
    }
]

@app.get("/store")  # http://127.0.0.1:5000/store
def get_stores():
    return {"stores": stores}


@app.post("/store")
def create_store():
    request_data = request.get_json()
    new_store = {"name": request_data["name"], "items": []}
    stores.append(new_store)
    return new_store, 201


@app.post("/store/<string:name>/item")
def create_item(name):
    request_data = request.get_json()
    for store in stores:
        if store["name"] == name:
            new_item = {"name": request_data["name"], "price": request_data["price"]}
            store["items"].append(new_item)
            return new_item, 201
    return {"message": "Store not found"}, 404


@app.get("/store/<string:name>")
def get_store(name):
    for store in stores:
        if store["name"] == name:
            return store
    return {"message": "Store not found"}, 404


@app.get("/store/<string:name>/item")
def get_item_in_store(name):
    for store in stores:
        if store["name"] == name:
            return {"items": store["items"]}
    return {"message": "Store not found"}, 404
```

</TabItem>
<TabItem value="docker" label="Dockerfile">

```docker
FROM python:3.10
EXPOSE 5000
WORKDIR /app
RUN pip install flask
COPY . .
CMD ["flask", "run", "--host", "0.0.0.0"]
```

</TabItem>
</Tabs>
</div>

## New files

:::tip Insomnia files
Remember to get the Insomnia files for this section or for all sections [here](/insomnia-files/)!

There are two Insomnia files for this section: one for lectures 1-5 (before adding Docker), and one for the other lectures (after adding Docker).
:::

Let's start off by creating a `requirements.txt` file with all our dependencies:

```txt title="requirements.txt"
flask
flask-smorest
python-dotenv
```

We're adding `flask-smorest` to help us write REST APIs more easily, and generate documentation for us.

We're adding `python-dotenv` so it's easier for us to load environment variables and use the `.flaskenv` file.

Next, let's create the `.flaskenv` file:

```txt title=".flaskenv"
FLASK_APP=app
FLASK_DEBUG=True
```

If we have the `python-dotenv` library installed, when we run the `flask run` command, Flask will read the variables inside `.flaskenv` and use them to configure the Flask app.

The configuration that we'll do is to define the Flask app file (here, `app.py`). Then we'll also set the `FLASK_DEBUG` flag to `True`, which does a couple things:

- Makes the app give us better error messages and return a traceback when we make requests if there's an error.
- Sets the app reloading to true, so the app restarts when we make code changes

We don't want debug mode to be enabled in production (when we deploy our app), but while we're doing development it's definitely a time-saving tool!

## Code improvements

### Creating a database file

First of all, let's move our "database" to another file.

Create a `db.py` file with the following content:

```py title="db.py"
stores = {}
items = {}
```

In the existing code we only have a `stores` list, so delete that from `app.py`. From now on we will be storing information about items and stores separately.

:::tip What is in each dictionary?
Each dictionary will closely mimic how a database works: a mapping of ID to data. So each dictionary will be something like this:

```py
{
    1: {
        "name": "Chair",
        "price": 17.99
    },
    2: {
        "name": "Table",
        "price": 180.50
    }
}
```

This will make it much easier to retrieve a specific store or item, just by knowing its ID.
:::

Then, import the `stores` and `items` variables from `db.py` in `app.py`:

```py title="app.py"
from db import stores, items
```

## Using stores and items in our API

Now let's make use of stores and items separately in our API.

### `get_store`

Here are the changes we'll need to make:

<div className="codeTabContainer">
<Tabs>
<TabItem value="old" label="get_store (old)" default>

```py title="app.py"
@app.get("/store/<string:name>")
def get_store(name):
    for store in stores:
        if store["name"] == name:
            return store
    return {"message": "Store not found"}, 404
```

</TabItem>
<TabItem value="new" label="get_store (new)">

```py title="app.py"
@app.get("/store/<string:store_id>")
def get_store(store_id):
    try:
        # Here you might also want to add the items in this store
        # We'll do that later on in the course
        return stores[store_id]
    except KeyError:
        return {"message": "Store not found"}, 404
```

Important to note that in this version, we won't return the items in the store. That's a limitation of our dictionaries-for-database setup that we will solve when we introduce databases!

</TabItem>
</Tabs>
</div>

### `get_stores`

<div className="codeTabContainer">
<Tabs>
<TabItem value="old" label="get_stores (old)" default>

```py title="app.py"
@app.get("/store")
def get_stores():
    return {"stores": stores}
```

</TabItem>
<TabItem value="new" label="get_stores (new)">

```py title="app.py"
@app.get("/store")
def get_stores():
    return {"stores": list(stores.values())}
```

</TabItem>
</Tabs>
</div>

### `create_store`

<div className="codeTabContainer">
<Tabs>
<TabItem value="old" label="create_store (old)" default>

```py title="app.py"
@app.post("/store")
def create_store():
    request_data = request.get_json()
    new_store = {"name": request_data["name"], "items": []}
    stores.append(new_store)
    return new_store, 201
```

</TabItem>
<TabItem value="new" label="create_store (new)">

```py title="app.py"
import uuid

@app.post("/store")
def create_store():
    store_data = request.get_json()
    store_id = uuid.uuid4().hex
    store = {**store_data, "id": store_id}
    stores[store_id] = store

    return store
```

Here we add a new import, [the `uuid` module](https://docs.python.org/3/library/uuid.html). We will be using it to create unique IDs for our stores and items instead of relying on the uniqueness of their names.

</TabItem>
</Tabs>
</div>

### `create_item`

<div className="codeTabContainer">
<Tabs>
<TabItem value="old" label="create_item (old)" default>

```py title="app.py"
@app.post("/store/<string:name>/item")
def create_item(name):
    request_data = request.get_json()
    for store in stores:
        if store["name"] == name:
            new_item = {"name": request_data["name"], "price": request_data["price"]}
            store["items"].append(new_item)
            return new_item, 201
    return {"message": "Store not found"}, 404
```

</TabItem>
<TabItem value="new" label="create_item (new)">

```py title="app.py"
@app.post("/item")
def create_item():
    item_data = request.get_json()
    if item_data["store_id"] not in stores:
        return {"message": "Store not found"}, 404

    item_id = uuid.uuid4().hex
    item = {**item_data, "id": item_id}
    items[item_id] = item

    return item
```

Now we are POSTing to `/item` instead of `/store/<string:name>/item`. The endpoint will expect to receive JSON with `price`, `name`, and `store_id`.

</TabItem>
</Tabs>
</div>


### `get_items` (new)

This is not an endpoint we could easily make when we were working with a single `stores` list!

```py
@app.get("/item")
def get_all_items():
    return {"items": list(items.values())}
```

### `get_item_in_store`

<div className="codeTabContainer">
<Tabs>
<TabItem value="old" label="get_item_in_store (old)" default>

```py title="app.py"
@app.get("/store/<string:name>/item")
def get_item_in_store(name):
    for store in stores:
        if store["name"] == name:
            return {"items": store["items"]}
    return {"message": "Store not found"}, 404
```

</TabItem>
<TabItem value="new" label="get_item (new)">

```py title="app.py"
@app.get("/item/<string:item_id>")
def get_item(item_id):
    try:
        return items[item_id]
    except KeyError:
        return {"message": "Item not found"}, 404
```

Now we are GETting from `/item` instead of `/store/<string:name>/item`. This is because while items are related to stores, they aren't inside a store anymore!

</TabItem>
</Tabs>
</div>


================================================
FILE: docs/docs/05_flask_smorest/02_data_model_improvements/end/.flaskenv
================================================
FLASK_APP=app
FLASK_DEBUG=True

================================================
FILE: docs/docs/05_flask_smorest/02_data_model_improvements/end/Dockerfile
================================================
# In the course we run the app outside Docker
# until lecture 5.
FROM python:3.10
EXPOSE 5000
WORKDIR /app
RUN pip install flask
COPY . .
CMD ["flask", "run", "--host", "0.0.0.0"]

================================================
FILE: docs/docs/05_flask_smorest/02_data_model_improvements/end/app.py
================================================
import uuid
from flask import Flask, request

from db import stores, items


app = Flask(__name__)


@app.get("/item/<string:item_id>")
def get_item(item_id):
    try:
        return items[item_id]
    except KeyError:
        return {"message": "Item not found"}, 404


@app.post("/item")
def create_item():
    item_data = request.get_json()
    if item_data["store_id"] not in stores:
        return {"message": "Store not found"}, 404

    item_id = uuid.uuid4().hex
    item = {**item_data, "id": item_id}
    items[item_id] = item

    return item


@app.get("/item")
def get_all_items():
    return {"items": list(items.values())}


@app.get("/store/<string:store_id>")
def get_store(store_id):
    try:
        # Here you might also want to add the items in this store
        # We'll do that later on in the course
        return stores[store_id]
    except KeyError:
        return {"message": "Store not found"}, 404


@app.post("/store")
def create_store():
    store_data = request.get_json()
    store_id = uuid.uuid4().hex
    store = {**store_data, "id": store_id}
    stores[store_id] = store

    return store


@app.get("/store")
def get_stores():
    return {"stores": list(stores.values())}


================================================
FILE: docs/docs/05_flask_smorest/02_data_model_improvements/end/db.py
================================================
"""
db.py
---

Later on, this file will be replaced by SQLAlchemy. For now, it mimics a database.
Our data storage is:
    - stores have a unique ID and a name
    - items have a unique ID, a name, a price, and a store ID.
"""

stores = {}
items = {}


================================================
FILE: docs/docs/05_flask_smorest/02_data_model_improvements/end/requirements.txt
================================================
flask
flask-smorest
python-dotenv

================================================
FILE: docs/docs/05_flask_smorest/02_data_model_improvements/start/Dockerfile
================================================
FROM python:3.10
EXPOSE 5000
WORKDIR /app
RUN pip install flask
COPY . .
CMD ["flask", "run", "--host", "0.0.0.0"]

================================================
FILE: docs/docs/05_flask_smorest/02_data_model_improvements/start/app.py
================================================
from flask import Flask, request

app = Flask(__name__)

stores = [{"name": "My Store", "items": [{"name": "Chair", "price": 15.99}]}]


@app.get("/store")  # http://127.0.0.1:5000/store
def get_stores():
    return {"stores": stores}


@app.post("/store")
def create_store():
    request_data = request.get_json()
    new_store = {"name": request_data["name"], "items": []}
    stores.append(new_store)
    return new_store, 201


@app.post("/store/<string:name>/item")
def create_item(name):
    request_data = request.get_json()
    for store in stores:
        if store["name"] == name:
            new_item = {"name": request_data["name"], "price": request_data["price"]}
            store["items"].append(new_item)
            return new_item, 201
    return {"message": "Store not found"}, 404


@app.get("/store/<string:name>")
def get_store(name):
    for store in stores:
        if store["name"] == name:
            return store
    return {"message": "Store not found"}, 404


@app.get("/store/<string:name>/item")
def get_item_in_store(name):
    for store in stores:
        if store["name"] == name:
            return {"items": store["items"]}
    return {"message": "Store not found"}, 404


================================================
FILE: docs/docs/05_flask_smorest/03_improvements_on_first_rest_api/README.md
================================================
---
title: "Improvements to our first REST API"
description: "Add new error handling and code improvements to the REST API before adding any new endpoints."
ctslug: improvements-to-our-first-rest-api
---

# Improvements to our first REST API

## Using `flask_smorest.abort` instead of returning errors manually

At the moment in our API we're doing things like these in case of an error:

```py title="app.py"
@app.get("/store/<string:name>")
def get_store(name):
    try:
        # Here you might also want to add the items in this store
        # We'll do that later on in the course
        return stores[store_id]
    except KeyError:
        return {"message": "Store not found"}, 404
```

A small improvement we can do on this is use the `abort` function from Flask-Smorest, which helps us write these messages and include a bit of extra information too.

Add this import at the top of `app.py`:

```py title="app.py"
from flask_smorest import abort
```

And then let's change our error returns to use `abort`.

```py title="app.py"
@app.get("/store/<string:store_id>")
def get_store(store_id):
    try:
        # Here you might also want to add the items in this store
        # We'll do that later on in the course
        return stores[store_id]
    except KeyError:
        # highlight-start
        abort(404, message="Store not found.")
        # highlight-end
```

And here:

```py title="app.py"
@app.get("/item/<string:item_id>")
def get_item(item_id):
    try:
        return items[item_id]
    except KeyError:
        # highlight-start
        abort(404, message="Item not found.")
        # highlight-end
```

## Adding error handling on creating items and stores

At the moment when we create items and stores, we _expect_ there to be certain items in the JSON body of the request.

If those items are missing, the app will return an error 500, which means "Internal Server Error".

Instead of that, it's good practice to return an error 400 and a message telling the client what went wrong.

To do so, let's inspect the body of the request and see if it contains the data we need.

Let's change our `create_item()` function to this:

```py title="app.py"
@app.post("/item")
def create_item():
    item_data = request.get_json()
    # Here not only we need to validate data exists,
    # But also what type of data. Price should be a float,
    # for example.
    if (
        "price" not in item_data
        or "store_id" not in item_data
        or "name" not in item_data
    ):
        abort(
            400,
            message="Bad request. Ensure 'price', 'store_id', and 'name' are included in the JSON payload.",
        )
    for item in items.values():
        if (
            item_data["name"] == item["name"]
            and item_data["store_id"] == item["store_id"]
        ):
            abort(400, message=f"Item already exists.")

    item_id = uuid.uuid4().hex
    item = {**item_data, "id": item_id}
    items[item_id] = item

    return item
```

And our `create_store()` function to this:

```py title="app.py"
@app.post("/store")
def create_store():
    store_data = request.get_json()
    if "name" not in store_data:
        abort(
            400,
            message="Bad request. Ensure 'name' is included in the JSON payload.",
        )
    for store in stores.values():
        if store_data["name"] == store["name"]:
            abort(400, message=f"Store already exists.")

    store_id = uuid.uuid4().hex
    store = {**store_data, "id": store_id}
    stores[store_id] = store

    return store
```

================================================
FILE: docs/docs/05_flask_smorest/03_improvements_on_first_rest_api/end/.flaskenv
================================================
FLASK_APP=app
FLASK_DEBUG=True

================================================
FILE: docs/docs/05_flask_smorest/03_improvements_on_first_rest_api/end/Dockerfile
================================================
FROM python:3.10
EXPOSE 5000
WORKDIR /app
RUN pip install flask
COPY . .
CMD ["flask", "run", "--host", "0.0.0.0"]

================================================
FILE: docs/docs/05_flask_smorest/03_improvements_on_first_rest_api/end/app.py
================================================
import uuid
from flask import Flask, request
from flask_smorest import abort

from db import stores, items


app = Flask(__name__)


@app.get("/item/<string:item_id>")
def get_item(item_id):
    try:
        return items[item_id]
    except KeyError:
        abort(404, message="Item not found.")


@app.post("/item")
def create_item():
    item_data = request.get_json()
    # Here not only we need to validate data exists,
    # But also what type of data. Price should be a float,
    # for example.
    if (
        "price" not in item_data
        or "store_id" not in item_data
        or "name" not in item_data
    ):
        abort(
            400,
            message="Bad request. Ensure 'price', 'store_id', and 'name' are included in the JSON payload.",
        )
    for item in items.values():
        if (
            item_data["name"] == item["name"]
            and item_data["store_id"] == item["store_id"]
        ):
            abort(400, message=f"Item already exists.")

    item_id = uuid.uuid4().hex
    item = {**item_data, "id": item_id}
    items[item_id] = item

    return item


@app.get("/item")
def get_all_items():
    return {"items": list(items.values())}


@app.get("/store/<string:store_id>")
def get_store(store_id):
    try:
        # Here you might also want to add the items in this store
        # We'll do that later on in the course
        return stores[store_id]
    except KeyError:
        abort(404, message="Store not found.")


@app.post("/store")
def create_store():
    store_data = request.get_json()
    if "name" not in store_data:
        abort(
            400,
            message="Bad request. Ensure 'name' is included in the JSON payload.",
        )
    for store in stores.values():
        if store_data["name"] == store["name"]:
            abort(400, message=f"Store already exists.")

    store_id = uuid.uuid4().hex
    store = {**store_data, "id": store_id}
    stores[store_id] = store

    return store


@app.get("/store")
def get_stores():
    return {"stores": list(stores.values())}


================================================
FILE: docs/docs/05_flask_smorest/03_improvements_on_first_rest_api/end/db.py
================================================
"""
db.py
---

Later on, this file will be replaced by SQLAlchemy. For now, it mimics a database.
Our data storage is:
    - stores have a unique ID and a name
    - items have a unique ID, a name, a price, and a store ID.
"""

stores = {}
items = {}


================================================
FILE: docs/docs/05_flask_smorest/03_improvements_on_first_rest_api/end/requirements.txt
================================================
flask
flask-smorest
python-dotenv

================================================
FILE: docs/docs/05_flask_smorest/03_improvements_on_first_rest_api/start/.flaskenv
================================================
FLASK_APP=app
FLASK_DEBUG=True

================================================
FILE: docs/docs/05_flask_smorest/03_improvements_on_first_rest_api/start/Dockerfile
================================================
FROM python:3.10
EXPOSE 5000
WORKDIR /app
RUN pip install flask
COPY . .
CMD ["flask", "run", "--host", "0.0.0.0"]

================================================
FILE: docs/docs/05_flask_smorest/03_improvements_on_first_rest_api/start/app.py
================================================
import uuid
from flask import Flask, request

from db import stores, items


app = Flask(__name__)


@app.get("/item/<string:item_id>")
def get_item(item_id):
    try:
        return items[item_id]
    except KeyError:
        return {"message": "Item not found"}, 404


@app.post("/item")
def create_item():
    item_data = request.get_json()
    if item_data["store_id"] not in stores:
        return {"message": "Store not found"}, 404

    item_id = uuid.uuid4().hex
    item = {**item_data, "id": item_id}
    items[item_id] = item

    return item


@app.get("/item")
def get_all_items():
    return {"items": list(items.values())}


@app.get("/store/<string:store_id>")
def get_store(store_id):
    try:
        # Here you might also want to add the items in this store
        # We'll do that later on in the course
        return stores[store_id]
    except KeyError:
        return {"message": "Store not found"}, 404


@app.post("/store")
def create_store():
    store_data = request.get_json()
    store_id = uuid.uuid4().hex
    store = {**store_data, "id": store_id}
    stores[store_id] = store

    return store


@app.get("/store")
def get_stores():
    return {"stores": list(stores.values())}


================================================
FILE: docs/docs/05_flask_smorest/03_improvements_on_first_rest_api/start/db.py
================================================
"""
db.py
---

Later on, this file will be replaced by SQLAlchemy. For now, it mimics a database.
Our data storage is:
    - stores have a unique ID and a name
    - items have a unique ID, a name, a price, and a store ID.
"""

stores = {}
items = {}


================================================
FILE: docs/docs/05_flask_smorest/03_improvements_on_first_rest_api/start/requirements.txt
================================================
flask
flask-smorest
python-dotenv

================================================
FILE: docs/docs/05_flask_smorest/04_new_endpoints_for_api/README.md
================================================
---
title: "New endpoints for our REST API"
description: "Let's add a few routes to our first REST API, so it better matches what a production REST API would look like."
ctslug: new-endpoints-for-our-rest-api
---

# New endpoints for our REST API

## New endpoints

We want to add some endpoints for added functionality:

- `DELETE /item/<string:item_id>` so we can delete items from the database.
- `PUT /item/<string:item_id>` so we can update items.
- `DELETE /store/<string:store_id>` so we can delete stores.

### Deleting items

This is almost identical to getting items, but we use the `del` keyword to remove the entry from the dictionary.

```py title="app.py"
@app.delete("/item/<string:item_id>")
def delete_item(item_id):
    try:
        del items[item_id]
        return {"message": "Item deleted."}
    except KeyError:
        abort(404, message="Item not found.")
```

### Updating items

This is almost identical to creating items, but in this API we've decided to not let item updates change the `store_id` of the item. So clients can change item name and price, but not the store that the item belongs to.

This is an API design decision, and you could very well allow clients to update the `store_id` if you want!

```py title="app.py"
@app.put("/item/<string:item_id>")
def update_item(item_id):
    item_data = request.get_json()
    # There's  more validation to do here!
    # Like making sure price is a number, and also both items are optional
    # You should also prevent keys that aren't 'price' or 'name' to be passed
    # Difficult to do with an if statement...
    if "price" not in item_data or "name" not in item_data:
        abort(
            400,
            message="Bad request. Ensure 'price', and 'name' are included in the JSON payload.",
        )
    try:
        item = items[item_id]
        item |= item_data

        return item
    except KeyError:
        abort(404, message="Item not found.")
```

:::tip Dictionary update operators
The `|=` syntax is a new dictionary operator. You can read more about it [here](https://blog.teclado.com/python-dictionary-merge-update-operators/).
:::

### Deleting stores

This is very similar to deleting items!

```py title="app.py"
@app.delete("/store/<string:store_id>")
def delete_store(store_id):
    try:
        del stores[store_id]
        return {"message": "Store deleted."}
    except KeyError:
        abort(404, message="Store not found.")
```


================================================
FILE: docs/docs/05_flask_smorest/04_new_endpoints_for_api/end/.flaskenv
================================================
FLASK_APP=app
FLASK_DEBUG=True

================================================
FILE: docs/docs/05_flask_smorest/04_new_endpoints_for_api/end/Dockerfile
================================================
FROM python:3.10
EXPOSE 5000
WORKDIR /app
RUN pip install flask
COPY . .
CMD ["flask", "run", "--host", "0.0.0.0"]

================================================
FILE: docs/docs/05_flask_smorest/04_new_endpoints_for_api/end/app.py
================================================
import uuid
from flask import Flask, request
from flask_smorest import abort

from db import stores, items


app = Flask(__name__)


@app.get("/item/<string:item_id>")
def get_item(item_id):
    try:
        return items[item_id]
    except KeyError:
        abort(404, message="Item not found.")


@app.post("/item")
def create_item():
    item_data = request.get_json()
    # Here not only we need to validate data exists,
    # But also what type of data. Price should be a float,
    # for example.
    if (
        "price" not in item_data
        or "store_id" not in item_data
        or "name" not in item_data
    ):
        abort(
            400,
            message="Bad request. Ensure 'price', 'store_id', and 'name' are included in the JSON payload.",
        )
    for item in items.values():
        if (
            item_data["name"] == item["name"]
            and item_data["store_id"] == item["store_id"]
        ):
            abort(400, message=f"Item already exists.")

    item_id = uuid.uuid4().hex
    item = {**item_data, "id": item_id}
    items[item_id] = item

    return item


@app.delete("/item/<string:item_id>")
def delete_item(item_id):
    try:
        del items[item_id]
        return {"message": "Item deleted."}
    except KeyError:
        abort(404, message="Item not found.")


@app.put("/item/<string:item_id>")
def update_item(item_id):
    item_data = request.get_json()
    # There's  more validation to do here!
    # Like making sure price is a number, and also both items are optional
    # Difficult to do with an if statement...
    if "price" not in item_data or "name" not in item_data:
        abort(
            400,
            message="Bad request. Ensure 'price', and 'name' are included in the JSON payload.",
        )
    try:
        item = items[item_id]

        # https://blog.teclado.com/python-dictionary-merge-update-operators/
        item |= item_data

        return item
    except KeyError:
        abort(404, message="Item not found.")


@app.get("/item")
def get_all_items():
    return {"items": list(items.values())}


@app.get("/store/<string:store_id>")
def get_store(store_id):
    try:
        # Here you might also want to add the items in this store
        # We'll do that later on in the course
        return stores[store_id]
    except KeyError:
        abort(404, message="Store not found.")


@app.post("/store")
def create_store():
    store_data = request.get_json()
    if "name" not in store_data:
        abort(
            400,
            message="Bad request. Ensure 'name' is included in the JSON payload.",
        )
    for store in stores.values():
        if store_data["name"] == store["name"]:
            abort(400, message=f"Store already exists.")

    store_id = uuid.uuid4().hex
    store = {**store_data, "id": store_id}
    stores[store_id] = store

    return store


@app.delete("/store/<string:store_id>")
def delete_store(store_id):
    try:
        del stores[store_id]
        return {"message": "Store deleted."}
    except KeyError:
        abort(404, message="Store not found.")


@app.get("/store")
def get_stores():
    return {"stores": list(stores.values())}


================================================
FILE: docs/docs/05_flask_smorest/04_new_endpoints_for_api/end/db.py
================================================
"""
db.py
---

Later on, this file will be replaced by SQLAlchemy. For now, it mimics a database.
Our data storage is:
    - stores have a unique ID and a name
    - items have a unique ID, a name, a price, and a store ID.
"""

stores = {}
items = {}


================================================
FILE: docs/docs/05_flask_smorest/04_new_endpoints_for_api/end/requirements.txt
================================================
flask
flask-smorest
python-dotenv

================================================
FILE: docs/docs/05_flask_smorest/04_new_endpoints_for_api/start/.flaskenv
================================================
FLASK_APP=app
FLASK_DEBUG=True

================================================
FILE: docs/docs/05_flask_smorest/04_new_endpoints_for_api/start/Dockerfile
================================================
FROM python:3.10
EXPOSE 5000
WORKDIR /app
RUN pip install flask
COPY . .
CMD ["flask", "run", "--host", "0.0.0.0"]

================================================
FILE: docs/docs/05_flask_smorest/04_new_endpoints_for_api/start/app.py
================================================
import uuid
from flask import Flask, request
from flask_smorest import abort

from db import stores, items


app = Flask(__name__)


@app.get("/item/<string:item_id>")
def get_item(item_id):
    try:
        return items[item_id]
    except KeyError:
        abort(404, message="Item not found.")


@app.post("/item")
def create_item():
    item_data = request.get_json()
    # Here not only we need to validate data exists,
    # But also what type of data. Price should be a float,
    # for example.
    if (
        "price" not in item_data
        or "store_id" not in item_data
        or "name" not in item_data
    ):
        abort(
            400,
            message="Bad request. Ensure 'price', 'store_id', and 'name' are included in the JSON payload.",
        )
    for item in items.values():
        if (
            item_data["name"] == item["name"]
            and item_data["store_id"] == item["store_id"]
        ):
            abort(400, message=f"Item already exists.")

    item_id = uuid.uuid4().hex
    item = {**item_data, "id": item_id}
    items[item_id] = item

    return item


@app.get("/item")
def get_all_items():
    return {"items": list(items.values())}


@app.get("/store/<string:store_id>")
def get_store(store_id):
    try:
        # Here you might also want to add the items in this store
        # We'll do that later on in the course
        return stores[store_id]
    except KeyError:
        abort(404, message="Store not found.")


@app.post("/store")
def create_store():
    store_data = request.get_json()
    if "name" not in store_data:
        abort(
            400,
            message="Bad request. Ensure 'name' is included in the JSON payload.",
        )
    for store in stores.values():
        if store_data["name"] == store["name"]:
            abort(400, message=f"Store already exists.")

    store_id = uuid.uuid4().hex
    store = {**store_data, "id": store_id}
    stores[store_id] = store

    return store


@app.get("/store")
def get_stores():
    return {"stores": list(stores.values())}


================================================
FILE: docs/docs/05_flask_smorest/04_new_endpoints_for_api/start/db.py
================================================
"""
db.py
---

Later on, this file will be replaced by SQLAlchemy. For now, it mimics a database.
Our data storage is:
    - stores have a unique ID and a name
    - items have a unique ID, a name, a price, and a store ID.
"""

stores = {}
items = {}


================================================
FILE: docs/docs/05_flask_smorest/04_new_endpoints_for_api/start/requirements.txt
================================================
flask
flask-smorest
python-dotenv

================================================
FILE: docs/docs/05_flask_smorest/05_reload_api_docker_container/README.md
================================================
---
title: "Reloading API code in Docker container"
description: "Learn how to get your code instantly synced up to the Docker container, so that every time you make a code change it restarts the app in the container and uses the latest code."
ctslug: reloading-api-code-in-docker-container
---

# Reloading API code in Docker container

## Updating Dockerfile to use `requirements.txt`

This is the Dockerfile as we've got it:

```dockerfile
FROM python:3.10
EXPOSE 5000
WORKDIR /app
RUN pip install flask
COPY . .
CMD ["flask", "run", "--host", "0.0.0.0"]
```

But there is a problem! It doesn't use the `requirements.txt`, so it only installs Flask as a dependency.

We want to add `requirements.txt` and install the dependencies from it. You might be tempted to move the `COPY` line above the `RUN` line, and then install it with `pip install -r requirements.txt`.

But there's a better way!

```dockerfile
FROM python:3.10
EXPOSE 5000
WORKDIR /app
COPY ./requirements.txt requirements.txt
RUN pip install --no-cache-dir --upgrade -r requirements.txt
COPY . .
CMD ["flask", "run", "--host", "0.0.0.0"]
```

Here we:

- Add a new `COPY` line that copies the `requirements.txt` file into the image. This creates a new cached layer, so that if the `requirements.txt` file doesn't change, this line and the following `RUN` line don't run again.
- Change the `pip install` code to use `--no-cache-dir --upgrade`. This makes sure that we don't use any pre-existing pip caches when installing, and also upgrades libraries to the latest version if necessary.

## Running the container with volumes for hot reloading

Up to now, we've been re-building the Docker image and re-running the container each time we make a code change.

This is a bit of a time sink, and a bit annoying to do! Let's do it so that the Docker container runs the code that we're editing. That way, when we make a change to the code, the Flask app should restart and use the new code.

All we have to do is:

1. Build the Docker image
2. Run the image, but replace the contents of the image's `/app` directory (where the code is) by the contents of our source code folder in the host machine.

So, first build the Docker image:

```
docker build -t flask-smorest-api .
```

Once that's done, the image has an `/app` directory which contains the source code as it was copied from the host machine during the build stage.

So at this point, we _can_ run a container from this image, and it will run the app _as it was when it was built_:

```
docker run -dp 5000:5000 flask-smorest-api
```

This should just work, and you can try it out in the Insomnia REST Client to make sure the endpoints all work.

But like we said earlier, when we make changes to the code we'll have to rebuild and rerun.

So instead, what we can do is run the image, but replace the image's `/app` directory with the host's source code folder.

That will cause the source code to change in the Docker container while it's running. And, since we've ran Flask with debug mode on, the Flask app will automatically restart when the code changes.

To do so, stop the running container (if you have one running), and use this command instead:

```
docker run -dp 5000:5000 -w /app -v "$(pwd):/app" flask-smorest-api
```

:::info Windows command
The command on Windows varies depending on what terminal application you use. Here are some of the most popular ones!

**PowerShell**

```
docker run -dp 5000:5000 -w //app -v "$(Get-Location)://app" flask-smorest-api
```

**Git Bash**

```
docker run -dp 5000:5000 -w //app -v "//$(pwd)://app" flask-smorest-api
```

**Command Prompt (CMD)**

```
docker run -dp 5000:5000 -w //app -v "%cd%://app" flask-smorest-api
```
:::

- `-dp 5000:5000` - same as before. Run in detached (background) mode and create a port mapping.
- `-w /app` - sets the container's present working directory where the command will run from.
- `-v "$(pwd):/app"` - bind mount (link) the host's present directory to the container's `/app` directory. Note: Docker requires absolute paths for binding mounts, so in this example we use `pwd` for printing the absolute path of the working directory instead of typing it manually.
- `flask-smorest-api` - the image to use.

And with this, your Docker container now is running the code as shown in your IDE. Plus, since Flask is running with debug mode on, the Flask app will restart when you make code changes!

:::info
Using this kind of volume mapping only makes sense _during development_. When you share your Docker image or deploy it, you won't be sharing anything from the host to the container. That's why it's still important to include the original source code in the image when you build it.
:::

Just to recap, here are the two ways we've seen to run your Docker container:

![Diagram showing two ways of running a Docker container from a built image, with and without volume mapping](https://res.cloudinary.com/teclado/image/upload/v1689180724/courses/rest-apis-flask-python/build-with-without-volume_a7mig8.png)

================================================
FILE: docs/docs/05_flask_smorest/05_reload_api_docker_container/end/.flaskenv
================================================
FLASK_APP=app
FLASK_DEBUG=True

================================================
FILE: docs/docs/05_flask_smorest/05_reload_api_docker_container/end/Dockerfile
================================================
FROM python:3.10
EXPOSE 5000
WORKDIR /app
COPY ./requirements.txt requirements.txt
RUN pip install --no-cache-dir --upgrade -r requirements.txt
COPY . .
CMD ["flask", "run", "--host", "0.0.0.0"]

================================================
FILE: docs/docs/05_flask_smorest/05_reload_api_docker_container/end/app.py
================================================
import uuid
from flask import Flask, request
from flask_smorest import abort

from db import stores, items


app = Flask(__name__)


@app.get("/item/<string:item_id>")
def get_item(item_id):
    try:
        return items[item_id]
    except KeyError:
        abort(404, message="Item not found.")


@app.post("/item")
def create_item():
    item_data = request.get_json()
    # Here not only we need to validate data exists,
    # But also what type of data. Price should be a float,
    # for example.
    if (
        "price" not in item_data
        or "store_id" not in item_data
        or "name" not in item_data
    ):
        abort(
            400,
            message="Bad request. Ensure 'price', 'store_id', and 'name' are included in the JSON payload.",
        )
    for item in items.values():
        if (
            item_data["name"] == item["name"]
            and item_data["store_id"] == item["store_id"]
        ):
            abort(400, message=f"Item already exists.")

    item_id = uuid.uuid4().hex
    item = {**item_data, "id": item_id}
    items[item_id] = item

    return item


@app.delete("/item/<string:item_id>")
def delete_item(item_id):
    try:
        del items[item_id]
        return {"message": "Item deleted."}
    except KeyError:
        abort(404, message="Item not found.")


@app.put("/item/<string:item_id>")
def update_item(item_id):
    item_data = request.get_json()
    # There's  more validation to do here!
    # Like making sure price is a number, and also both items are optional
    # Difficult to do with an if statement...
    if "price" not in item_data or "name" not in item_data:
        abort(
            400,
            message="Bad request. Ensure 'price', and 'name' are included in the JSON payload.",
        )
    try:
        item = items[item_id]

        # https://blog.teclado.com/python-dictionary-merge-update-operators/
        item |= item_data

        return item
    except KeyError:
        abort(404, message="Item not found.")


@app.get("/item")
def get_all_items():
    return {"items": list(items.values())}


@app.get("/store/<string:store_id>")
def get_store(store_id):
    try:
        # Here you might also want to add the items in this store
        # We'll do that later on in the course
        return stores[store_id]
    except KeyError:
        abort(404, message="Store not found.")


@app.post("/store")
def create_store():
    store_data = request.get_json()
    if "name" not in store_data:
        abort(
            400,
            message="Bad request. Ensure 'name' is included in the JSON payload.",
        )
    for store in stores.values():
        if store_data["name"] == store["name"]:
            abort(400, message=f"Store already exists.")

    store_id = uuid.uuid4().hex
    store = {**store_data, "id": store_id}
    stores[store_id] = store

    return store


@app.delete("/store/<string:store_id>")
def delete_store(store_id):
    try:
        del stores[store_id]
        return {"message": "Store deleted."}
    except KeyError:
        abort(404, message="Store not found.")


@app.get("/store")
def get_stores():
    return {"stores": list(stores.values())}


================================================
FILE: docs/docs/05_flask_smorest/05_reload_api_docker_container/end/db.py
================================================
"""
db.py
---

Later on, this file will be replaced by SQLAlchemy. For now, it mimics a database.
Our data storage is:
    - stores have a unique ID and a name
    - items have a unique ID, a name, a price, and a store ID.
"""

stores = {}
items = {}


================================================
FILE: docs/docs/05_flask_smorest/05_reload_api_docker_container/end/requirements.txt
================================================
flask
flask-smorest
python-dotenv

================================================
FILE: docs/docs/05_flask_smorest/05_reload_api_docker_container/start/.flaskenv
================================================
FLASK_APP=app
FLASK_DEBUG=True

================================================
FILE: docs/docs/05_flask_smorest/05_reload_api_docker_container/start/Dockerfile
================================================
FROM python:3.10
EXPOSE 5000
WORKDIR /app
RUN pip install flask
COPY . .
CMD ["flask", "run", "--host", "0.0.0.0"]

================================================
FILE: docs/docs/05_flask_smorest/05_reload_api_docker_container/start/app.py
================================================
import uuid
from flask import Flask, request
from flask_smorest import abort

from db import stores, items


app = Flask(__name__)


@app.get("/item/<string:item_id>")
def get_item(item_id):
    try:
        return items[item_id]
    except KeyError:
        abort(404, message="Item not found.")


@app.post("/item")
def create_item():
    item_data = request.get_json()
    # Here not only we need to validate data exists,
    # But also what type of data. Price should be a float,
    # for example.
    if (
        "price" not in item_data
        or "store_id" not in item_data
        or "name" not in item_data
    ):
        abort(
            400,
            message="Bad request. Ensure 'price', 'store_id', and 'name' are included in the JSON payload.",
        )
    for item in items.values():
        if (
            item_data["name"] == item["name"]
            and item_data["store_id"] == item["store_id"]
        ):
            abort(400, message=f"Item already exists.")

    item_id = uuid.uuid4().hex
    item = {**item_data, "id": item_id}
    items[item_id] = item

    return item


@app.delete("/item/<string:item_id>")
def delete_item(item_id):
    try:
        del items[item_id]
        return {"message": "Item deleted."}
    except KeyError:
        abort(404, message="Item not found.")


@app.put("/item/<string:item_id>")
def update_item(item_id):
    item_data = request.get_json()
    # There's  more validation to do here!
    # Like making sure price is a number, and also both items are optional
    # Difficult to do with an if statement...
    if "price" not in item_data or "name" not in item_data:
        abort(
            400,
            message="Bad request. Ensure 'price', and 'name' are included in the JSON payload.",
        )
    try:
        item = items[item_id]

        # https://blog.teclado.com/python-dictionary-merge-update-operators/
        item |= item_data

        return item
    except KeyError:
        abort(404, message="Item not found.")


@app.get("/item")
def get_all_items():
    return {"items": list(items.values())}


@app.get("/store/<string:store_id>")
def get_store(store_id):
    try:
        # Here you might also want to add the items in this store
        # We'll do that later on in the course
        return stores[store_id]
    except KeyError:
        abort(404, message="Store not found.")


@app.post("/store")
def create_store():
    store_data = request.get_json()
    if "name" not in store_data:
        abort(
            400,
            message="Bad request. Ensure 'name' is included in the JSON payload.",
        )
    for store in stores.values():
        if store_data["name"] == store["name"]:
            abort(400, message=f"Store already exists.")

    store_id = uuid.uuid4().hex
    store = {**store_data, "id": store_id}
    stores[store_id] = store

    return store


@app.delete("/store/<string:store_id>")
def delete_store(store_id):
    try:
        del stores[store_id]
        return {"message": "Store deleted."}
    except KeyError:
        abort(404, message="Store not found.")


@app.get("/store")
def get_stores():
    return {"stores": list(stores.values())}


================================================
FILE: docs/docs/05_flask_smorest/05_reload_api_docker_container/start/db.py
================================================
"""
db.py
---

Later on, this file will be replaced by SQLAlchemy. For now, it mimics a database.
Our data storage is:
    - stores have a unique ID and a name
    - items have a unique ID, a name, a price, and a store ID.
"""

stores = {}
items = {}


================================================
FILE: docs/docs/05_flask_smorest/05_reload_api_docker_container/start/requirements.txt
================================================
flask
flask-smorest
python-dotenv

================================================
FILE: docs/docs/05_flask_smorest/06_api_with_method_views/README.md
================================================
---
title: How to use Blueprints and MethodViews
description: Flask-Smorest MethodViews allow us to simplify API Resources by defining all methods that interact with the resource in one Python class.
ctslug: how-to-use-flask-smorest-methodviews-blueprints
---

# How to use Flask-Smorest MethodViews and Blueprints

Let's improve the structure of our code by splitting items and stores endpoints into their own files.

Let's create a `resources` folder, and inside it create `item.py` and `store.py`.

## Creating a blueprint for each related group of resources

### `resources/store.py`

Let's start in `store.py`, and create a `Blueprint`:

```py title="resources/store.py"
import uuid
from flask import request
from flask.views import MethodView
from flask_smorest import Blueprint, abort
from db import stores


blp = Blueprint("stores", __name__, description="Operations on stores")
```

The `Blueprint` arguments are the same as the Flask `Blueprint`[^1], with an added optional `description` keyword argument:

1. `"stores"` is the name of the blueprint. This will be shown in the documentation and is prepended to the endpoint names when you use `url_for` (we won't use it).
2. `__name__` is the "import name".
3. The `description` will be shown in the documentation UI.


Now that we've got this, let's add our `MethodView`s. These are classes where each method maps to one endpoint. The interesting thing is that method names are important:

```py title="resources/store.py"
@blp.route("/store/<string:store_id>")
class Store(MethodView):
    def get(self, store_id):
        pass

    def delete(self, store_id):
        pass
```

Two things are going on here:

1. The endpoint is associated to the `MethodView` class. Here, the class is called `Store` and the endpoint is `/store/<string:store_id>`.
2. There are two methods inside the `Store` class: `get` and `delete`. These are going to map directly to `GET /store/<string:store_id>` and `DELETE /store/<string:store_id>`.

Now we can copy the code from earlier into each of the methods:

```py title="resources/store.py"
@blp.route("/store/<string:store_id>")
class Store(MethodView):
    def get(self, store_id):
        try:
            return stores[store_id]
        except KeyError:
            abort(404, message="Store not found.")

    def delete(self, store_id):
        try:
            del stores[store_id]
            return {"message": "Store deleted."}
        except KeyError:
            abort(404, message="Store not found.")
```

Now, still inside the same file, we can add another `MethodView` with a different endpoint, for the `/store` route:

```py title="resources/store.py"
@blp.route("/store")
class StoreList(MethodView):
    def get(self):
        return {"stores": list(stores.values())}

    def post(self):
        store_data = request.get_json()
        if "name" not in store_data:
            abort(
                400,
                message="Bad request. Ensure 'name' is included in the JSON payload.",
            )
        for store in stores.values():
            if store_data["name"] == store["name"]:
                abort(400, message=f"Store already exists.")

        store_id = uuid.uuid4().hex
        store = {**store_data, "id": store_id}
        stores[store_id] = store

        return store
```

### `resources/item.py`

Let's do the same thing with the `resources/item.py` file:

```py title="resources/item.py"
import uuid
from flask import request
from flask.views import MethodView
from flask_smorest import Blueprint, abort

from db import items

blp = Blueprint("Items", __name__, description="Operations on items")


@blp.route("/item/<string:item_id>")
class Item(MethodView):
    def get(self, item_id):
        try:
            return items[item_id]
        except KeyError:
            abort(404, message="Item not found.")

    def delete(self, item_id):
        try:
            del items[item_id]
            return {"message": "Item deleted."}
        except KeyError:
            abort(404, message="Item not found.")

    def put(self, item_id):
        item_data = request.get_json()
        # There's  more validation to do here!
        # Like making sure price is a number, and also both items are optional
        # Difficult to do with an if statement...
        if "price" not in item_data or "name" not in item_data:
            abort(
                400,
                message="Bad request. Ensure 'price', and 'name' are included in the JSON payload.",
            )
        try:
            item = items[item_id]

            # https://blog.teclado.com/python-dictionary-merge-update-operators/
            item |= item_data

            return item
        except KeyError:
            abort(404, message="Item not found.")


@blp.route("/item")
class ItemList(MethodView):
    def get(self):
        return {"items": list(items.values())}

    def post(self):
        item_data = request.get_json()
        # Here not only we need to validate data exists,
        # But also what type of data. Price should be a float,
        # for example.
        if (
            "price" not in item_data
            or "store_id" not in item_data
            or "name" not in item_data
        ):
            abort(
                400,
                message="Bad request. Ensure 'price', 'store_id', and 'name' are included in the JSON payload.",
            )
        for item in items.values():
            if (
                item_data["name"] == item["name"]
                and item_data["store_id"] == item["store_id"]
            ):
                abort(400, message=f"Item already exists.")

        item_id = uuid.uuid4().hex
        item = {**item_data, "id": item_id}
        items[item_id] = item

        return item
```

## Import blueprints and Flask-Smorest configuration

Finally, we have to import the `Blueprints` inside `app.py`, and register them with Flask-Smorest:

```py title="app.py"
from flask import Flask
from flask_smorest import Api

from resources.item import blp as ItemBlueprint
from resources.store import blp as StoreBlueprint


app = Flask(__name__)

app.config["PROPAGATE_EXCEPTIONS"] = True
app.config["API_TITLE"] = "Stores REST API"
app.config["API_VERSION"] = "v1"
app.config["OPENAPI_VERSION"] = "3.0.3"
app.config["OPENAPI_URL_PREFIX"] = "/"
app.config["OPENAPI_SWAGGER_UI_PATH"] = "/swagger-ui"
app.config["OPENAPI_SWAGGER_UI_URL"] = "https://cdn.jsdelivr.net/npm/swagger-ui-dist/"

api = Api(app)

api.register_blueprint(ItemBlueprint)
api.register_blueprint(StoreBlueprint)
```

I've also added a few config variables to the `app.config`. The `PROPAGATE_EXCEPTIONS` value is used so that when an exception is raised in an extension, it is bubbled up to the main Flask app so you'd see it more easily.

The other config values are there for the documentation of our API, and they define things such as the API name and version, as well as information for the Swagger UI.

Now you should be able to go to `http://127.0.0.1:5000/swagger-ui` and see your Swagger documentation rendered out!

[^1]: [Flask Blueprint (Flask Official Documentation)](https://flask.palletsprojects.com/en/2.1.x/api/#flask.Blueprint)

================================================
FILE: docs/docs/05_flask_smorest/06_api_with_method_views/end/.flaskenv
================================================
FLASK_APP=app
FLASK_DEBUG=True

================================================
FILE: docs/docs/05_flask_smorest/06_api_with_method_views/end/Dockerfile
================================================
FROM python:3.10
EXPOSE 5000
WORKDIR /app
COPY ./requirements.txt requirements.txt
RUN pip install --no-cache-dir --upgrade -r requirements.txt
COPY . .
CMD ["flask", "run", "--host", "0.0.0.0"]

================================================
FILE: docs/docs/05_flask_smorest/06_api_with_method_views/end/app.py
================================================
from flask import Flask
from flask_smorest import Api

from resources.item import blp as ItemBlueprint
from resources.store import blp as StoreBlueprint


app = Flask(__name__)

app.config["PROPAGATE_EXCEPTIONS"] = True
app.config["API_TITLE"] = "Stores REST API"
app.config["API_VERSION"] = "v1"
app.config["OPENAPI_VERSION"] = "3.0.3"
app.config["OPENAPI_URL_PREFIX"] = "/"
app.config["OPENAPI_SWAGGER_UI_PATH"] = "/swagger-ui"
app.config["OPENAPI_SWAGGER_UI_URL"] = "https://cdn.jsdelivr.net/npm/swagger-ui-dist/"

api = Api(app)

api.register_blueprint(ItemBlueprint)
api.register_blueprint(StoreBlueprint)


================================================
FILE: docs/docs/05_flask_smorest/06_api_with_method_views/end/db.py
================================================
"""
db.py
---

Later on, this file will be replaced by SQLAlchemy. For now, it mimics a database.
Our data storage is:
    - stores have a unique ID and a name
    - items have a unique ID, a name, a price, and a store ID.
"""

stores = {}
items = {}


================================================
FILE: docs/docs/05_flask_smorest/06_api_with_method_views/end/requirements.txt
================================================
flask
flask-smorest
python-dotenv

================================================
FILE: docs/docs/05_flask_smorest/06_api_with_method_views/end/resources/__init__.py
================================================



================================================
FILE: docs/docs/05_flask_smorest/06_api_with_method_views/end/resources/item.py
================================================
import uuid
from flask import request
from flask.views import MethodView
from flask_smorest import Blueprint, abort

from db import items

blp = Blueprint("Items", __name__, description="Operations on items")


@blp.route("/item/<string:item_id>")
class Item(MethodView):
    def get(self, item_id):
        try:
            return items[item_id]
        except KeyError:
            abort(404, message="Item not found.")

    def delete(self, item_id):
        try:
            del items[item_id]
            return {"message": "Item deleted."}
        except KeyError:
            abort(404, message="Item not found.")

    def put(self, item_id):
        item_data = request.get_json()
        # There's  more validation to do here!
        # Like making sure price is a number, and also both items are optional
        # Difficult to do with an if statement...
        if "price" not in item_data or "name" not in item_data:
            abort(
                400,
                message="Bad request. Ensure 'price', and 'name' are included in the JSON payload.",
            )
        try:
            item = items[item_id]

            # https://blog.teclado.com/python-dictionary-merge-update-operators/
            item |= item_data

            return item
        except KeyError:
            abort(404, message="Item not found.")


@blp.route("/item")
class ItemList(MethodView):
    def get(self):
        return {"items": list(items.values())}

    def post(self):
        item_data = request.get_json()
        # Here not only we need to validate data exists,
        # But also what type of data. Price should be a float,
        # for example.
        if (
            "price" not in item_data
            or "store_id" not in item_data
            or "name" not in item_data
        ):
            abort(
                400,
                message="Bad request. Ensure 'price', 'store_id', and 'name' are included in the JSON payload.",
            )
        for item in items.values():
            if (
                item_data["name"] == item["name"]
                and item_data["store_id"] == item["store_id"]
            ):
                abort(400, message=f"Item already exists.")

        item_id = uuid.uuid4().hex
        item = {**item_data, "id": item_id}
        items[item_id] = item

        return item


================================================
FILE: docs/docs/05_flask_smorest/06_api_with_method_views/end/resources/store.py
================================================
import uuid
from flask import request
from flask.views import MethodView
from flask_smorest import Blueprint, abort
from db import stores


blp = Blueprint("Stores", __name__, description="Operations on stores")


@blp.route("/store/<string:store_id>")
class Store(MethodView):
    def get(self, store_id):
        try:
            # You presumably would want to include the store's items here too
            # More on that when we look at databases
            return stores[store_id]
        except KeyError:
            abort(404, message="Store not found.")

    def delete(self, store_id):
        try:
            del stores[store_id]
            return {"message": "Store deleted."}
        except KeyError:
            abort(404, message="Store not found.")


@blp.route("/store")
class StoreList(MethodView):
    def get(self):
        return {"stores": list(stores.values())}

    def post(self):
        store_data = request.get_json()
        if "name" not in store_data:
            abort(
                400,
                message="Bad request. Ensure 'name' is included in the JSON payload.",
            )
        for store in stores.values():
            if store_data["name"] == store["name"]:
                abort(400, message=f"Store already exists.")

        store_id = uuid.uuid4().hex
        store = {**store_data, "id": store_id}
        stores[store_id] = store

        return store


================================================
FILE: docs/docs/05_flask_smorest/06_api_with_method_views/start/.flaskenv
================================================
FLASK_APP=app
FLASK_DEBUG=True

================================================
FILE: docs/docs/05_flask_smorest/06_api_with_method_views/start/Dockerfile
================================================
FROM python:3.10
EXPOSE 5000
WORKDIR /app
COPY ./requirements.txt requirements.txt
RUN pip install --no-cache-dir --upgrade -r requirements.txt
COPY . .
CMD ["flask", "run", "--host", "0.0.0.0"]

================================================
FILE: docs/docs/05_flask_smorest/06_api_with_method_views/start/app.py
================================================
import uuid
from flask import Flask, request
from flask_smorest import abort

from db import stores, items


app = Flask(__name__)


@app.get("/item/<string:id>")
def get_item(item_id):
    try:
        return items[item_id]
    except KeyError:
        abort(404, message="Item not found.")


@app.delete("/item/<string:id>")
def delete_item(item_id):
    try:
        del items[item_id]
        return {"message": "Item deleted."}
    except KeyError:
        abort(404, message="Item not found.")


@app.put("/item/<string:id>")
def update_item(item_id):
    item_data = request.get_json()
    # There's  more validation to do here!
    # Like making sure price is a number, and also both items are optional
    # Difficult to do with an if statement...
    if "price" not in item_data or "name" not in item_data:
        abort(
            400,
            message="Bad request. Ensure 'price', and 'name' are included in the JSON payload.",
        )
    try:
        item = items[item_id]

        # https://blog.teclado.com/python-dictionary-merge-update-operators/
        item |= item_data

        return item
    except KeyError:
        abort(404, message="Item not found.")


@app.get("/item")
def get_all_items():
    return {"items": list(items.values())}


@app.post("/item")
def create_item():
    item_data = request.get_json()
    # Here not only we need to validate data exists,
    # But also what type of data. Price should be a float,
    # for example.
    if (
        "price" not in item_data
        or "store_id" not in item_data
        or "name" not in item_data
    ):
        abort(
            400,
            message="Bad request. Ensure 'price', 'store_id', and 'name' are included in the JSON payload.",
        )
    for item in items.values():
        if (
            item_data["name"] == item["name"]
            and item_data["store_id"] == item["store_id"]
        ):
            abort(400, message=f"Item already exists.")

    item_id = uuid.uuid4().hex
    item = {**item_data, "id": item_id}
    items[item_id] = item

    return item


@app.get("/store/<string:id>")
def get_store(store_id):
    try:
        # You presumably would want to include the store's items here too
        # More on that when we look at databases
        return stores[store_id]
    except KeyError:
        abort(404, message="Store not found.")


@app.delete("/store/<string:id>")
def delete_store(store_id):
    try:
        del stores[store_id]
        return {"message": "Store deleted."}
    except KeyError:
        abort(404, message="Store not found.")


@app.get("/store")
def get_stores():
    return {"stores": list(stores.values())}


@app.post("/store")
def create_store():
    store_data = request.get_json()
    if "name" not in store_data:
        abort(
            400,
            message="Bad request. Ensure 'name' is included in the JSON payload.",
        )
    for store in stores.values():
        if store_data["name"] == store["name"]:
            abort(400, message=f"Store already exists.")

    store_id = uuid.uuid4().hex
    store = {**store_data, "id": store_id}
    stores[store_id] = store

    return store


================================================
FILE: docs/docs/05_flask_smorest/06_api_with_method_views/start/db.py
================================================
"""
db.py
---

Later on, this file will be replaced by SQLAlchemy. For now, it mimics a database.
Our data storage is:
    - stores have a unique ID and a name
    - items have a unique ID, a name, a price, and a store ID.
"""

stores = {}
items = {}


================================================
FILE: docs/docs/05_flask_smorest/06_api_with_method_views/start/requirements.txt
================================================
flask
python-dotenv

================================================
FILE: docs/docs/05_flask_smorest/07_marshmallow_schemas/README.md
================================================
---
title: Adding marshmallow schemas
description: A marshmallow schema is useful for validation and serialization. Learn how to write them in this lecture.
ctslug: adding-marshmallow-schemas
---

# Adding marshmallow schemas

Something that we're lacking in our API at the moment is validation. We've done a _tiny_ bit of it with this kind of code:

```py
if (
    "price" not in item_data
    or "store_id" not in item_data
    or "name" not in item_data
):
    abort(
        400,
        message="Bad request. Ensure 'price', 'store_id', and 'name' are included in the JSON payload.",
    )
```

But there's so much more we can do. For starters, some data points may be optional in some endpoints. We also want to check the data type is correct (i.e. `price` shouldn't be a string, for example).

To do this kind of checking we can construct a massive `if` statement, or we can use a library that is made specifically for it.

The `marshmallow`[^1] library is used to define _what_ data fields we want, and then we can pass incoming data through the validator. We can also go the other way round, and give it a Python object which `marshmallow` then turns into a dictionary.

## Writing the `ItemSchema`

Here's the definition of an `Item` using `marshmallow` (this is called a **schema**):

```py title="schemas.py"
from marshmallow import Schema, fields


class ItemSchema(Schema):
    id = fields.Str(dump_only=True)
    name = fields.Str(required=True)
    price = fields.Float(required=True)
    store_id = fields.Str(required=True)
```

A couple of weird things maybe!

The `id` field is a string, but it has the `dump_only=True` argument. This means that when we use marshmallow to _validate incoming data_, the `id` field won't be used or expected. However, when we use marshmallow to _serialize_ data to be returned to a client, the `id` field will be included in the output.

The other fields will be used for both validation and serialization, and since they have the `required=True` argument, that means that when we do validation if the fields are not present, an error will be raised.

`marshmallow` will also check the data type with `fields.Float` and `fields.Int`.

## Writing the `ItemUpdateSchema`

Something that even to do this day sits a bit weird with me is having multiple different schemas for different applications.

When we want to update an Item, we have different requirements than when we want to create an item.

The main difference is that the incoming data to our API when we update an item is different than when we create one. Fields are optional, such that not all item fields should be required. Also, you may not want to allow certain fields _at all_.

This is the `ItemUpdateSchema`:

```py title="schemas.py"
class ItemUpdateSchema(Schema):
    name = fields.Str()
    price = fields.Float()
```

As you can see, these are not `required=True`. I've also taken off the `id` and `store_id` fields, because:

- This schema will only be used for incoming data, and we will never receive an `id`.
- We don't want clients to be able to change the `store_id` of an item. If you wanted to allow this, you can add the `store_id` field here as well.

## Writing the `StoreSchema`

```py title="schemas.py"
class StoreSchema(Schema):
    id = fields.Str(dump_only=True)
    name = fields.Str(required=True)
```

There's not much to explain here! Similar to the `ItemSchema`, we have `id` and `name` since those are the only fields we need for a store.

================================================
FILE: docs/docs/05_flask_smorest/07_marshmallow_schemas/end/.flaskenv
================================================
FLASK_APP=app
FLASK_DEBUG=True

================================================
FILE: docs/docs/05_flask_smorest/07_marshmallow_schemas/end/Dockerfile
================================================
FROM python:3.10
EXPOSE 5000
WORKDIR /app
COPY ./requirements.txt requirements.txt
RUN pip install --no-cache-dir --upgrade -r requirements.txt
COPY . .
CMD ["flask", "run", "--host", "0.0.0.0"]

================================================
FILE: docs/docs/05_flask_smorest/07_marshmallow_schemas/end/app.py
================================================
from flask import Flask
from flask_smorest import Api

from resources.item import blp as ItemBlueprint
from resources.store import blp as StoreBlueprint


app = Flask(__name__)

app.config["PROPAGATE_EXCEPTIONS"] = True
app.config["API_TITLE"] = "Stores REST API"
app.config["API_VERSION"] = "v1"
app.config["OPENAPI_VERSION"] = "3.0.3"
app.config["OPENAPI_URL_PREFIX"] = "/"
app.config["OPENAPI_SWAGGER_UI_PATH"] = "/swagger-ui"
app.config["OPENAPI_SWAGGER_UI_URL"] = "https://cdn.jsdelivr.net/npm/swagger-ui-dist/"

api = Api(app)

api.register_blueprint(ItemBlueprint)
api.register_blueprint(StoreBlueprint)


================================================
FILE: docs/docs/05_flask_smorest/07_marshmallow_schemas/end/db.py
================================================
"""
db.py
---

Later on, this file will be replaced by SQLAlchemy. For now, it mimics a database.
Our data storage is:
    - stores have a unique ID and a name
    - items have a unique ID, a name, a price, and a store ID.
"""

stores = {}
items = {}


================================================
FILE: docs/docs/05_flask_smorest/07_marshmallow_schemas/end/requirements.txt
================================================
flask
flask-smorest
python-dotenv
marshmallow

================================================
FILE: docs/docs/05_flask_smorest/07_marshmallow_schemas/end/resources/__init__.py
================================================



================================================
FILE: docs/docs/05_flask_smorest/07_marshmallow_schemas/end/resources/item.py
================================================
import uuid
from flask import request
from flask.views import MethodView
from flask_smorest import Blueprint, abort

from db import items

blp = Blueprint("Items", __name__, description="Operations on items")


@blp.route("/item/<string:item_id>")
class Item(MethodView):
    def get(self, item_id):
        try:
            return items[item_id]
        except KeyError:
            abort(404, message="Item not found.")

    def delete(self, item_id):
        try:
            del items[item_id]
            return {"message": "Item deleted."}
        except KeyError:
            abort(404, message="Item not found.")

    def put(self, item_id):
        item_data = request.get_json()
        # There's  more validation to do here!
        # Like making sure price is a number, and also both items are optional
        # Difficult to do with an if statement...
        if "price" not in item_data or "name" not in item_data:
            abort(
                400,
                message="Bad request. Ensure 'price', and 'name' are included in the JSON payload.",
            )
        try:
            item = items[item_id]

            # https://blog.teclado.com/python-dictionary-merge-update-operators/
            item |= item_data

            return item
        except KeyError:
            abort(404, message="Item not found.")


@blp.route("/item")
class ItemList(MethodView):
    def get(self):
        return {"items": list(items.values())}

    def post(self):
        item_data = request.get_json()
        # Here not only we need to validate data exists,
        # But also what type of data. Price should be a float,
        # for example.
        if (
            "price" not in item_data
            or "store_id" not in item_data
            or "name" not in item_data
        ):
            abort(
                400,
                message="Bad request. Ensure 'price', 'store_id', and 'name' are included in the JSON payload.",
            )
        for item in items.values():
            if (
                item_data["name"] == item["name"]
                and item_data["store_id"] == item["store_id"]
            ):
                abort(400, message=f"Item already exists.")

        item_id = uuid.uuid4().hex
        item = {**item_data, "id": item_id}
        items[item_id] = item

        return item


================================================
FILE: docs/docs/05_flask_smorest/07_marshmallow_schemas/end/resources/store.py
================================================
import uuid
from flask import request
from flask.views import MethodView
from flask_smorest import Blueprint, abort
from db import stores


blp = Blueprint("Stores", __name__, description="Operations on stores")


@blp.route("/store/<string:store_id>")
class Store(MethodView):
    def get(cls, store_id):
        try:
            # You presumably would want to include the store's items here too
            # More on that when we look at databases
            return stores[store_id]
        except KeyError:
            abort(404, message="Store not found.")

    def delete(cls, store_id):
        try:
            del stores[store_id]
            return {"message": "Store deleted."}
        except KeyError:
            abort(404, message="Store not found.")


@blp.route("/store")
class StoreList(MethodView):
    def get(cls):
        return {"stores": list(stores.values())}

    def post(cls):
        store_data = request.get_json()
        if "name" not in store_data:
            abort(
                400,
                message="Bad request. Ensure 'name' is included in the JSON payload.",
            )
        for store in stores.values():
            if store_data["name"] == store["name"]:
                abort(400, message=f"Store already exists.")

        store_id = uuid.uuid4().hex
        store = {**store_data, "id": store_id}
        stores[store_id] = store

        return store


================================================
FILE: docs/docs/05_flask_smorest/07_marshmallow_schemas/end/schemas.py
================================================
from marshmallow import Schema, fields


class ItemSchema(Schema):
    id = fields.Str(dump_only=True)
    name = fields.Str(required=True)
    price = fields.Float(required=True)
    store_id = fields.Str(required=True)


class ItemUpdateSchema(Schema):
    name = fields.Str()
    price = fields.Float()


class StoreSchema(Schema):
    id = fields.Str(dump_only=True)
    name = fields.Str(required=True)


================================================
FILE: docs/docs/05_flask_smorest/07_marshmallow_schemas/start/.flaskenv
================================================
FLASK_APP=app
FLASK_DEBUG=True

================================================
FILE: docs/docs/05_flask_smorest/07_marshmallow_schemas/start/Dockerfile
================================================
FROM python:3.10
EXPOSE 5000
WORKDIR /app
COPY ./requirements.txt requirements.txt
RUN pip install --no-cache-dir --upgrade -r requirements.txt
COPY . .
CMD ["flask", "run", "--host", "0.0.0.0"]

================================================
FILE: docs/docs/05_flask_smorest/07_marshmallow_schemas/start/app.py
================================================
from flask import Flask
from flask_smorest import Api

from resources.item import blp as ItemBlueprint
from resources.store import blp as StoreBlueprint


app = Flask(__name__)

app.config["PROPAGATE_EXCEPTIONS"] = True
app.config["API_TITLE"] = "Stores REST API"
app.config["API_VERSION"] = "v1"
app.config["OPENAPI_VERSION"] = "3.0.3"
app.config["OPENAPI_URL_PREFIX"] = "/"
app.config["OPENAPI_SWAGGER_UI_PATH"] = "/swagger-ui"
app.config["OPENAPI_SWAGGER_UI_URL"] = "https://cdn.jsdelivr.net/npm/swagger-ui-dist/"

api = Api(app)

api.register_blueprint(ItemBlueprint)
api.register_blueprint(StoreBlueprint)


================================================
FILE: docs/docs/05_flask_smorest/07_marshmallow_schemas/start/db.py
================================================
"""
db.py
---

Later on, this file will be replaced by SQLAlchemy. For now, it mimics a database.
Our data storage is:
    - stores have a unique ID and a name
    - items have a unique ID, a name, a price, and a store ID.
"""

stores = {}
items = {}


================================================
FILE: docs/docs/05_flask_smorest/07_marshmallow_schemas/start/requirements.txt
================================================
flask
flask-smorest
python-dotenv

================================================
FILE: docs/docs/05_flask_smorest/07_marshmallow_schemas/start/resources/__init__.py
================================================



================================================
FILE: docs/docs/05_flask_smorest/07_marshmallow_schemas/start/resources/item.py
================================================
import uuid
from flask import request
from flask.views import MethodView
from flask_smorest import Blueprint, abort

from db import items

blp = Blueprint("Items", __name__, description="Operations on items")


@blp.route("/item/<string:item_id>")
class Item(MethodView):
    def get(self, item_id):
        try:
            return items[item_id]
        except KeyError:
            abort(404, message="Item not found.")

    def delete(self, item_id):
        try:
            del items[item_id]
            return {"message": "Item deleted."}
        except KeyError:
            abort(404, message="Item not found.")

    def put(self, item_id):
        item_data = request.get_json()
        # There's  more validation to do here!
        # Like making sure price is a number, and also both items are optional
        # Difficult to do with an if statement...
        if "price" not in item_data or "name" not in item_data:
            abort(
                400,
                message="Bad request. Ensure 'price', and 'name' are included in the JSON payload.",
            )
        try:
            item = items[item_id]

            # https://blog.teclado.com/python-dictionary-merge-update-operators/
            item |= item_data

            return item
        except KeyError:
            abort(404, message="Item not found.")


@blp.route("/item")
class ItemList(MethodView):
    def get(self):
        return {"items": list(items.values())}

    def post(self):
        item_data = request.get_json()
        # Here not only we need to validate data exists,
        # But also what type of data. Price should be a float,
        # for example.
        if (
            "price" not in item_data
            or "store_id" not in item_data
            or "name" not in item_data
        ):
            abort(
                400,
                message="Bad request. Ensure 'price', 'store_id', and 'name' are included in the JSON payload.",
            )
        for item in items.values():
            if (
                item_data["name"] == item["name"]
                and item_data["store_id"] == item["store_id"]
            ):
                abort(400, message=f"Item already exists.")

        item_id = uuid.uuid4().hex
        item = {**item_data, "id": item_id}
        items[item_id] = item

        return item


================================================
FILE: docs/docs/05_flask_smorest/07_marshmallow_schemas/start/resources/store.py
================================================
import uuid
from flask import request
from flask.views import MethodView
from flask_smorest import Blueprint, abort
from db import stores


blp = Blueprint("Stores", __name__, description="Operations on stores")


@blp.route("/store/<string:store_id>")
class Store(MethodView):
    def get(cls, store_id):
        try:
            # You presumably would want to include the store's items here too
            # More on that when we look at databases
            return stores[store_id]
        except KeyError:
            abort(404, message="Store not found.")

    def delete(cls, store_id):
        try:
            del stores[store_id]
            return {"message": "Store deleted."}
        except KeyError:
            abort(404, message="Store not found.")


@blp.route("/store")
class StoreList(MethodView):
    def get(cls):
        return {"stores": list(stores.values())}

    def post(cls):
        store_data = request.get_json()
        if "name" not in store_data:
            abort(
                400,
                message="Bad request. Ensure 'name' is included in the JSON payload.",
            )
        for store in stores.values():
            if store_data["name"] == store["name"]:
                abort(400, message=f"Store already exists.")

        store_id = uuid.uuid4().hex
        store = {**store_data, "id": store_id}
        stores[store_id] = store

        return store


================================================
FILE: docs/docs/05_flask_smorest/08_validation_with_marshmallow/README.md
================================================
---
title: Validation with marshmallow
description: We can use the marshmallow library to validate request data from our API clients.
ctslug: validation-with-marshmallow
---

# Validation with marshmallow

Now that we've got our schemas written, let's use them to validate incoming data to our API.

With Flask-Smorest, this couldn't be easier!

Let's start with `resources/item.py`

## Validation in `resources/item.py`

At the top of the file, import the schemas:

```py
from schemas import ItemSchema, ItemUpdateSchema
```

We have two sets of data that may be incoming (in the JSON body of a request): new items and updating items.

So let's go to the `ItemList#post` method and make a couple changes!

First, let's get rid of the existing data validation. Delete the highlighted lines below:

```py
def post(self):
    # highlight-start
    item_data = request.get_json()
    if (
        "price" not in item_data
        or "store_id" not in item_data
        or "name" not in item_data
    ):
        abort(
            400,
            message="Bad request. Ensure 'price', 'store_id', and 'name' are included in the JSON payload.",
        )
    # highlight-end
    for item in items.values():
        if (
            item_data["name"] == item["name"]
            and item_data["store_id"] == item["store_id"]
        ):
            abort(400, message=f"Item already exists.")

    item_id = uuid.uuid4().hex
    item = {**item_data, "id": item_id}
    items[item_id] = item

    return item
```

Now, I know what you're thinking! What about `item_data`? Do we not need to keep that?

When we use `marshmallow` for validation with Flask-Smorest, it will inject the validated data into our method for us.

Look at these two highlighted lines:

```py
# highlight-start
@blp.arguments(ItemSchema)
def post(self, item_data):
    # highlight-end
    for item in items.values():
        if (
            item_data["name"] == item["name"]
            and item_data["store_id"] == item["store_id"]
        ):
            abort(400, message=f"Item already exists.")

    item_id = uuid.uuid4().hex
    item = {**item_data, "id": item_id}
    items[item_id] = item

    return item
```

Nice!

Plus, doing this also adds to your Swagger UI documentation.

Let's do the same when updating items:

```py
# highlight-start
@blp.arguments(ItemUpdateSchema)
def put(self, item_data, item_id):
    # highlight-end
    try:
        item = items[item_id]
        item |= item_data

        return item
    except KeyError:
        abort(404, message="Item not found.")
```

:::caution Order of parameters
Be careful here since we've now got `item_data` and `item_id`. The URL arguments come in at the end. The injected arguments are passed first, so `item_data` goes before `item_id` in our function signature.
:::

## Validation in `resources/store.py`

Now let's do the same in `store.py`!

At the top of the file, import the schema:

```py
from schemas import StoreSchema
```

When creating a store, we'll have this:

```py
@blp.arguments(StoreSchema)
def post(cls, store_data):
        for store in stores.values():
            if store_data["name"] == store["name"]:
                abort(400, message=f"Store already exists.")

        store_id = uuid.uuid4().hex
        store = {**store_data, "id": store_id}
        stores[store_id] = store

        return store
```

================================================
FILE: docs/docs/05_flask_smorest/08_validation_with_marshmallow/end/.flaskenv
================================================
FLASK_APP=app
FLASK_DEBUG=True

================================================
FILE: docs/docs/05_flask_smorest/08_validation_with_marshmallow/end/Dockerfile
================================================
FROM python:3.10
EXPOSE 5000
WORKDIR /app
COPY ./requirements.txt requirements.txt
RUN pip install --no-cache-dir --upgrade -r requirements.txt
COPY . .
CMD ["flask", "run", "--host", "0.0.0.0"]

================================================
FILE: docs/docs/05_flask_smorest/08_validation_with_marshmallow/end/app.py
================================================
from flask import Flask
from flask_smorest import Api

from resources.item import blp as ItemBlueprint
from resources.store import blp as StoreBlueprint


app = Flask(__name__)

app.config["PROPAGATE_EXCEPTIONS"] = True
app.config["API_TITLE"] = "Stores REST API"
app.config["API_VERSION"] = "v1"
app.config["OPENAPI_VERSION"] = "3.0.3"
app.config["OPENAPI_URL_PREFIX"] = "/"
app.config["OPENAPI_SWAGGER_UI_PATH"] = "/swagger-ui"
app.config["OPENAPI_SWAGGER_UI_URL"] = "https://cdn.jsdelivr.net/npm/swagger-ui-dist/"

api = Api(app)

api.register_blueprint(ItemBlueprint)
api.register_blueprint(StoreBlueprint)


================================================
FILE: docs/docs/05_flask_smorest/08_validation_with_marshmallow/end/db.py
================================================
"""
db.py
---

Later on, this file will be replaced by SQLAlchemy. For now, it mimics a database.
Our data storage is:
    - stores have a unique ID and a name
    - items have a unique ID, a name, a price, and a store ID.
"""

stores = {}
items = {}


================================================
FILE: docs/docs/05_flask_smorest/08_validation_with_marshmallow/end/requirements.txt
================================================
flask
flask-smorest
python-dotenv
marshmallow

================================================
FILE: docs/docs/05_flask_smorest/08_validation_with_marshmallow/end/resources/__init__.py
================================================



================================================
FILE: docs/docs/05_flask_smorest/08_validation_with_marshmallow/end/resources/item.py
================================================
import uuid
from flask.views import MethodView
from flask_smorest import Blueprint, abort

from schemas import ItemSchema, ItemUpdateSchema
from db import items

blp = Blueprint("Items", __name__, description="Operations on items")


@blp.route("/item/<string:item_id>")
class Item(MethodView):
    def get(self, item_id):
        try:
            return items[item_id]
        except KeyError:
            abort(404, message="Item not found.")

    def delete(self, item_id):
        try:
            del items[item_id]
            return {"message": "Item deleted."}
        except KeyError:
            abort(404, message="Item not found.")

    @blp.arguments(ItemUpdateSchema)
    def put(self, item_data, item_id):
        try:
            item = items[item_id]

            # https://blog.teclado.com/python-dictionary-merge-update-operators/
            item |= item_data

            return item
        except KeyError:
            abort(404, message="Item not found.")


@blp.route("/item")
class ItemList(MethodView):
    def get(self):
        return {"items": list(items.values())}

    @blp.arguments(ItemSchema)
    def post(self, item_data):
        for item in items.values():
            if (
                item_data["name"] == item["name"]
                and item_data["store_id"] == item["store_id"]
            ):
                abort(400, message=f"Item already exists.")

        item_id = uuid.uuid4().hex
        item = {**item_data, "id": item_id}
        items[item_id] = item

        return item


================================================
FILE: docs/docs/05_flask_smorest/08_validation_with_marshmallow/end/resources/store.py
================================================
import uuid
from flask.views import MethodView
from flask_smorest import Blueprint, abort
from db import stores
from schemas import StoreSchema


blp = Blueprint("Stores", __name__, description="Operations on stores")


@blp.route("/store/<string:store_id>")
class Store(MethodView):
    def get(cls, store_id):
        try:
            # You presumably would want to include the store's items here too
            # More on that when we look at databases
            return stores[store_id]
        except KeyError:
            abort(404, message="Store not found.")

    def delete(cls, store_id):
        try:
            del stores[store_id]
            return {"message": "Store deleted."}
        except KeyError:
            abort(404, message="Store not found.")


@blp.route("/store")
class StoreList(MethodView):
    def get(cls):
        return {"stores": list(stores.values())}

    @blp.arguments(StoreSchema)
    def post(cls, store_data):
        for store in stores.values():
            if store_data["name"] == store["name"]:
                abort(400, message=f"Store already exists.")

        store_id = uuid.uuid4().hex
        store = {**store_data, "id": store_id}
        stores[store_id] = store

        return store


================================================
FILE: docs/docs/05_flask_smorest/08_validation_with_marshmallow/end/schemas.py
================================================
from marshmallow import Schema, fields


class ItemSchema(Schema):
    id = fields.Str(dump_only=True)
    name = fields.Str(required=True)
    price = fields.Float(required=True)
    store_id = fields.Str(required=True)


class ItemUpdateSchema(Schema):
    name = fields.Str()
    price = fields.Float()


class StoreSchema(Schema):
    id = fields.Str(dump_only=True)
    name = fields.Str(required=True)


================================================
FILE: docs/docs/05_flask_smorest/08_validation_with_marshmallow/start/.flaskenv
================================================
FLASK_APP=app
FLASK_DEBUG=True

================================================
FILE: docs/docs/05_flask_smorest/08_validation_with_marshmallow/start/Dockerfile
================================================
FROM python:3.10
EXPOSE 5000
WORKDIR /app
COPY ./requirements.txt requirements.txt
RUN pip install --no-cache-dir --upgrade -r requirements.txt
COPY . .
CMD ["flask", "run", "--host", "0.0.0.0"]

================================================
FILE: docs/docs/05_flask_smorest/08_validation_with_marshmallow/start/app.py
================================================
from flask import Flask
from flask_smorest import Api

from resources.item import blp as ItemBlueprint
from resources.store import blp as StoreBlueprint


app = Flask(__name__)

app.config["PROPAGATE_EXCEPTIONS"] = True
app.config["API_TITLE"] = "Stores REST API"
app.config["API_VERSION"] = "v1"
app.config["OPENAPI_VERSION"] = "3.0.3"
app.config["OPENAPI_URL_PREFIX"] = "/"
app.config["OPENAPI_SWAGGER_UI_PATH"] = "/swagger-ui"
app.config["OPENAPI_SWAGGER_UI_URL"] = "https://cdn.jsdelivr.net/npm/swagger-ui-dist/"

api = Api(app)

api.register_blueprint(ItemBlueprint)
api.register_blueprint(StoreBlueprint)


================================================
FILE: docs/docs/05_flask_smorest/08_validation_with_marshmallow/start/db.py
================================================
"""
db.py
---

Later on, this file will be replaced by SQLAlchemy. For now, it mimics a database.
Our data storage is:
    - stores have a unique ID and a name
    - items have a unique ID, a name, a price, and a store ID.
"""

stores = {}
items = {}


================================================
FILE: docs/docs/05_flask_smorest/08_validation_with_marshmallow/start/requirements.txt
================================================
flask
flask-smorest
python-dotenv
marshmallow

================================================
FILE: docs/docs/05_flask_smorest/08_validation_with_marshmallow/start/resources/__init__.py
================================================



================================================
FILE: docs/docs/05_flask_smorest/08_validation_with_marshmallow/start/resources/item.py
================================================
import uuid
from flask import request
from flask.views import MethodView
from flask_smorest import Blueprint, abort

from db import items

blp = Blueprint("Items", __name__, description="Operations on items")


@blp.route("/item/<string:item_id>")
class Item(MethodView):
    def get(self, item_id):
        try:
            return items[item_id]
        except KeyError:
            abort(404, message="Item not found.")

    def delete(self, item_id):
        try:
            del items[item_id]
            return {"message": "Item deleted."}
        except KeyError:
            abort(404, message="Item not found.")

    def put(self, item_id):
        item_data = request.get_json()
        # There's  more validation to do here!
        # Like making sure price is a number, and also both items are optional
        # Difficult to do with an if statement...
        if "price" not in item_data or "name" not in item_data:
            abort(
                400,
                message="Bad request. Ensure 'price', and 'name' are included in the JSON payload.",
            )
        try:
            item = items[item_id]

            # https://blog.teclado.com/python-dictionary-merge-update-operators/
            item |= item_data

            return item
        except KeyError:
            abort(404, message="Item not found.")


@blp.route("/item")
class ItemList(MethodView):
    def get(self):
        return {"items": list(items.values())}

    def post(self):
        item_data = request.get_json()
        # Here not only we need to validate data exists,
        # But also what type of data. Price should be a float,
        # for example.
        if (
            "price" not in item_data
            or "store_id" not in item_data
            or "name" not in item_data
        ):
            abort(
                400,
                message="Bad request. Ensure 'price', 'store_id', and 'name' are included in the JSON payload.",
            )
        for item in items.values():
            if (
                item_data["name"] == item["name"]
                and item_data["store_id"] == item["store_id"]
            ):
                abort(400, message=f"Item already exists.")

        item_id = uuid.uuid4().hex
        item = {**item_data, "id": item_id}
        items[item_id] = item

        return item


================================================
FILE: docs/docs/05_flask_smorest/08_validation_with_marshmallow/start/resources/store.py
================================================
import uuid
from flask import request
from flask.views import MethodView
from flask_smorest import Blueprint, abort
from db import stores


blp = Blueprint("Stores", __name__, description="Operations on stores")


@blp.route("/store/<string:store_id>")
class Store(MethodView):
    def get(cls, store_id):
        try:
            # You presumably would want to include the store's items here too
            # More on that when we look at databases
            return stores[store_id]
        except KeyError:
            abort(404, message="Store not found.")

    def delete(cls, store_id):
        try:
            del stores[store_id]
            return {"message": "Store deleted."}
        except KeyError:
            abort(404, message="Store not found.")


@blp.route("/store")
class StoreList(MethodView):
    def get(cls):
        return {"stores": list(stores.values())}

    def post(cls):
        store_data = request.get_json()
        if "name" not in store_data:
            abort(
                400,
                message="Bad request. Ensure 'name' is included in the JSON payload.",
            )
        for store in stores.values():
            if store_data["name"] == store["name"]:
                abort(400, message=f"Store already exists.")

        store_id = uuid.uuid4().hex
        store = {**store_data, "id": store_id}
        stores[store_id] = store

        return store


================================================
FILE: docs/docs/05_flask_smorest/08_validation_with_marshmallow/start/schemas.py
================================================
from marshmallow import Schema, fields


class ItemSchema(Schema):
    id = fields.Str(dump_only=True)
    name = fields.Str(required=True)
    price = fields.Float(required=True)
    store_id = fields.Str(required=True)


class ItemUpdateSchema(Schema):
    name = fields.Str()
    price = fields.Float()


class StoreSchema(Schema):
    id = fields.Str(dump_only=True)
    name = fields.Str(required=True)


================================================
FILE: docs/docs/05_flask_smorest/09_decorating_responses/README.md
================================================
---
title: Decorating responses with Flask-Smorest
description: Add response serialization and status code to API endpoints, and add to your documentation in the process.
ctslug: decorating-responses-with-flask-smorest
---

# Decorating responses with Flask-Smorest

We can use marshmallow schemas for serialization when we respond to a client. To do so, we need to tell Flask-Smorest what Schema to use when responding.

This will do a few things:

1. Update your documentation to show what data and status code will be returned by the endpoint.
2. Pass any data your endpoint returns through the marshmallow schema, casting data types and removing data that isn't in the schema.

## Decorating responses in `resources/item.py`

Let's start with retrieving a specific item.

Up until now, we've been doing this:

```py
def get(self, item_id):
    try:
        return items[item_id]
    except KeyError:
        abort(404, message="Item not found.")
```

But now we can run the `items[item_id]` dictionary through the marshmallow schema and tell Flask-Smorest about it so the documentation will be updated:

```py
@blp.response(200, ItemSchema)
def get(self, item_id):
    try:
        return items[item_id]
    except KeyError:
        abort(404, message="Item not found.")
```

:::info
The number, `200`, is the status code. It means "OK" (all good).
:::

Our endpoint for updating items looks like this:

```py
@blp.arguments(ItemUpdateSchema)
def put(self, item_data, item_id):
    try:
        item = items[item_id]
        item |= item_data

        return item
    except KeyError:
        abort(404, message="Item not found.")
```

Let's pass this through the schema as well:

```py
@blp.arguments(ItemUpdateSchema)
# highlight-start
@blp.response(200, ItemSchema)
# highlight-end
def put(self, item_data, item_id):
    try:
        item = items[item_id]

        # https://blog.teclado.com/python-dictionary-merge-update-operators/
        item |= item_data

        return item
    except KeyError:
        abor
Download .txt
gitextract_l2o0gskj/

├── .flake8
├── .github/
│   └── workflows/
│       └── algolia-scraper.yml
├── .gitignore
├── .gitmodules
├── .python-version
├── .templates/
│   ├── lecture.md
│   └── section.md
├── CONTRIBUTING.md
├── README.md
├── dependabot.yml
├── docs/
│   ├── .gitignore
│   ├── README.md
│   ├── algolia.config.json
│   ├── babel.config.js
│   ├── docs/
│   │   ├── 01_course_intro/
│   │   │   ├── 02_how_to_install_python/
│   │   │   │   └── README.md
│   │   │   ├── 03_how_to_install_ide/
│   │   │   │   └── README.md
│   │   │   ├── 04_what_is_rest_api/
│   │   │   │   └── README.md
│   │   │   ├── _category_.json
│   │   │   └── index.md
│   │   ├── 02_python_refresher/
│   │   │   ├── _category_.json
│   │   │   └── index.md
│   │   ├── 03_first_rest_api/
│   │   │   ├── 01_project_overview/
│   │   │   │   └── README.md
│   │   │   ├── 02_getting_set_up/
│   │   │   │   └── README.md
│   │   │   ├── 03_first_rest_api_endpoint/
│   │   │   │   └── README.md
│   │   │   ├── 04_what_is_json/
│   │   │   │   └── README.md
│   │   │   ├── 05_make_request_to_rest_api/
│   │   │   │   └── README.md
│   │   │   ├── 06_creating_stores/
│   │   │   │   └── README.md
│   │   │   ├── 07_creating_items/
│   │   │   │   └── README.md
│   │   │   ├── 08_return_data_from_rest_api/
│   │   │   │   └── README.md
│   │   │   ├── 09_final_code/
│   │   │   │   ├── README.md
│   │   │   │   └── end/
│   │   │   │       └── app.py
│   │   │   ├── Insomnia_section3.json
│   │   │   └── _category_.json
│   │   ├── 04_docker_intro/
│   │   │   ├── 01_what_is_docker_container/
│   │   │   │   ├── README.md
│   │   │   │   └── docker-presentation.key
│   │   │   ├── 02_run_docker_container/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   └── app.py
│   │   │   │   └── start/
│   │   │   │       └── app.py
│   │   │   ├── 03_in_depth_docker_tutorial/
│   │   │   │   └── README.md
│   │   │   ├── 04_run_with_docker_compose/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   └── docker-compose.yml
│   │   │   │   └── start/
│   │   │   │       ├── Dockerfile
│   │   │   │       └── app.py
│   │   │   ├── 05_run_commands_in_docker_containers/
│   │   │   │   └── README.md
│   │   │   ├── README.md
│   │   │   └── _category_.json
│   │   ├── 05_flask_smorest/
│   │   │   ├── 01_why_flask_smorest/
│   │   │   │   └── README.md
│   │   │   ├── 02_data_model_improvements/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   └── requirements.txt
│   │   │   │   └── start/
│   │   │   │       ├── Dockerfile
│   │   │   │       └── app.py
│   │   │   ├── 03_improvements_on_first_rest_api/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   └── requirements.txt
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       └── requirements.txt
│   │   │   ├── 04_new_endpoints_for_api/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   └── requirements.txt
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       └── requirements.txt
│   │   │   ├── 05_reload_api_docker_container/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   └── requirements.txt
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       └── requirements.txt
│   │   │   ├── 06_api_with_method_views/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   └── resources/
│   │   │   │   │       ├── __init__.py
│   │   │   │   │       ├── item.py
│   │   │   │   │       └── store.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       └── requirements.txt
│   │   │   ├── 07_marshmallow_schemas/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       ├── requirements.txt
│   │   │   │       └── resources/
│   │   │   │           ├── __init__.py
│   │   │   │           ├── item.py
│   │   │   │           └── store.py
│   │   │   ├── 08_validation_with_marshmallow/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       └── schemas.py
│   │   │   ├── 09_decorating_responses/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       └── schemas.py
│   │   │   ├── Insomnia_section5_Docker.json
│   │   │   ├── Insomnia_section5_before_Docker.json
│   │   │   └── _category_.json
│   │   ├── 06_sql_storage_sqlalchemy/
│   │   │   ├── 01_project_overview_sqlalchemy/
│   │   │   │   └── README.md
│   │   │   ├── 02_create_simple_sqlalchemy_model/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       └── schemas.py
│   │   │   ├── 03_one_to_many_relationships_sqlalchemy/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       └── schemas.py
│   │   │   ├── 04_configure_flask_sqlalchemy/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       └── schemas.py
│   │   │   ├── 05_insert_models_sqlalchemy/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       └── schemas.py
│   │   │   ├── 06_get_models_or_404/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       └── schemas.py
│   │   │   ├── 07_updating_models_sqlalchemy/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       └── schemas.py
│   │   │   ├── 08_retrieve_list_all_models/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       └── schemas.py
│   │   │   ├── 09_delete_models_sqlalchemy/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       └── schemas.py
│   │   │   ├── 10_delete_related_models_sqlalchemy/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   └── store.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       └── schemas.py
│   │   │   ├── 11_conclusion/
│   │   │   │   └── README.md
│   │   │   ├── Insomnia_section6.json
│   │   │   └── _category_.json
│   │   ├── 07_sqlalchemy_many_to_many/
│   │   │   ├── 01_section_changes/
│   │   │   │   └── README.md
│   │   │   ├── 02_one_to_many_review/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   └── tag.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   └── tag.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   └── store.py
│   │   │   │       └── schemas.py
│   │   │   ├── 03_many_to_many_relationships/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── conftest.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   └── tag.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   └── tag.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   └── tag.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   └── tag.py
│   │   │   │       └── schemas.py
│   │   │   ├── Insomnia_section7.json
│   │   │   └── _category_.json
│   │   ├── 08_flask_jwt_extended/
│   │   │   ├── 01_section_changes/
│   │   │   │   └── README.md
│   │   │   ├── 02_what_is_a_jwt/
│   │   │   │   └── README.md
│   │   │   ├── 03_how_is_jwt_used/
│   │   │   │   ├── README.md
│   │   │   │   └── how-are-jwts-used.key
│   │   │   ├── 04_flask_jwt_extended_setup/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .dockerignore
│   │   │   │   │   ├── .flake8
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── conftest.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   └── tag.py
│   │   │   │   │   ├── requirements-dev.txt
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   ├── conftest.py
│   │   │   │   │   │   │   ├── test_item.py
│   │   │   │   │   │   │   ├── test_store.py
│   │   │   │   │   │   │   └── test_tag.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   └── tag.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .dockerignore
│   │   │   │       ├── .flake8
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── conftest.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   └── tag.py
│   │   │   │       ├── requirements-dev.txt
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── __tests__/
│   │   │   │       │   │   ├── conftest.py
│   │   │   │       │   │   ├── test_item.py
│   │   │   │       │   │   ├── test_store.py
│   │   │   │       │   │   └── test_tag.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   └── tag.py
│   │   │   │       └── schemas.py
│   │   │   ├── 05_user_model_and_schema/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .dockerignore
│   │   │   │   │   ├── .flake8
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── conftest.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements-dev.txt
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   ├── conftest.py
│   │   │   │   │   │   │   ├── test_item.py
│   │   │   │   │   │   │   ├── test_store.py
│   │   │   │   │   │   │   └── test_tag.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   └── tag.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .dockerignore
│   │   │   │       ├── .flake8
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── conftest.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   └── tag.py
│   │   │   │       ├── requirements-dev.txt
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── __tests__/
│   │   │   │       │   │   ├── conftest.py
│   │   │   │       │   │   ├── test_item.py
│   │   │   │       │   │   ├── test_store.py
│   │   │   │       │   │   └── test_tag.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   └── tag.py
│   │   │   │       └── schemas.py
│   │   │   ├── 06_registering_users_rest_api/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .dockerignore
│   │   │   │   │   ├── .flake8
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── conftest.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements-dev.txt
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   ├── conftest.py
│   │   │   │   │   │   │   ├── test_item.py
│   │   │   │   │   │   │   ├── test_store.py
│   │   │   │   │   │   │   ├── test_tag.py
│   │   │   │   │   │   │   └── test_user.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .dockerignore
│   │   │   │       ├── .flake8
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── conftest.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── requirements-dev.txt
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── __tests__/
│   │   │   │       │   │   ├── conftest.py
│   │   │   │       │   │   ├── test_item.py
│   │   │   │       │   │   ├── test_store.py
│   │   │   │       │   │   └── test_tag.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   └── tag.py
│   │   │   │       └── schemas.py
│   │   │   ├── 07_login_users_rest_api/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .dockerignore
│   │   │   │   │   ├── .flake8
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── conftest.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements-dev.txt
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   ├── conftest.py
│   │   │   │   │   │   │   ├── test_item.py
│   │   │   │   │   │   │   ├── test_store.py
│   │   │   │   │   │   │   ├── test_tag.py
│   │   │   │   │   │   │   └── test_user.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .dockerignore
│   │   │   │       ├── .flake8
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── conftest.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── requirements-dev.txt
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── __tests__/
│   │   │   │       │   │   ├── conftest.py
│   │   │   │       │   │   ├── test_item.py
│   │   │   │       │   │   ├── test_store.py
│   │   │   │       │   │   ├── test_tag.py
│   │   │   │       │   │   └── test_user.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       └── schemas.py
│   │   │   ├── 08_protect_resources_with_jwt_required/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .dockerignore
│   │   │   │   │   ├── .flake8
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── conftest.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements-dev.txt
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   ├── conftest.py
│   │   │   │   │   │   │   ├── test_item.py
│   │   │   │   │   │   │   ├── test_store.py
│   │   │   │   │   │   │   ├── test_tag.py
│   │   │   │   │   │   │   └── test_user.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .dockerignore
│   │   │   │       ├── .flake8
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── conftest.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── requirements-dev.txt
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── __tests__/
│   │   │   │       │   │   ├── conftest.py
│   │   │   │       │   │   ├── test_item.py
│   │   │   │       │   │   ├── test_store.py
│   │   │   │       │   │   ├── test_tag.py
│   │   │   │       │   │   └── test_user.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       └── schemas.py
│   │   │   ├── 09_jwt_claims_and_authorization/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .dockerignore
│   │   │   │   │   ├── .flake8
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── conftest.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements-dev.txt
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   ├── conftest.py
│   │   │   │   │   │   │   ├── test_item.py
│   │   │   │   │   │   │   ├── test_store.py
│   │   │   │   │   │   │   ├── test_tag.py
│   │   │   │   │   │   │   └── test_user.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .dockerignore
│   │   │   │       ├── .flake8
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── conftest.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── requirements-dev.txt
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── __tests__/
│   │   │   │       │   │   ├── conftest.py
│   │   │   │       │   │   ├── test_item.py
│   │   │   │       │   │   ├── test_store.py
│   │   │   │       │   │   ├── test_tag.py
│   │   │   │       │   │   └── test_user.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       └── schemas.py
│   │   │   ├── 10_logout_users_rest_api/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .dockerignore
│   │   │   │   │   ├── .flake8
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── blocklist.py
│   │   │   │   │   ├── conftest.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements-dev.txt
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   ├── conftest.py
│   │   │   │   │   │   │   ├── test_item.py
│   │   │   │   │   │   │   ├── test_store.py
│   │   │   │   │   │   │   ├── test_tag.py
│   │   │   │   │   │   │   └── test_user.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .dockerignore
│   │   │   │       ├── .flake8
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── conftest.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── requirements-dev.txt
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── __tests__/
│   │   │   │       │   │   ├── conftest.py
│   │   │   │       │   │   ├── test_item.py
│   │   │   │       │   │   ├── test_store.py
│   │   │   │       │   │   ├── test_tag.py
│   │   │   │       │   │   └── test_user.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       └── schemas.py
│   │   │   ├── 11_insomnia_request_chaining/
│   │   │   │   └── README.md
│   │   │   ├── 12_token_refreshing_flask_jwt_extended/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .dockerignore
│   │   │   │   │   ├── .flake8
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── blocklist.py
│   │   │   │   │   ├── conftest.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements-dev.txt
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   ├── conftest.py
│   │   │   │   │   │   │   ├── test_item.py
│   │   │   │   │   │   │   ├── test_store.py
│   │   │   │   │   │   │   ├── test_tag.py
│   │   │   │   │   │   │   └── test_user.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   └── schemas.py
│   │   │   │   ├── end_video/
│   │   │   │   │   ├── .dockerignore
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── blocklist.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .dockerignore
│   │   │   │       ├── .flake8
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── blocklist.py
│   │   │   │       ├── conftest.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── requirements-dev.txt
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── __tests__/
│   │   │   │       │   │   ├── conftest.py
│   │   │   │       │   │   ├── test_item.py
│   │   │   │       │   │   ├── test_store.py
│   │   │   │       │   │   ├── test_tag.py
│   │   │   │       │   │   └── test_user.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       └── schemas.py
│   │   │   ├── Insomnia_section8_before_chaining.json
│   │   │   ├── Insomnia_section8_chaining.json
│   │   │   └── _category_.json
│   │   ├── 09_flask_migrate/
│   │   │   ├── 01_why_use_database_migrations/
│   │   │   │   └── README.md
│   │   │   ├── 02_add_flask_migrate_to_app/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .dockerignore
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── blocklist.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .dockerignore
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── blocklist.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       └── schemas.py
│   │   │   ├── 03_initialize_database_flask_db_init/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .dockerignore
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── .python-version
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── blocklist.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── migrations/
│   │   │   │   │   │   ├── README
│   │   │   │   │   │   ├── alembic.ini
│   │   │   │   │   │   ├── env.py
│   │   │   │   │   │   ├── script.py.mako
│   │   │   │   │   │   └── versions/
│   │   │   │   │   │       └── c575166f6192_.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .dockerignore
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── blocklist.py
│   │   │   │       ├── db.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       └── schemas.py
│   │   │   ├── 04_change_models_generate_alembic_migration/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .dockerignore
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── .python-version
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── blocklist.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── migrations/
│   │   │   │   │   │   ├── README
│   │   │   │   │   │   ├── alembic.ini
│   │   │   │   │   │   ├── env.py
│   │   │   │   │   │   ├── script.py.mako
│   │   │   │   │   │   └── versions/
│   │   │   │   │   │       ├── bcc005bc255c_.py
│   │   │   │   │   │       └── c575166f6192_.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .dockerignore
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── .python-version
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── app.py
│   │   │   │       ├── blocklist.py
│   │   │   │       ├── db.py
│   │   │   │       ├── migrations/
│   │   │   │       │   ├── README
│   │   │   │       │   ├── alembic.ini
│   │   │   │       │   ├── env.py
│   │   │   │       │   ├── script.py.mako
│   │   │   │       │   └── versions/
│   │   │   │       │       └── c575166f6192_.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       └── schemas.py
│   │   │   ├── 05_manually_review_modify_migrations/
│   │   │   │   └── README.md
│   │   │   └── _category_.json
│   │   ├── 10_git_crash_course/
│   │   │   ├── README.md
│   │   │   └── _category_.json
│   │   ├── 11_deploy_to_render/
│   │   │   ├── 01_section_overview/
│   │   │   │   └── README.md
│   │   │   ├── 02_create_render_web_service/
│   │   │   │   └── README.md
│   │   │   ├── 03_docker_with_gunicorn/
│   │   │   │   └── README.md
│   │   │   ├── 04_deploy_postgresql_database/
│   │   │   │   └── README.md
│   │   │   ├── 05_environment_variables_and_migrations/
│   │   │   │   └── README.md
│   │   │   ├── 06_run_everything_docker_compose/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── .gitignore
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── blocklist.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── docker-compose.yml
│   │   │   │   │   ├── docker-entrypoint.sh
│   │   │   │   │   ├── migrations/
│   │   │   │   │   │   ├── README
│   │   │   │   │   │   ├── alembic.ini
│   │   │   │   │   │   ├── env.py
│   │   │   │   │   │   ├── script.py.mako
│   │   │   │   │   │   └── versions/
│   │   │   │   │   │       ├── 07006e31e788_.py
│   │   │   │   │   │       ├── 8ca023a4a4b0_.py
│   │   │   │   │   │       └── bb5da1e68550_.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── .gitignore
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── README.md
│   │   │   │       ├── app.py
│   │   │   │       ├── blocklist.py
│   │   │   │       ├── db.py
│   │   │   │       ├── docker-entrypoint.sh
│   │   │   │       ├── migrations/
│   │   │   │       │   ├── README
│   │   │   │       │   ├── alembic.ini
│   │   │   │       │   ├── env.py
│   │   │   │       │   ├── script.py.mako
│   │   │   │       │   └── versions/
│   │   │   │       │       ├── 07006e31e788_.py
│   │   │   │       │       ├── 8ca023a4a4b0_.py
│   │   │   │       │       └── bb5da1e68550_.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       └── schemas.py
│   │   │   ├── Insomnia_section11.json
│   │   │   └── _category_.json
│   │   ├── 12_task_queues_emails/
│   │   │   ├── 01_send_emails_python_mailgun/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── .gitignore
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── blocklist.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── docker-entrypoint.sh
│   │   │   │   │   ├── migrations/
│   │   │   │   │   │   ├── README
│   │   │   │   │   │   ├── alembic.ini
│   │   │   │   │   │   ├── env.py
│   │   │   │   │   │   ├── script.py.mako
│   │   │   │   │   │   └── versions/
│   │   │   │   │   │       ├── 07006e31e788_.py
│   │   │   │   │   │       ├── 8ca023a4a4b0_.py
│   │   │   │   │   │       └── bb5da1e68550_.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── .gitignore
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── README.md
│   │   │   │       ├── app.py
│   │   │   │       ├── blocklist.py
│   │   │   │       ├── db.py
│   │   │   │       ├── docker-entrypoint.sh
│   │   │   │       ├── migrations/
│   │   │   │       │   ├── README
│   │   │   │       │   ├── alembic.ini
│   │   │   │       │   ├── env.py
│   │   │   │       │   ├── script.py.mako
│   │   │   │       │   └── versions/
│   │   │   │       │       ├── 07006e31e788_.py
│   │   │   │       │       ├── 8ca023a4a4b0_.py
│   │   │   │       │       └── bb5da1e68550_.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       └── schemas.py
│   │   │   ├── 02_send_email_user_registration/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── .gitignore
│   │   │   │   │   ├── .python-version
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── blocklist.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── docker-entrypoint.sh
│   │   │   │   │   ├── migrations/
│   │   │   │   │   │   ├── README
│   │   │   │   │   │   ├── alembic.ini
│   │   │   │   │   │   ├── env.py
│   │   │   │   │   │   ├── script.py.mako
│   │   │   │   │   │   └── versions/
│   │   │   │   │   │       ├── 07006e31e788_.py
│   │   │   │   │   │       ├── 8ca023a4a4b0_.py
│   │   │   │   │   │       ├── bb5da1e68550_.py
│   │   │   │   │   │       └── d8e0f80631fb_.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   └── schemas.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── .gitignore
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── README.md
│   │   │   │       ├── app.py
│   │   │   │       ├── blocklist.py
│   │   │   │       ├── db.py
│   │   │   │       ├── docker-entrypoint.sh
│   │   │   │       ├── migrations/
│   │   │   │       │   ├── README
│   │   │   │       │   ├── alembic.ini
│   │   │   │       │   ├── env.py
│   │   │   │       │   ├── script.py.mako
│   │   │   │       │   └── versions/
│   │   │   │       │       ├── 07006e31e788_.py
│   │   │   │       │       ├── 8ca023a4a4b0_.py
│   │   │   │       │       └── bb5da1e68550_.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       └── schemas.py
│   │   │   ├── 03_what_is_task_queue/
│   │   │   │   └── README.md
│   │   │   ├── 04_populate_rq_task_queue/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── .gitignore
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── blocklist.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── docker-entrypoint.sh
│   │   │   │   │   ├── migrations/
│   │   │   │   │   │   ├── README
│   │   │   │   │   │   ├── alembic.ini
│   │   │   │   │   │   ├── env.py
│   │   │   │   │   │   ├── script.py.mako
│   │   │   │   │   │   └── versions/
│   │   │   │   │   │       ├── 07006e31e788_.py
│   │   │   │   │   │       ├── 8ca023a4a4b0_.py
│   │   │   │   │   │       ├── bb5da1e68550_.py
│   │   │   │   │   │       └── d8e0f80631fb_.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── schemas.py
│   │   │   │   │   └── tasks.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── .gitignore
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── README.md
│   │   │   │       ├── app.py
│   │   │   │       ├── blocklist.py
│   │   │   │       ├── db.py
│   │   │   │       ├── docker-entrypoint.sh
│   │   │   │       ├── migrations/
│   │   │   │       │   ├── README
│   │   │   │       │   ├── alembic.ini
│   │   │   │       │   ├── env.py
│   │   │   │       │   ├── script.py.mako
│   │   │   │       │   └── versions/
│   │   │   │       │       ├── 07006e31e788_.py
│   │   │   │       │       ├── 8ca023a4a4b0_.py
│   │   │   │       │       ├── bb5da1e68550_.py
│   │   │   │       │       └── d8e0f80631fb_.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       └── schemas.py
│   │   │   ├── 05_rq_background_worker/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── .gitignore
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── blocklist.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── docker-entrypoint.sh
│   │   │   │   │   ├── migrations/
│   │   │   │   │   │   ├── README
│   │   │   │   │   │   ├── alembic.ini
│   │   │   │   │   │   ├── env.py
│   │   │   │   │   │   ├── script.py.mako
│   │   │   │   │   │   └── versions/
│   │   │   │   │   │       ├── 07006e31e788_.py
│   │   │   │   │   │       ├── 8ca023a4a4b0_.py
│   │   │   │   │   │       ├── bb5da1e68550_.py
│   │   │   │   │   │       └── d8e0f80631fb_.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── schemas.py
│   │   │   │   │   └── tasks.py
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── .gitignore
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── README.md
│   │   │   │       ├── app.py
│   │   │   │       ├── blocklist.py
│   │   │   │       ├── db.py
│   │   │   │       ├── docker-entrypoint.sh
│   │   │   │       ├── migrations/
│   │   │   │       │   ├── README
│   │   │   │       │   ├── alembic.ini
│   │   │   │       │   ├── env.py
│   │   │   │       │   ├── script.py.mako
│   │   │   │       │   └── versions/
│   │   │   │       │       ├── 07006e31e788_.py
│   │   │   │       │       ├── 8ca023a4a4b0_.py
│   │   │   │       │       ├── bb5da1e68550_.py
│   │   │   │       │       └── d8e0f80631fb_.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── schemas.py
│   │   │   │       └── tasks.py
│   │   │   ├── 06_sending_html_emails/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── .gitignore
│   │   │   │   │   ├── .python-version
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── blocklist.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── docker-entrypoint.sh
│   │   │   │   │   ├── migrations/
│   │   │   │   │   │   ├── README
│   │   │   │   │   │   ├── alembic.ini
│   │   │   │   │   │   ├── env.py
│   │   │   │   │   │   ├── script.py.mako
│   │   │   │   │   │   └── versions/
│   │   │   │   │   │       ├── 07006e31e788_.py
│   │   │   │   │   │       ├── 8ca023a4a4b0_.py
│   │   │   │   │   │       ├── bb5da1e68550_.py
│   │   │   │   │   │       └── d8e0f80631fb_.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── schemas.py
│   │   │   │   │   ├── tasks.py
│   │   │   │   │   └── templates/
│   │   │   │   │       └── email/
│   │   │   │   │           ├── action.html
│   │   │   │   │           └── action.original.html
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── .gitignore
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── README.md
│   │   │   │       ├── app.py
│   │   │   │       ├── blocklist.py
│   │   │   │       ├── db.py
│   │   │   │       ├── docker-entrypoint.sh
│   │   │   │       ├── migrations/
│   │   │   │       │   ├── README
│   │   │   │       │   ├── alembic.ini
│   │   │   │       │   ├── env.py
│   │   │   │       │   ├── script.py.mako
│   │   │   │       │   └── versions/
│   │   │   │       │       ├── 07006e31e788_.py
│   │   │   │       │       ├── 8ca023a4a4b0_.py
│   │   │   │       │       ├── bb5da1e68550_.py
│   │   │   │       │       └── d8e0f80631fb_.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── schemas.py
│   │   │   │       └── tasks.py
│   │   │   ├── 07_deploy_background_worker_render/
│   │   │   │   ├── README.md
│   │   │   │   ├── end/
│   │   │   │   │   ├── .flaskenv
│   │   │   │   │   ├── .gitignore
│   │   │   │   │   ├── .python-version
│   │   │   │   │   ├── Dockerfile
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── app.py
│   │   │   │   │   ├── blocklist.py
│   │   │   │   │   ├── db.py
│   │   │   │   │   ├── docker-entrypoint.sh
│   │   │   │   │   ├── migrations/
│   │   │   │   │   │   ├── README
│   │   │   │   │   │   ├── alembic.ini
│   │   │   │   │   │   ├── env.py
│   │   │   │   │   │   ├── script.py.mako
│   │   │   │   │   │   └── versions/
│   │   │   │   │   │       ├── 07006e31e788_.py
│   │   │   │   │   │       ├── 8ca023a4a4b0_.py
│   │   │   │   │   │       ├── bb5da1e68550_.py
│   │   │   │   │   │       └── d8e0f80631fb_.py
│   │   │   │   │   ├── models/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── item_tags.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── requirements.txt
│   │   │   │   │   ├── resources/
│   │   │   │   │   │   ├── item.py
│   │   │   │   │   │   ├── store.py
│   │   │   │   │   │   ├── tag.py
│   │   │   │   │   │   └── user.py
│   │   │   │   │   ├── schemas.py
│   │   │   │   │   ├── settings.py
│   │   │   │   │   ├── tasks.py
│   │   │   │   │   └── templates/
│   │   │   │   │       └── email/
│   │   │   │   │           ├── action.html
│   │   │   │   │           └── action.original.html
│   │   │   │   └── start/
│   │   │   │       ├── .flaskenv
│   │   │   │       ├── .gitignore
│   │   │   │       ├── .python-version
│   │   │   │       ├── Dockerfile
│   │   │   │       ├── README.md
│   │   │   │       ├── app.py
│   │   │   │       ├── blocklist.py
│   │   │   │       ├── db.py
│   │   │   │       ├── docker-entrypoint.sh
│   │   │   │       ├── migrations/
│   │   │   │       │   ├── README
│   │   │   │       │   ├── alembic.ini
│   │   │   │       │   ├── env.py
│   │   │   │       │   ├── script.py.mako
│   │   │   │       │   └── versions/
│   │   │   │       │       ├── 07006e31e788_.py
│   │   │   │       │       ├── 8ca023a4a4b0_.py
│   │   │   │       │       ├── bb5da1e68550_.py
│   │   │   │       │       └── d8e0f80631fb_.py
│   │   │   │       ├── models/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── item_tags.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── requirements.txt
│   │   │   │       ├── resources/
│   │   │   │       │   ├── item.py
│   │   │   │       │   ├── store.py
│   │   │   │       │   ├── tag.py
│   │   │   │       │   └── user.py
│   │   │   │       ├── schemas.py
│   │   │   │       ├── tasks.py
│   │   │   │       └── templates/
│   │   │   │           └── email/
│   │   │   │               ├── action.html
│   │   │   │               └── action.original.html
│   │   │   ├── Insomnia_section12.json
│   │   │   └── _category_.json
│   │   └── Insomnia_all_sections.json
│   ├── docusaurus.config.js
│   ├── package.json
│   ├── sidebars.js
│   └── src/
│       ├── components/
│       │   ├── HomepageFeatures/
│       │   │   ├── index.js
│       │   │   └── styles.module.css
│       │   ├── LockedVideoEmbed/
│       │   │   └── index.js
│       │   └── VideoEmbed/
│       │       └── index.js
│       ├── css/
│       │   └── custom.css
│       └── pages/
│           ├── index.js
│           ├── index.module.css
│           └── insomnia-files.md
└── project/
    ├── 01-first-rest-api/
    │   └── app.py
    ├── 02-first-rest-api-docker/
    │   ├── Dockerfile
    │   └── app.py
    ├── 03-items-stores-smorest/
    │   ├── .flaskenv
    │   ├── Dockerfile
    │   ├── app.py
    │   ├── db.py
    │   ├── requirements.txt
    │   ├── resources/
    │   │   ├── __init__.py
    │   │   ├── item.py
    │   │   └── store.py
    │   └── schemas.py
    ├── 04-items-stores-smorest-sqlalchemy/
    │   ├── .flaskenv
    │   ├── Dockerfile
    │   ├── app.py
    │   ├── db.py
    │   ├── models/
    │   │   ├── __init__.py
    │   │   ├── item.py
    │   │   └── store.py
    │   ├── requirements.txt
    │   ├── resources/
    │   │   ├── __init__.py
    │   │   ├── item.py
    │   │   └── store.py
    │   └── schemas.py
    ├── 05-add-many-to-many/
    │   ├── .flaskenv
    │   ├── Dockerfile
    │   ├── app.py
    │   ├── conftest.py
    │   ├── db.py
    │   ├── models/
    │   │   ├── __init__.py
    │   │   ├── item.py
    │   │   ├── item_tags.py
    │   │   ├── store.py
    │   │   └── tag.py
    │   ├── requirements.txt
    │   ├── resources/
    │   │   ├── __init__.py
    │   │   ├── __tests__/
    │   │   │   ├── conftest.py
    │   │   │   ├── test_item.py
    │   │   │   ├── test_store.py
    │   │   │   └── test_tag.py
    │   │   ├── item.py
    │   │   ├── store.py
    │   │   └── tag.py
    │   └── schemas.py
    ├── 06-add-db-migrations/
    │   ├── .flaskenv
    │   ├── .python-version
    │   ├── Dockerfile
    │   ├── app.py
    │   ├── conftest.py
    │   ├── db.py
    │   ├── migrations/
    │   │   ├── README
    │   │   ├── alembic.ini
    │   │   ├── env.py
    │   │   ├── script.py.mako
    │   │   └── versions/
    │   │       ├── 5acd69659946_.py
    │   │       └── a40bdfbd7a9d_.py
    │   ├── models/
    │   │   ├── __init__.py
    │   │   ├── item.py
    │   │   ├── item_tags.py
    │   │   ├── store.py
    │   │   └── tag.py
    │   ├── requirements.txt
    │   ├── resources/
    │   │   ├── __init__.py
    │   │   ├── __tests__/
    │   │   │   ├── conftest.py
    │   │   │   ├── test_item.py
    │   │   │   ├── test_store.py
    │   │   │   └── test_tag.py
    │   │   ├── item.py
    │   │   ├── store.py
    │   │   └── tag.py
    │   └── schemas.py
    ├── using-flask-restful/
    │   ├── .flaskenv
    │   ├── Flask-JWT-Extended.postman_collection.json
    │   ├── Stores_REST_API_2022-01-14.json
    │   ├── app.py
    │   ├── blocklist.py
    │   ├── db.py
    │   ├── models/
    │   │   ├── __init__.py
    │   │   ├── item.py
    │   │   ├── item_tags.py
    │   │   ├── store.py
    │   │   ├── tag.py
    │   │   └── user.py
    │   ├── requirements.txt
    │   └── resources/
    │       ├── __init__.py
    │       ├── item.py
    │       ├── store.py
    │       ├── tag.py
    │       └── user.py
    ├── using-flask-restx/
    │   ├── .flaskenv
    │   ├── Flask-JWT-Extended.postman_collection.json
    │   ├── Stores_REST_API_2022-01-14.json
    │   ├── app.py
    │   ├── blocklist.py
    │   ├── db.py
    │   ├── models/
    │   │   ├── __init__.py
    │   │   ├── item.py
    │   │   ├── item_tags.py
    │   │   ├── store.py
    │   │   ├── tag.py
    │   │   └── user.py
    │   ├── requirements.txt
    │   └── resources/
    │       ├── __init__.py
    │       ├── item.py
    │       ├── store.py
    │       ├── tag.py
    │       └── user.py
    └── using-flask-smorest/
        ├── .flaskenv
        ├── Flask-JWT-Extended.postman_collection.json
        ├── Stores_REST_API_2022-01-14.json
        ├── app.py
        ├── blocklist.py
        ├── db.py
        ├── models/
        │   ├── __init__.py
        │   ├── item.py
        │   ├── item_tags.py
        │   ├── store.py
        │   ├── tag.py
        │   └── user.py
        ├── requirements.txt
        ├── resources/
        │   ├── __init__.py
        │   ├── item.py
        │   ├── store.py
        │   ├── tag.py
        │   └── user.py
        └── schemas.py
Download .txt
Showing preview only (317K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (3696 symbols across 812 files)

FILE: docs/docs/03_first_rest_api/09_final_code/end/app.py
  function get_stores (line 9) | def get_stores():
  function create_store (line 14) | def create_store():
  function create_item (line 22) | def create_item(name):
  function get_store (line 33) | def get_store(name):
  function get_item_in_store (line 41) | def get_item_in_store(name):

FILE: docs/docs/04_docker_intro/02_run_docker_container/end/app.py
  function get_stores (line 9) | def get_stores():
  function create_store (line 14) | def create_store():
  function create_item (line 22) | def create_item(name):
  function get_store (line 33) | def get_store(name):
  function get_item_in_store (line 41) | def get_item_in_store(name):

FILE: docs/docs/04_docker_intro/02_run_docker_container/start/app.py
  function get_stores (line 9) | def get_stores():
  function create_store (line 14) | def create_store():
  function create_item (line 22) | def create_item(name):
  function get_store (line 33) | def get_store(name):
  function get_item_in_store (line 41) | def get_item_in_store(name):

FILE: docs/docs/04_docker_intro/04_run_with_docker_compose/end/app.py
  function get_stores (line 9) | def get_stores():
  function create_store (line 14) | def create_store():
  function create_item (line 22) | def create_item(name):
  function get_store (line 33) | def get_store(name):
  function get_item_in_store (line 41) | def get_item_in_store(name):

FILE: docs/docs/04_docker_intro/04_run_with_docker_compose/start/app.py
  function get_stores (line 9) | def get_stores():
  function create_store (line 14) | def create_store():
  function create_item (line 22) | def create_item(name):
  function get_store (line 33) | def get_store(name):
  function get_item_in_store (line 41) | def get_item_in_store(name):

FILE: docs/docs/05_flask_smorest/02_data_model_improvements/end/app.py
  function get_item (line 11) | def get_item(item_id):
  function create_item (line 19) | def create_item():
  function get_all_items (line 32) | def get_all_items():
  function get_store (line 37) | def get_store(store_id):
  function create_store (line 47) | def create_store():
  function get_stores (line 57) | def get_stores():

FILE: docs/docs/05_flask_smorest/02_data_model_improvements/start/app.py
  function get_stores (line 9) | def get_stores():
  function create_store (line 14) | def create_store():
  function create_item (line 22) | def create_item(name):
  function get_store (line 33) | def get_store(name):
  function get_item_in_store (line 41) | def get_item_in_store(name):

FILE: docs/docs/05_flask_smorest/03_improvements_on_first_rest_api/end/app.py
  function get_item (line 12) | def get_item(item_id):
  function create_item (line 20) | def create_item():
  function get_all_items (line 49) | def get_all_items():
  function get_store (line 54) | def get_store(store_id):
  function create_store (line 64) | def create_store():
  function get_stores (line 83) | def get_stores():

FILE: docs/docs/05_flask_smorest/03_improvements_on_first_rest_api/start/app.py
  function get_item (line 11) | def get_item(item_id):
  function create_item (line 19) | def create_item():
  function get_all_items (line 32) | def get_all_items():
  function get_store (line 37) | def get_store(store_id):
  function create_store (line 47) | def create_store():
  function get_stores (line 57) | def get_stores():

FILE: docs/docs/05_flask_smorest/04_new_endpoints_for_api/end/app.py
  function get_item (line 12) | def get_item(item_id):
  function create_item (line 20) | def create_item():
  function delete_item (line 49) | def delete_item(item_id):
  function update_item (line 58) | def update_item(item_id):
  function get_all_items (line 80) | def get_all_items():
  function get_store (line 85) | def get_store(store_id):
  function create_store (line 95) | def create_store():
  function delete_store (line 114) | def delete_store(store_id):
  function get_stores (line 123) | def get_stores():

FILE: docs/docs/05_flask_smorest/04_new_endpoints_for_api/start/app.py
  function get_item (line 12) | def get_item(item_id):
  function create_item (line 20) | def create_item():
  function get_all_items (line 49) | def get_all_items():
  function get_store (line 54) | def get_store(store_id):
  function create_store (line 64) | def create_store():
  function get_stores (line 83) | def get_stores():

FILE: docs/docs/05_flask_smorest/05_reload_api_docker_container/end/app.py
  function get_item (line 12) | def get_item(item_id):
  function create_item (line 20) | def create_item():
  function delete_item (line 49) | def delete_item(item_id):
  function update_item (line 58) | def update_item(item_id):
  function get_all_items (line 80) | def get_all_items():
  function get_store (line 85) | def get_store(store_id):
  function create_store (line 95) | def create_store():
  function delete_store (line 114) | def delete_store(store_id):
  function get_stores (line 123) | def get_stores():

FILE: docs/docs/05_flask_smorest/05_reload_api_docker_container/start/app.py
  function get_item (line 12) | def get_item(item_id):
  function create_item (line 20) | def create_item():
  function delete_item (line 49) | def delete_item(item_id):
  function update_item (line 58) | def update_item(item_id):
  function get_all_items (line 80) | def get_all_items():
  function get_store (line 85) | def get_store(store_id):
  function create_store (line 95) | def create_store():
  function delete_store (line 114) | def delete_store(store_id):
  function get_stores (line 123) | def get_stores():

FILE: docs/docs/05_flask_smorest/06_api_with_method_views/end/resources/item.py
  class Item (line 12) | class Item(MethodView):
    method get (line 13) | def get(self, item_id):
    method delete (line 19) | def delete(self, item_id):
    method put (line 26) | def put(self, item_id):
  class ItemList (line 48) | class ItemList(MethodView):
    method get (line 49) | def get(self):
    method post (line 52) | def post(self):

FILE: docs/docs/05_flask_smorest/06_api_with_method_views/end/resources/store.py
  class Store (line 12) | class Store(MethodView):
    method get (line 13) | def get(self, store_id):
    method delete (line 21) | def delete(self, store_id):
  class StoreList (line 30) | class StoreList(MethodView):
    method get (line 31) | def get(self):
    method post (line 34) | def post(self):

FILE: docs/docs/05_flask_smorest/06_api_with_method_views/start/app.py
  function get_item (line 12) | def get_item(item_id):
  function delete_item (line 20) | def delete_item(item_id):
  function update_item (line 29) | def update_item(item_id):
  function get_all_items (line 51) | def get_all_items():
  function create_item (line 56) | def create_item():
  function get_store (line 85) | def get_store(store_id):
  function delete_store (line 95) | def delete_store(store_id):
  function get_stores (line 104) | def get_stores():
  function create_store (line 109) | def create_store():

FILE: docs/docs/05_flask_smorest/07_marshmallow_schemas/end/resources/item.py
  class Item (line 12) | class Item(MethodView):
    method get (line 13) | def get(self, item_id):
    method delete (line 19) | def delete(self, item_id):
    method put (line 26) | def put(self, item_id):
  class ItemList (line 48) | class ItemList(MethodView):
    method get (line 49) | def get(self):
    method post (line 52) | def post(self):

FILE: docs/docs/05_flask_smorest/07_marshmallow_schemas/end/resources/store.py
  class Store (line 12) | class Store(MethodView):
    method get (line 13) | def get(cls, store_id):
    method delete (line 21) | def delete(cls, store_id):
  class StoreList (line 30) | class StoreList(MethodView):
    method get (line 31) | def get(cls):
    method post (line 34) | def post(cls):

FILE: docs/docs/05_flask_smorest/07_marshmallow_schemas/end/schemas.py
  class ItemSchema (line 4) | class ItemSchema(Schema):
  class ItemUpdateSchema (line 11) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 16) | class StoreSchema(Schema):

FILE: docs/docs/05_flask_smorest/07_marshmallow_schemas/start/resources/item.py
  class Item (line 12) | class Item(MethodView):
    method get (line 13) | def get(self, item_id):
    method delete (line 19) | def delete(self, item_id):
    method put (line 26) | def put(self, item_id):
  class ItemList (line 48) | class ItemList(MethodView):
    method get (line 49) | def get(self):
    method post (line 52) | def post(self):

FILE: docs/docs/05_flask_smorest/07_marshmallow_schemas/start/resources/store.py
  class Store (line 12) | class Store(MethodView):
    method get (line 13) | def get(cls, store_id):
    method delete (line 21) | def delete(cls, store_id):
  class StoreList (line 30) | class StoreList(MethodView):
    method get (line 31) | def get(cls):
    method post (line 34) | def post(cls):

FILE: docs/docs/05_flask_smorest/08_validation_with_marshmallow/end/resources/item.py
  class Item (line 12) | class Item(MethodView):
    method get (line 13) | def get(self, item_id):
    method delete (line 19) | def delete(self, item_id):
    method put (line 27) | def put(self, item_data, item_id):
  class ItemList (line 40) | class ItemList(MethodView):
    method get (line 41) | def get(self):
    method post (line 45) | def post(self, item_data):

FILE: docs/docs/05_flask_smorest/08_validation_with_marshmallow/end/resources/store.py
  class Store (line 12) | class Store(MethodView):
    method get (line 13) | def get(cls, store_id):
    method delete (line 21) | def delete(cls, store_id):
  class StoreList (line 30) | class StoreList(MethodView):
    method get (line 31) | def get(cls):
    method post (line 35) | def post(cls, store_data):

FILE: docs/docs/05_flask_smorest/08_validation_with_marshmallow/end/schemas.py
  class ItemSchema (line 4) | class ItemSchema(Schema):
  class ItemUpdateSchema (line 11) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 16) | class StoreSchema(Schema):

FILE: docs/docs/05_flask_smorest/08_validation_with_marshmallow/start/resources/item.py
  class Item (line 12) | class Item(MethodView):
    method get (line 13) | def get(self, item_id):
    method delete (line 19) | def delete(self, item_id):
    method put (line 26) | def put(self, item_id):
  class ItemList (line 48) | class ItemList(MethodView):
    method get (line 49) | def get(self):
    method post (line 52) | def post(self):

FILE: docs/docs/05_flask_smorest/08_validation_with_marshmallow/start/resources/store.py
  class Store (line 12) | class Store(MethodView):
    method get (line 13) | def get(cls, store_id):
    method delete (line 21) | def delete(cls, store_id):
  class StoreList (line 30) | class StoreList(MethodView):
    method get (line 31) | def get(cls):
    method post (line 34) | def post(cls):

FILE: docs/docs/05_flask_smorest/08_validation_with_marshmallow/start/schemas.py
  class ItemSchema (line 4) | class ItemSchema(Schema):
  class ItemUpdateSchema (line 11) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 16) | class StoreSchema(Schema):

FILE: docs/docs/05_flask_smorest/09_decorating_responses/end/resources/item.py
  class Item (line 12) | class Item(MethodView):
    method get (line 14) | def get(self, item_id):
    method delete (line 20) | def delete(self, item_id):
    method put (line 29) | def put(self, item_data, item_id):
  class ItemList (line 42) | class ItemList(MethodView):
    method get (line 44) | def get(self):
    method post (line 49) | def post(self, item_data):

FILE: docs/docs/05_flask_smorest/09_decorating_responses/end/resources/store.py
  class Store (line 12) | class Store(MethodView):
    method get (line 14) | def get(cls, store_id):
    method delete (line 22) | def delete(cls, store_id):
  class StoreList (line 31) | class StoreList(MethodView):
    method get (line 33) | def get(cls):
    method post (line 38) | def post(cls, store_data):

FILE: docs/docs/05_flask_smorest/09_decorating_responses/end/schemas.py
  class ItemSchema (line 4) | class ItemSchema(Schema):
  class ItemUpdateSchema (line 11) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 16) | class StoreSchema(Schema):

FILE: docs/docs/05_flask_smorest/09_decorating_responses/start/resources/item.py
  class Item (line 12) | class Item(MethodView):
    method get (line 13) | def get(self, item_id):
    method delete (line 19) | def delete(self, item_id):
    method put (line 27) | def put(self, item_data, item_id):
  class ItemList (line 40) | class ItemList(MethodView):
    method get (line 41) | def get(self):
    method post (line 45) | def post(self, item_data):

FILE: docs/docs/05_flask_smorest/09_decorating_responses/start/resources/store.py
  class Store (line 12) | class Store(MethodView):
    method get (line 13) | def get(cls, store_id):
    method delete (line 21) | def delete(cls, store_id):
  class StoreList (line 30) | class StoreList(MethodView):
    method get (line 31) | def get(cls):
    method post (line 35) | def post(cls, store_data):

FILE: docs/docs/05_flask_smorest/09_decorating_responses/start/schemas.py
  class ItemSchema (line 4) | class ItemSchema(Schema):
  class ItemUpdateSchema (line 11) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 16) | class StoreSchema(Schema):

FILE: docs/docs/06_sql_storage_sqlalchemy/02_create_simple_sqlalchemy_model/end/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/06_sql_storage_sqlalchemy/02_create_simple_sqlalchemy_model/end/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/06_sql_storage_sqlalchemy/02_create_simple_sqlalchemy_model/end/resources/item.py
  class Item (line 13) | class Item(MethodView):
    method get (line 15) | def get(self, item_id):
    method delete (line 18) | def delete(self, item_id):
    method put (line 23) | def put(self, item_data, item_id):
  class ItemList (line 28) | class ItemList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, item_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/02_create_simple_sqlalchemy_model/end/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 19) | def delete(self, store_id):
  class StoreList (line 24) | class StoreList(MethodView):
    method get (line 26) | def get(self):
    method post (line 31) | def post(self, store_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/02_create_simple_sqlalchemy_model/end/schemas.py
  class ItemSchema (line 4) | class ItemSchema(Schema):
  class ItemUpdateSchema (line 11) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 16) | class StoreSchema(Schema):

FILE: docs/docs/06_sql_storage_sqlalchemy/02_create_simple_sqlalchemy_model/start/resources/item.py
  class Item (line 13) | class Item(MethodView):
    method get (line 15) | def get(self, item_id):
    method delete (line 18) | def delete(self, item_id):
    method put (line 23) | def put(self, item_data, item_id):
  class ItemList (line 28) | class ItemList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, item_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/02_create_simple_sqlalchemy_model/start/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 19) | def delete(self, store_id):
  class StoreList (line 24) | class StoreList(MethodView):
    method get (line 26) | def get(self):
    method post (line 31) | def post(self, store_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/02_create_simple_sqlalchemy_model/start/schemas.py
  class ItemSchema (line 4) | class ItemSchema(Schema):
  class ItemUpdateSchema (line 11) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 16) | class StoreSchema(Schema):

FILE: docs/docs/06_sql_storage_sqlalchemy/03_one_to_many_relationships_sqlalchemy/end/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/06_sql_storage_sqlalchemy/03_one_to_many_relationships_sqlalchemy/end/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/06_sql_storage_sqlalchemy/03_one_to_many_relationships_sqlalchemy/end/resources/item.py
  class Item (line 13) | class Item(MethodView):
    method get (line 15) | def get(self, item_id):
    method delete (line 18) | def delete(self, item_id):
    method put (line 23) | def put(self, item_data, item_id):
  class ItemList (line 28) | class ItemList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, item_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/03_one_to_many_relationships_sqlalchemy/end/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 19) | def delete(self, store_id):
  class StoreList (line 24) | class StoreList(MethodView):
    method get (line 26) | def get(self):
    method post (line 31) | def post(self, store_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/03_one_to_many_relationships_sqlalchemy/end/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class ItemSchema (line 15) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 20) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 25) | class StoreSchema(PlainStoreSchema):

FILE: docs/docs/06_sql_storage_sqlalchemy/03_one_to_many_relationships_sqlalchemy/start/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/06_sql_storage_sqlalchemy/03_one_to_many_relationships_sqlalchemy/start/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/06_sql_storage_sqlalchemy/03_one_to_many_relationships_sqlalchemy/start/resources/item.py
  class Item (line 13) | class Item(MethodView):
    method get (line 15) | def get(self, item_id):
    method delete (line 18) | def delete(self, item_id):
    method put (line 23) | def put(self, item_data, item_id):
  class ItemList (line 28) | class ItemList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, item_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/03_one_to_many_relationships_sqlalchemy/start/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 19) | def delete(self, store_id):
  class StoreList (line 24) | class StoreList(MethodView):
    method get (line 26) | def get(self):
    method post (line 31) | def post(self, store_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/03_one_to_many_relationships_sqlalchemy/start/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class ItemSchema (line 15) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 20) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 25) | class StoreSchema(PlainStoreSchema):

FILE: docs/docs/06_sql_storage_sqlalchemy/04_configure_flask_sqlalchemy/end/app.py
  function create_app (line 12) | def create_app(db_url=None):

FILE: docs/docs/06_sql_storage_sqlalchemy/04_configure_flask_sqlalchemy/end/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/06_sql_storage_sqlalchemy/04_configure_flask_sqlalchemy/end/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/06_sql_storage_sqlalchemy/04_configure_flask_sqlalchemy/end/resources/item.py
  class Item (line 13) | class Item(MethodView):
    method get (line 15) | def get(self, item_id):
    method delete (line 18) | def delete(self, item_id):
    method put (line 23) | def put(self, item_data, item_id):
  class ItemList (line 28) | class ItemList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, item_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/04_configure_flask_sqlalchemy/end/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 19) | def delete(self, store_id):
  class StoreList (line 24) | class StoreList(MethodView):
    method get (line 26) | def get(self):
    method post (line 31) | def post(self, store_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/04_configure_flask_sqlalchemy/end/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class ItemSchema (line 15) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 20) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 25) | class StoreSchema(PlainStoreSchema):

FILE: docs/docs/06_sql_storage_sqlalchemy/04_configure_flask_sqlalchemy/start/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/06_sql_storage_sqlalchemy/04_configure_flask_sqlalchemy/start/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/06_sql_storage_sqlalchemy/04_configure_flask_sqlalchemy/start/resources/item.py
  class Item (line 13) | class Item(MethodView):
    method get (line 15) | def get(self, item_id):
    method delete (line 18) | def delete(self, item_id):
    method put (line 23) | def put(self, item_data, item_id):
  class ItemList (line 28) | class ItemList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, item_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/04_configure_flask_sqlalchemy/start/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 19) | def delete(self, store_id):
  class StoreList (line 24) | class StoreList(MethodView):
    method get (line 26) | def get(self):
    method post (line 31) | def post(self, store_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/04_configure_flask_sqlalchemy/start/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class ItemSchema (line 15) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 20) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 25) | class StoreSchema(PlainStoreSchema):

FILE: docs/docs/06_sql_storage_sqlalchemy/05_insert_models_sqlalchemy/end/app.py
  function create_app (line 12) | def create_app(db_url=None):

FILE: docs/docs/06_sql_storage_sqlalchemy/05_insert_models_sqlalchemy/end/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/06_sql_storage_sqlalchemy/05_insert_models_sqlalchemy/end/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/06_sql_storage_sqlalchemy/05_insert_models_sqlalchemy/end/resources/item.py
  class Item (line 13) | class Item(MethodView):
    method get (line 15) | def get(self, item_id):
    method delete (line 18) | def delete(self, item_id):
    method put (line 23) | def put(self, item_data, item_id):
  class ItemList (line 28) | class ItemList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, item_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/05_insert_models_sqlalchemy/end/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 19) | def delete(self, store_id):
  class StoreList (line 24) | class StoreList(MethodView):
    method get (line 26) | def get(self):
    method post (line 31) | def post(self, store_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/05_insert_models_sqlalchemy/end/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class ItemSchema (line 15) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 20) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 25) | class StoreSchema(PlainStoreSchema):

FILE: docs/docs/06_sql_storage_sqlalchemy/05_insert_models_sqlalchemy/start/app.py
  function create_app (line 12) | def create_app(db_url=None):

FILE: docs/docs/06_sql_storage_sqlalchemy/05_insert_models_sqlalchemy/start/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/06_sql_storage_sqlalchemy/05_insert_models_sqlalchemy/start/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/06_sql_storage_sqlalchemy/05_insert_models_sqlalchemy/start/resources/item.py
  class Item (line 13) | class Item(MethodView):
    method get (line 15) | def get(self, item_id):
    method delete (line 18) | def delete(self, item_id):
    method put (line 23) | def put(self, item_data, item_id):
  class ItemList (line 28) | class ItemList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, item_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/05_insert_models_sqlalchemy/start/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 19) | def delete(self, store_id):
  class StoreList (line 24) | class StoreList(MethodView):
    method get (line 26) | def get(self):
    method post (line 31) | def post(self, store_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/05_insert_models_sqlalchemy/start/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class ItemSchema (line 15) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 20) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 25) | class StoreSchema(PlainStoreSchema):

FILE: docs/docs/06_sql_storage_sqlalchemy/06_get_models_or_404/end/app.py
  function create_app (line 12) | def create_app(db_url=None):

FILE: docs/docs/06_sql_storage_sqlalchemy/06_get_models_or_404/end/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/06_sql_storage_sqlalchemy/06_get_models_or_404/end/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/06_sql_storage_sqlalchemy/06_get_models_or_404/end/resources/item.py
  class Item (line 13) | class Item(MethodView):
    method get (line 15) | def get(self, item_id):
    method delete (line 19) | def delete(self, item_id):
    method put (line 25) | def put(self, item_data, item_id):
  class ItemList (line 32) | class ItemList(MethodView):
    method get (line 34) | def get(self):
    method post (line 39) | def post(self, item_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/06_get_models_or_404/end/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 20) | def delete(self, store_id):
  class StoreList (line 26) | class StoreList(MethodView):
    method get (line 28) | def get(self):
    method post (line 33) | def post(self, store_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/06_get_models_or_404/end/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class ItemSchema (line 15) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 20) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 25) | class StoreSchema(PlainStoreSchema):

FILE: docs/docs/06_sql_storage_sqlalchemy/06_get_models_or_404/start/app.py
  function create_app (line 12) | def create_app(db_url=None):

FILE: docs/docs/06_sql_storage_sqlalchemy/06_get_models_or_404/start/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/06_sql_storage_sqlalchemy/06_get_models_or_404/start/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/06_sql_storage_sqlalchemy/06_get_models_or_404/start/resources/item.py
  class Item (line 13) | class Item(MethodView):
    method get (line 15) | def get(self, item_id):
    method delete (line 18) | def delete(self, item_id):
    method put (line 23) | def put(self, item_data, item_id):
  class ItemList (line 28) | class ItemList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, item_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/06_get_models_or_404/start/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 19) | def delete(self, store_id):
  class StoreList (line 24) | class StoreList(MethodView):
    method get (line 26) | def get(self):
    method post (line 31) | def post(self, store_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/06_get_models_or_404/start/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class ItemSchema (line 15) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 20) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 25) | class StoreSchema(PlainStoreSchema):

FILE: docs/docs/06_sql_storage_sqlalchemy/07_updating_models_sqlalchemy/end/app.py
  function create_app (line 12) | def create_app(db_url=None):

FILE: docs/docs/06_sql_storage_sqlalchemy/07_updating_models_sqlalchemy/end/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/06_sql_storage_sqlalchemy/07_updating_models_sqlalchemy/end/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/06_sql_storage_sqlalchemy/07_updating_models_sqlalchemy/end/resources/item.py
  class Item (line 13) | class Item(MethodView):
    method get (line 15) | def get(self, item_id):
    method delete (line 19) | def delete(self, item_id):
    method put (line 25) | def put(self, item_data, item_id):
  class ItemList (line 41) | class ItemList(MethodView):
    method get (line 43) | def get(self):
    method post (line 48) | def post(self, item_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/07_updating_models_sqlalchemy/end/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 20) | def delete(self, store_id):
  class StoreList (line 26) | class StoreList(MethodView):
    method get (line 28) | def get(self):
    method post (line 33) | def post(self, store_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/07_updating_models_sqlalchemy/end/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class ItemSchema (line 15) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 20) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 25) | class StoreSchema(PlainStoreSchema):

FILE: docs/docs/06_sql_storage_sqlalchemy/07_updating_models_sqlalchemy/start/app.py
  function create_app (line 12) | def create_app(db_url=None):

FILE: docs/docs/06_sql_storage_sqlalchemy/07_updating_models_sqlalchemy/start/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/06_sql_storage_sqlalchemy/07_updating_models_sqlalchemy/start/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/06_sql_storage_sqlalchemy/07_updating_models_sqlalchemy/start/resources/item.py
  class Item (line 13) | class Item(MethodView):
    method get (line 15) | def get(self, item_id):
    method delete (line 19) | def delete(self, item_id):
    method put (line 25) | def put(self, item_data, item_id):
  class ItemList (line 32) | class ItemList(MethodView):
    method get (line 34) | def get(self):
    method post (line 39) | def post(self, item_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/07_updating_models_sqlalchemy/start/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 20) | def delete(self, store_id):
  class StoreList (line 26) | class StoreList(MethodView):
    method get (line 28) | def get(self):
    method post (line 33) | def post(self, store_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/07_updating_models_sqlalchemy/start/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class ItemSchema (line 15) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 20) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 25) | class StoreSchema(PlainStoreSchema):

FILE: docs/docs/06_sql_storage_sqlalchemy/08_retrieve_list_all_models/end/app.py
  function create_app (line 12) | def create_app(db_url=None):

FILE: docs/docs/06_sql_storage_sqlalchemy/08_retrieve_list_all_models/end/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/06_sql_storage_sqlalchemy/08_retrieve_list_all_models/end/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/06_sql_storage_sqlalchemy/08_retrieve_list_all_models/end/resources/item.py
  class Item (line 13) | class Item(MethodView):
    method get (line 15) | def get(self, item_id):
    method delete (line 19) | def delete(self, item_id):
    method put (line 25) | def put(self, item_data, item_id):
  class ItemList (line 41) | class ItemList(MethodView):
    method get (line 43) | def get(self):
    method post (line 48) | def post(self, item_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/08_retrieve_list_all_models/end/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 20) | def delete(self, store_id):
  class StoreList (line 26) | class StoreList(MethodView):
    method get (line 28) | def get(self):
    method post (line 33) | def post(self, store_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/08_retrieve_list_all_models/end/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class ItemSchema (line 15) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 20) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 25) | class StoreSchema(PlainStoreSchema):

FILE: docs/docs/06_sql_storage_sqlalchemy/08_retrieve_list_all_models/start/app.py
  function create_app (line 12) | def create_app(db_url=None):

FILE: docs/docs/06_sql_storage_sqlalchemy/08_retrieve_list_all_models/start/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/06_sql_storage_sqlalchemy/08_retrieve_list_all_models/start/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/06_sql_storage_sqlalchemy/08_retrieve_list_all_models/start/resources/item.py
  class Item (line 13) | class Item(MethodView):
    method get (line 15) | def get(self, item_id):
    method delete (line 19) | def delete(self, item_id):
    method put (line 25) | def put(self, item_data, item_id):
  class ItemList (line 41) | class ItemList(MethodView):
    method get (line 43) | def get(self):
    method post (line 48) | def post(self, item_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/08_retrieve_list_all_models/start/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 20) | def delete(self, store_id):
  class StoreList (line 26) | class StoreList(MethodView):
    method get (line 28) | def get(self):
    method post (line 33) | def post(self, store_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/08_retrieve_list_all_models/start/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class ItemSchema (line 15) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 20) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 25) | class StoreSchema(PlainStoreSchema):

FILE: docs/docs/06_sql_storage_sqlalchemy/09_delete_models_sqlalchemy/end/app.py
  function create_app (line 12) | def create_app(db_url=None):

FILE: docs/docs/06_sql_storage_sqlalchemy/09_delete_models_sqlalchemy/end/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/06_sql_storage_sqlalchemy/09_delete_models_sqlalchemy/end/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/06_sql_storage_sqlalchemy/09_delete_models_sqlalchemy/end/resources/item.py
  class Item (line 13) | class Item(MethodView):
    method get (line 15) | def get(self, item_id):
    method delete (line 19) | def delete(self, item_id):
    method put (line 27) | def put(self, item_data, item_id):
  class ItemList (line 43) | class ItemList(MethodView):
    method get (line 45) | def get(self):
    method post (line 50) | def post(self, item_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/09_delete_models_sqlalchemy/end/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 20) | def delete(self, store_id):
  class StoreList (line 28) | class StoreList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, store_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/09_delete_models_sqlalchemy/end/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class ItemSchema (line 15) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 20) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 25) | class StoreSchema(PlainStoreSchema):

FILE: docs/docs/06_sql_storage_sqlalchemy/09_delete_models_sqlalchemy/start/app.py
  function create_app (line 12) | def create_app(db_url=None):

FILE: docs/docs/06_sql_storage_sqlalchemy/09_delete_models_sqlalchemy/start/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/06_sql_storage_sqlalchemy/09_delete_models_sqlalchemy/start/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/06_sql_storage_sqlalchemy/09_delete_models_sqlalchemy/start/resources/item.py
  class Item (line 13) | class Item(MethodView):
    method get (line 15) | def get(self, item_id):
    method delete (line 19) | def delete(self, item_id):
    method put (line 25) | def put(self, item_data, item_id):
  class ItemList (line 41) | class ItemList(MethodView):
    method get (line 43) | def get(self):
    method post (line 48) | def post(self, item_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/09_delete_models_sqlalchemy/start/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 20) | def delete(self, store_id):
  class StoreList (line 26) | class StoreList(MethodView):
    method get (line 28) | def get(self):
    method post (line 33) | def post(self, store_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/09_delete_models_sqlalchemy/start/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class ItemSchema (line 15) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 20) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 25) | class StoreSchema(PlainStoreSchema):

FILE: docs/docs/06_sql_storage_sqlalchemy/10_delete_related_models_sqlalchemy/end/app.py
  function create_app (line 12) | def create_app(db_url=None):

FILE: docs/docs/06_sql_storage_sqlalchemy/10_delete_related_models_sqlalchemy/end/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/06_sql_storage_sqlalchemy/10_delete_related_models_sqlalchemy/end/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/06_sql_storage_sqlalchemy/10_delete_related_models_sqlalchemy/end/resources/item.py
  class Item (line 13) | class Item(MethodView):
    method get (line 15) | def get(self, item_id):
    method delete (line 19) | def delete(self, item_id):
    method put (line 27) | def put(self, item_data, item_id):
  class ItemList (line 43) | class ItemList(MethodView):
    method get (line 45) | def get(self):
    method post (line 50) | def post(self, item_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/10_delete_related_models_sqlalchemy/end/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 20) | def delete(self, store_id):
  class StoreList (line 28) | class StoreList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, store_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/10_delete_related_models_sqlalchemy/end/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class ItemSchema (line 15) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 20) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 25) | class StoreSchema(PlainStoreSchema):

FILE: docs/docs/06_sql_storage_sqlalchemy/10_delete_related_models_sqlalchemy/start/app.py
  function create_app (line 12) | def create_app(db_url=None):

FILE: docs/docs/06_sql_storage_sqlalchemy/10_delete_related_models_sqlalchemy/start/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/06_sql_storage_sqlalchemy/10_delete_related_models_sqlalchemy/start/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/06_sql_storage_sqlalchemy/10_delete_related_models_sqlalchemy/start/resources/item.py
  class Item (line 13) | class Item(MethodView):
    method get (line 15) | def get(self, item_id):
    method delete (line 19) | def delete(self, item_id):
    method put (line 27) | def put(self, item_data, item_id):
  class ItemList (line 43) | class ItemList(MethodView):
    method get (line 45) | def get(self):
    method post (line 50) | def post(self, item_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/10_delete_related_models_sqlalchemy/start/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 20) | def delete(self, store_id):
  class StoreList (line 28) | class StoreList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, store_data):

FILE: docs/docs/06_sql_storage_sqlalchemy/10_delete_related_models_sqlalchemy/start/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class ItemSchema (line 15) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 20) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 25) | class StoreSchema(PlainStoreSchema):

FILE: docs/docs/07_sqlalchemy_many_to_many/02_one_to_many_review/end/app.py
  function create_app (line 12) | def create_app(db_url=None):

FILE: docs/docs/07_sqlalchemy_many_to_many/02_one_to_many_review/end/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/07_sqlalchemy_many_to_many/02_one_to_many_review/end/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/07_sqlalchemy_many_to_many/02_one_to_many_review/end/models/tag.py
  class TagModel (line 4) | class TagModel(db.Model):

FILE: docs/docs/07_sqlalchemy_many_to_many/02_one_to_many_review/end/resources/item.py
  class Item (line 13) | class Item(MethodView):
    method get (line 15) | def get(self, item_id):
    method delete (line 19) | def delete(self, item_id):
    method put (line 27) | def put(self, item_data, item_id):
  class ItemList (line 43) | class ItemList(MethodView):
    method get (line 45) | def get(self):
    method post (line 50) | def post(self, item_data):

FILE: docs/docs/07_sqlalchemy_many_to_many/02_one_to_many_review/end/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 20) | def delete(self, store_id):
  class StoreList (line 28) | class StoreList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, store_data):

FILE: docs/docs/07_sqlalchemy_many_to_many/02_one_to_many_review/end/resources/tag.py
  class TagsInStore (line 13) | class TagsInStore(MethodView):
    method get (line 15) | def get(self, store_id):
    method post (line 22) | def post(self, tag_data, store_id):
  class Tag (line 41) | class Tag(MethodView):
    method get (line 43) | def get(self, tag_id):

FILE: docs/docs/07_sqlalchemy_many_to_many/02_one_to_many_review/end/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class PlainTagSchema (line 15) | class PlainTagSchema(Schema):
  class ItemSchema (line 20) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 25) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 30) | class StoreSchema(PlainStoreSchema):
  class TagSchema (line 35) | class TagSchema(PlainTagSchema):

FILE: docs/docs/07_sqlalchemy_many_to_many/02_one_to_many_review/start/app.py
  function create_app (line 11) | def create_app(db_url=None):

FILE: docs/docs/07_sqlalchemy_many_to_many/02_one_to_many_review/start/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/07_sqlalchemy_many_to_many/02_one_to_many_review/start/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/07_sqlalchemy_many_to_many/02_one_to_many_review/start/resources/item.py
  class Item (line 13) | class Item(MethodView):
    method get (line 15) | def get(self, item_id):
    method delete (line 19) | def delete(self, item_id):
    method put (line 27) | def put(self, item_data, item_id):
  class ItemList (line 43) | class ItemList(MethodView):
    method get (line 45) | def get(self):
    method post (line 50) | def post(self, item_data):

FILE: docs/docs/07_sqlalchemy_many_to_many/02_one_to_many_review/start/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 20) | def delete(self, store_id):
  class StoreList (line 28) | class StoreList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, store_data):

FILE: docs/docs/07_sqlalchemy_many_to_many/02_one_to_many_review/start/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class ItemSchema (line 15) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 20) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 25) | class StoreSchema(PlainStoreSchema):

FILE: docs/docs/07_sqlalchemy_many_to_many/03_many_to_many_relationships/end/app.py
  function create_app (line 12) | def create_app(db_url=None):

FILE: docs/docs/07_sqlalchemy_many_to_many/03_many_to_many_relationships/end/conftest.py
  function app (line 6) | def app():
  function client (line 18) | def client(app):

FILE: docs/docs/07_sqlalchemy_many_to_many/03_many_to_many_relationships/end/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/07_sqlalchemy_many_to_many/03_many_to_many_relationships/end/models/item_tags.py
  class ItemsTags (line 4) | class ItemsTags(db.Model):

FILE: docs/docs/07_sqlalchemy_many_to_many/03_many_to_many_relationships/end/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/07_sqlalchemy_many_to_many/03_many_to_many_relationships/end/models/tag.py
  class TagModel (line 4) | class TagModel(db.Model):

FILE: docs/docs/07_sqlalchemy_many_to_many/03_many_to_many_relationships/end/resources/item.py
  class Item (line 13) | class Item(MethodView):
    method get (line 15) | def get(self, item_id):
    method delete (line 19) | def delete(self, item_id):
    method put (line 27) | def put(self, item_data, item_id):
  class ItemList (line 43) | class ItemList(MethodView):
    method get (line 45) | def get(self):
    method post (line 50) | def post(self, item_data):

FILE: docs/docs/07_sqlalchemy_many_to_many/03_many_to_many_relationships/end/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 20) | def delete(self, store_id):
  class StoreList (line 28) | class StoreList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, store_data):

FILE: docs/docs/07_sqlalchemy_many_to_many/03_many_to_many_relationships/end/resources/tag.py
  class TagsInStore (line 13) | class TagsInStore(MethodView):
    method get (line 15) | def get(self, store_id):
    method post (line 22) | def post(self, tag_data, store_id):
  class LinkTagsToItem (line 41) | class LinkTagsToItem(MethodView):
    method post (line 43) | def post(self, item_id, tag_id):
    method delete (line 58) | def delete(self, item_id, tag_id):
  class Tag (line 74) | class Tag(MethodView):
    method get (line 76) | def get(self, tag_id):
    method delete (line 90) | def delete(self, tag_id):

FILE: docs/docs/07_sqlalchemy_many_to_many/03_many_to_many_relationships/end/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class PlainTagSchema (line 15) | class PlainTagSchema(Schema):
  class ItemSchema (line 20) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 26) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 31) | class StoreSchema(PlainStoreSchema):
  class TagSchema (line 36) | class TagSchema(PlainTagSchema):
  class TagAndItemSchema (line 42) | class TagAndItemSchema(Schema):

FILE: docs/docs/07_sqlalchemy_many_to_many/03_many_to_many_relationships/start/app.py
  function create_app (line 12) | def create_app(db_url=None):

FILE: docs/docs/07_sqlalchemy_many_to_many/03_many_to_many_relationships/start/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/07_sqlalchemy_many_to_many/03_many_to_many_relationships/start/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/07_sqlalchemy_many_to_many/03_many_to_many_relationships/start/models/tag.py
  class TagModel (line 4) | class TagModel(db.Model):

FILE: docs/docs/07_sqlalchemy_many_to_many/03_many_to_many_relationships/start/resources/item.py
  class Item (line 13) | class Item(MethodView):
    method get (line 15) | def get(self, item_id):
    method delete (line 19) | def delete(self, item_id):
    method put (line 27) | def put(self, item_data, item_id):
  class ItemList (line 43) | class ItemList(MethodView):
    method get (line 45) | def get(self):
    method post (line 50) | def post(self, item_data):

FILE: docs/docs/07_sqlalchemy_many_to_many/03_many_to_many_relationships/start/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 20) | def delete(self, store_id):
  class StoreList (line 28) | class StoreList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, store_data):

FILE: docs/docs/07_sqlalchemy_many_to_many/03_many_to_many_relationships/start/resources/tag.py
  class TagsInStore (line 13) | class TagsInStore(MethodView):
    method get (line 15) | def get(self, store_id):
    method post (line 22) | def post(self, tag_data, store_id):
  class Tag (line 41) | class Tag(MethodView):
    method get (line 43) | def get(self, tag_id):

FILE: docs/docs/07_sqlalchemy_many_to_many/03_many_to_many_relationships/start/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class PlainTagSchema (line 15) | class PlainTagSchema(Schema):
  class ItemSchema (line 20) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 25) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 30) | class StoreSchema(PlainStoreSchema):
  class TagSchema (line 35) | class TagSchema(PlainTagSchema):

FILE: docs/docs/08_flask_jwt_extended/04_flask_jwt_extended_setup/end/app.py
  function create_app (line 12) | def create_app(db_url=None):

FILE: docs/docs/08_flask_jwt_extended/04_flask_jwt_extended_setup/end/conftest.py
  function app (line 6) | def app():
  function client (line 18) | def client(app):

FILE: docs/docs/08_flask_jwt_extended/04_flask_jwt_extended_setup/end/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/04_flask_jwt_extended_setup/end/models/item_tags.py
  class ItemsTags (line 4) | class ItemsTags(db.Model):

FILE: docs/docs/08_flask_jwt_extended/04_flask_jwt_extended_setup/end/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/04_flask_jwt_extended_setup/end/models/tag.py
  class TagModel (line 4) | class TagModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/04_flask_jwt_extended_setup/end/resources/__tests__/conftest.py
  function created_store_id (line 5) | def created_store_id(client):
  function created_item_id (line 15) | def created_item_id(client, created_store_id):
  function created_tag_id (line 25) | def created_tag_id(client, created_store_id):

FILE: docs/docs/08_flask_jwt_extended/04_flask_jwt_extended_setup/end/resources/__tests__/test_item.py
  function test_create_item_in_store (line 1) | def test_create_item_in_store(client, created_store_id):
  function test_create_item_with_store_id_not_found (line 13) | def test_create_item_with_store_id_not_found(client):
  function test_create_item_with_unknown_data (line 26) | def test_create_item_with_unknown_data(client):
  function test_delete_item (line 41) | def test_delete_item(client, created_item_id):
  function test_update_item (line 50) | def test_update_item(client, created_item_id):
  function test_get_all_items (line 61) | def test_get_all_items(client):
  function test_get_all_items_empty (line 82) | def test_get_all_items_empty(client):
  function test_get_item_details (line 91) | def test_get_item_details(client, created_item_id, created_store_id):
  function test_get_item_details_with_tag (line 102) | def test_get_item_details_with_tag(client, created_item_id, created_tag_...
  function test_get_item_detail_not_found (line 114) | def test_get_item_detail_not_found(client):

FILE: docs/docs/08_flask_jwt_extended/04_flask_jwt_extended_setup/end/resources/__tests__/test_store.py
  function test_get_store (line 1) | def test_get_store(client, created_store_id):
  function test_get_store_not_found (line 15) | def test_get_store_not_found(client):
  function test_get_store_with_item (line 24) | def test_get_store_with_item(client, created_store_id):
  function test_get_store_with_tag (line 44) | def test_get_store_with_tag(client, created_store_id):
  function test_create_store (line 58) | def test_create_store(client):
  function test_create_store_with_items (line 68) | def test_create_store_with_items(client, created_store_id):
  function test_delete_store (line 89) | def test_delete_store(client, created_store_id):
  function test_delete_store_doesnt_exist (line 98) | def test_delete_store_doesnt_exist(client):
  function test_get_store_list_empty (line 107) | def test_get_store_list_empty(client):
  function test_get_store_list_single (line 116) | def test_get_store_list_single(client):
  function test_get_store_list_multiple (line 130) | def test_get_store_list_multiple(client):
  function test_get_store_list_with_items (line 151) | def test_get_store_list_with_items(client):
  function test_get_store_list_with_tags (line 182) | def test_get_store_list_with_tags(client):
  function test_create_store_duplicate_name (line 206) | def test_create_store_duplicate_name(client):

FILE: docs/docs/08_flask_jwt_extended/04_flask_jwt_extended_setup/end/resources/__tests__/test_tag.py
  function created_tag_with_item_id (line 8) | def created_tag_with_item_id(client, created_item_id, created_tag_id):
  function test_get_tag (line 18) | def test_get_tag(client, created_tag_id):
  function test_get_tag_not_found (line 32) | def test_get_tag_not_found(client):
  function test_items_linked_with_tag (line 41) | def test_items_linked_with_tag(client, created_tag_with_item_id):
  function test_unlink_tag_from_item (line 56) | def test_unlink_tag_from_item(client, created_item_id, created_tag_with_...
  function test_delete_tag_without_items (line 67) | def test_delete_tag_without_items(client, created_tag_id):
  function test_delete_tag_still_has_items (line 80) | def test_delete_tag_still_has_items(client, created_tag_with_item_id):
  function test_delete_tag_not_found (line 90) | def test_delete_tag_not_found(client):
  function test_get_all_tags_in_store (line 99) | def test_get_all_tags_in_store(client, created_store_id, created_tag_id):
  function test_get_all_tags_in_store_not_found (line 115) | def test_get_all_tags_in_store_not_found(client):

FILE: docs/docs/08_flask_jwt_extended/04_flask_jwt_extended_setup/end/resources/item.py
  class Item (line 13) | class Item(MethodView):
    method get (line 15) | def get(self, item_id):
    method delete (line 19) | def delete(self, item_id):
    method put (line 27) | def put(self, item_data, item_id):
  class ItemList (line 43) | class ItemList(MethodView):
    method get (line 45) | def get(self):
    method post (line 50) | def post(self, item_data):

FILE: docs/docs/08_flask_jwt_extended/04_flask_jwt_extended_setup/end/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 20) | def delete(self, store_id):
  class StoreList (line 28) | class StoreList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, store_data):

FILE: docs/docs/08_flask_jwt_extended/04_flask_jwt_extended_setup/end/resources/tag.py
  class TagsInStore (line 13) | class TagsInStore(MethodView):
    method get (line 15) | def get(self, store_id):
    method post (line 22) | def post(self, tag_data, store_id):
  class LinkTagsToItem (line 41) | class LinkTagsToItem(MethodView):
    method post (line 43) | def post(self, item_id, tag_id):
    method delete (line 58) | def delete(self, item_id, tag_id):
  class Tag (line 74) | class Tag(MethodView):
    method get (line 76) | def get(self, tag_id):
    method delete (line 90) | def delete(self, tag_id):

FILE: docs/docs/08_flask_jwt_extended/04_flask_jwt_extended_setup/end/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class PlainTagSchema (line 15) | class PlainTagSchema(Schema):
  class ItemSchema (line 20) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 26) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 31) | class StoreSchema(PlainStoreSchema):
  class TagSchema (line 36) | class TagSchema(PlainTagSchema):
  class TagAndItemSchema (line 42) | class TagAndItemSchema(Schema):

FILE: docs/docs/08_flask_jwt_extended/04_flask_jwt_extended_setup/start/app.py
  function create_app (line 11) | def create_app(db_url=None):

FILE: docs/docs/08_flask_jwt_extended/04_flask_jwt_extended_setup/start/conftest.py
  function app (line 6) | def app():
  function client (line 18) | def client(app):

FILE: docs/docs/08_flask_jwt_extended/04_flask_jwt_extended_setup/start/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/04_flask_jwt_extended_setup/start/models/item_tags.py
  class ItemsTags (line 4) | class ItemsTags(db.Model):

FILE: docs/docs/08_flask_jwt_extended/04_flask_jwt_extended_setup/start/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/04_flask_jwt_extended_setup/start/models/tag.py
  class TagModel (line 4) | class TagModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/04_flask_jwt_extended_setup/start/resources/__tests__/conftest.py
  function created_store_id (line 5) | def created_store_id(client):
  function created_item_id (line 15) | def created_item_id(client, created_store_id):
  function created_tag_id (line 25) | def created_tag_id(client, created_store_id):

FILE: docs/docs/08_flask_jwt_extended/04_flask_jwt_extended_setup/start/resources/__tests__/test_item.py
  function test_create_item_in_store (line 1) | def test_create_item_in_store(client, created_store_id):
  function test_create_item_with_store_id_not_found (line 13) | def test_create_item_with_store_id_not_found(client):
  function test_create_item_with_unknown_data (line 26) | def test_create_item_with_unknown_data(client):
  function test_delete_item (line 41) | def test_delete_item(client, created_item_id):
  function test_update_item (line 50) | def test_update_item(client, created_item_id):
  function test_get_all_items (line 61) | def test_get_all_items(client):
  function test_get_all_items_empty (line 82) | def test_get_all_items_empty(client):
  function test_get_item_details (line 91) | def test_get_item_details(client, created_item_id, created_store_id):
  function test_get_item_details_with_tag (line 102) | def test_get_item_details_with_tag(client, created_item_id, created_tag_...
  function test_get_item_detail_not_found (line 114) | def test_get_item_detail_not_found(client):

FILE: docs/docs/08_flask_jwt_extended/04_flask_jwt_extended_setup/start/resources/__tests__/test_store.py
  function test_get_store (line 1) | def test_get_store(client, created_store_id):
  function test_get_store_not_found (line 15) | def test_get_store_not_found(client):
  function test_get_store_with_item (line 24) | def test_get_store_with_item(client, created_store_id):
  function test_get_store_with_tag (line 44) | def test_get_store_with_tag(client, created_store_id):
  function test_create_store (line 58) | def test_create_store(client):
  function test_create_store_with_items (line 68) | def test_create_store_with_items(client, created_store_id):
  function test_delete_store (line 89) | def test_delete_store(client, created_store_id):
  function test_delete_store_doesnt_exist (line 98) | def test_delete_store_doesnt_exist(client):
  function test_get_store_list_empty (line 107) | def test_get_store_list_empty(client):
  function test_get_store_list_single (line 116) | def test_get_store_list_single(client):
  function test_get_store_list_multiple (line 130) | def test_get_store_list_multiple(client):
  function test_get_store_list_with_items (line 151) | def test_get_store_list_with_items(client):
  function test_get_store_list_with_tags (line 182) | def test_get_store_list_with_tags(client):
  function test_create_store_duplicate_name (line 206) | def test_create_store_duplicate_name(client):

FILE: docs/docs/08_flask_jwt_extended/04_flask_jwt_extended_setup/start/resources/__tests__/test_tag.py
  function created_tag_with_item_id (line 8) | def created_tag_with_item_id(client, created_item_id, created_tag_id):
  function test_get_tag (line 18) | def test_get_tag(client, created_tag_id):
  function test_get_tag_not_found (line 32) | def test_get_tag_not_found(client):
  function test_items_linked_with_tag (line 41) | def test_items_linked_with_tag(client, created_tag_with_item_id):
  function test_unlink_tag_from_item (line 56) | def test_unlink_tag_from_item(client, created_item_id, created_tag_with_...
  function test_delete_tag_without_items (line 67) | def test_delete_tag_without_items(client, created_tag_id):
  function test_delete_tag_still_has_items (line 80) | def test_delete_tag_still_has_items(client, created_tag_with_item_id):
  function test_delete_tag_not_found (line 90) | def test_delete_tag_not_found(client):
  function test_get_all_tags_in_store (line 99) | def test_get_all_tags_in_store(client, created_store_id, created_tag_id):
  function test_get_all_tags_in_store_not_found (line 115) | def test_get_all_tags_in_store_not_found(client):

FILE: docs/docs/08_flask_jwt_extended/04_flask_jwt_extended_setup/start/resources/item.py
  class Item (line 13) | class Item(MethodView):
    method get (line 15) | def get(self, item_id):
    method delete (line 19) | def delete(self, item_id):
    method put (line 27) | def put(self, item_data, item_id):
  class ItemList (line 43) | class ItemList(MethodView):
    method get (line 45) | def get(self):
    method post (line 50) | def post(self, item_data):

FILE: docs/docs/08_flask_jwt_extended/04_flask_jwt_extended_setup/start/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 20) | def delete(self, store_id):
  class StoreList (line 28) | class StoreList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, store_data):

FILE: docs/docs/08_flask_jwt_extended/04_flask_jwt_extended_setup/start/resources/tag.py
  class TagsInStore (line 13) | class TagsInStore(MethodView):
    method get (line 15) | def get(self, store_id):
    method post (line 22) | def post(self, tag_data, store_id):
  class LinkTagsToItem (line 41) | class LinkTagsToItem(MethodView):
    method post (line 43) | def post(self, item_id, tag_id):
    method delete (line 58) | def delete(self, item_id, tag_id):
  class Tag (line 74) | class Tag(MethodView):
    method get (line 76) | def get(self, tag_id):
    method delete (line 90) | def delete(self, tag_id):

FILE: docs/docs/08_flask_jwt_extended/04_flask_jwt_extended_setup/start/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class PlainTagSchema (line 15) | class PlainTagSchema(Schema):
  class ItemSchema (line 20) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 26) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 31) | class StoreSchema(PlainStoreSchema):
  class TagSchema (line 36) | class TagSchema(PlainTagSchema):
  class TagAndItemSchema (line 42) | class TagAndItemSchema(Schema):

FILE: docs/docs/08_flask_jwt_extended/05_user_model_and_schema/end/app.py
  function create_app (line 12) | def create_app(db_url=None):

FILE: docs/docs/08_flask_jwt_extended/05_user_model_and_schema/end/conftest.py
  function app (line 6) | def app():
  function client (line 18) | def client(app):

FILE: docs/docs/08_flask_jwt_extended/05_user_model_and_schema/end/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/05_user_model_and_schema/end/models/item_tags.py
  class ItemsTags (line 4) | class ItemsTags(db.Model):

FILE: docs/docs/08_flask_jwt_extended/05_user_model_and_schema/end/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/05_user_model_and_schema/end/models/tag.py
  class TagModel (line 4) | class TagModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/05_user_model_and_schema/end/models/user.py
  class UserModel (line 4) | class UserModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/05_user_model_and_schema/end/resources/__tests__/conftest.py
  function created_store_id (line 5) | def created_store_id(client):
  function created_item_id (line 15) | def created_item_id(client, created_store_id):
  function created_tag_id (line 25) | def created_tag_id(client, created_store_id):

FILE: docs/docs/08_flask_jwt_extended/05_user_model_and_schema/end/resources/__tests__/test_item.py
  function test_create_item_in_store (line 1) | def test_create_item_in_store(client, created_store_id):
  function test_create_item_with_store_id_not_found (line 13) | def test_create_item_with_store_id_not_found(client):
  function test_create_item_with_unknown_data (line 26) | def test_create_item_with_unknown_data(client):
  function test_delete_item (line 41) | def test_delete_item(client, created_item_id):
  function test_update_item (line 50) | def test_update_item(client, created_item_id):
  function test_get_all_items (line 61) | def test_get_all_items(client):
  function test_get_all_items_empty (line 82) | def test_get_all_items_empty(client):
  function test_get_item_details (line 91) | def test_get_item_details(client, created_item_id, created_store_id):
  function test_get_item_details_with_tag (line 102) | def test_get_item_details_with_tag(client, created_item_id, created_tag_...
  function test_get_item_detail_not_found (line 114) | def test_get_item_detail_not_found(client):

FILE: docs/docs/08_flask_jwt_extended/05_user_model_and_schema/end/resources/__tests__/test_store.py
  function test_get_store (line 1) | def test_get_store(client, created_store_id):
  function test_get_store_not_found (line 15) | def test_get_store_not_found(client):
  function test_get_store_with_item (line 24) | def test_get_store_with_item(client, created_store_id):
  function test_get_store_with_tag (line 44) | def test_get_store_with_tag(client, created_store_id):
  function test_create_store (line 58) | def test_create_store(client):
  function test_create_store_with_items (line 68) | def test_create_store_with_items(client, created_store_id):
  function test_delete_store (line 89) | def test_delete_store(client, created_store_id):
  function test_delete_store_doesnt_exist (line 98) | def test_delete_store_doesnt_exist(client):
  function test_get_store_list_empty (line 107) | def test_get_store_list_empty(client):
  function test_get_store_list_single (line 116) | def test_get_store_list_single(client):
  function test_get_store_list_multiple (line 130) | def test_get_store_list_multiple(client):
  function test_get_store_list_with_items (line 151) | def test_get_store_list_with_items(client):
  function test_get_store_list_with_tags (line 182) | def test_get_store_list_with_tags(client):
  function test_create_store_duplicate_name (line 206) | def test_create_store_duplicate_name(client):

FILE: docs/docs/08_flask_jwt_extended/05_user_model_and_schema/end/resources/__tests__/test_tag.py
  function created_tag_with_item_id (line 8) | def created_tag_with_item_id(client, created_item_id, created_tag_id):
  function test_get_tag (line 18) | def test_get_tag(client, created_tag_id):
  function test_get_tag_not_found (line 32) | def test_get_tag_not_found(client):
  function test_items_linked_with_tag (line 41) | def test_items_linked_with_tag(client, created_tag_with_item_id):
  function test_unlink_tag_from_item (line 56) | def test_unlink_tag_from_item(client, created_item_id, created_tag_with_...
  function test_delete_tag_without_items (line 67) | def test_delete_tag_without_items(client, created_tag_id):
  function test_delete_tag_still_has_items (line 80) | def test_delete_tag_still_has_items(client, created_tag_with_item_id):
  function test_delete_tag_not_found (line 90) | def test_delete_tag_not_found(client):
  function test_get_all_tags_in_store (line 99) | def test_get_all_tags_in_store(client, created_store_id, created_tag_id):
  function test_get_all_tags_in_store_not_found (line 115) | def test_get_all_tags_in_store_not_found(client):

FILE: docs/docs/08_flask_jwt_extended/05_user_model_and_schema/end/resources/item.py
  class Item (line 13) | class Item(MethodView):
    method get (line 15) | def get(self, item_id):
    method delete (line 19) | def delete(self, item_id):
    method put (line 27) | def put(self, item_data, item_id):
  class ItemList (line 43) | class ItemList(MethodView):
    method get (line 45) | def get(self):
    method post (line 50) | def post(self, item_data):

FILE: docs/docs/08_flask_jwt_extended/05_user_model_and_schema/end/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 20) | def delete(self, store_id):
  class StoreList (line 28) | class StoreList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, store_data):

FILE: docs/docs/08_flask_jwt_extended/05_user_model_and_schema/end/resources/tag.py
  class TagsInStore (line 13) | class TagsInStore(MethodView):
    method get (line 15) | def get(self, store_id):
    method post (line 22) | def post(self, tag_data, store_id):
  class LinkTagsToItem (line 41) | class LinkTagsToItem(MethodView):
    method post (line 43) | def post(self, item_id, tag_id):
    method delete (line 58) | def delete(self, item_id, tag_id):
  class Tag (line 74) | class Tag(MethodView):
    method get (line 76) | def get(self, tag_id):
    method delete (line 90) | def delete(self, tag_id):

FILE: docs/docs/08_flask_jwt_extended/05_user_model_and_schema/end/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class PlainTagSchema (line 15) | class PlainTagSchema(Schema):
  class ItemSchema (line 20) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 26) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 31) | class StoreSchema(PlainStoreSchema):
  class TagSchema (line 36) | class TagSchema(PlainTagSchema):
  class TagAndItemSchema (line 42) | class TagAndItemSchema(Schema):
  class UserSchema (line 48) | class UserSchema(Schema):

FILE: docs/docs/08_flask_jwt_extended/05_user_model_and_schema/start/app.py
  function create_app (line 12) | def create_app(db_url=None):

FILE: docs/docs/08_flask_jwt_extended/05_user_model_and_schema/start/conftest.py
  function app (line 6) | def app():
  function client (line 18) | def client(app):

FILE: docs/docs/08_flask_jwt_extended/05_user_model_and_schema/start/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/05_user_model_and_schema/start/models/item_tags.py
  class ItemsTags (line 4) | class ItemsTags(db.Model):

FILE: docs/docs/08_flask_jwt_extended/05_user_model_and_schema/start/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/05_user_model_and_schema/start/models/tag.py
  class TagModel (line 4) | class TagModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/05_user_model_and_schema/start/resources/__tests__/conftest.py
  function created_store_id (line 5) | def created_store_id(client):
  function created_item_id (line 15) | def created_item_id(client, created_store_id):
  function created_tag_id (line 25) | def created_tag_id(client, created_store_id):

FILE: docs/docs/08_flask_jwt_extended/05_user_model_and_schema/start/resources/__tests__/test_item.py
  function test_create_item_in_store (line 1) | def test_create_item_in_store(client, created_store_id):
  function test_create_item_with_store_id_not_found (line 13) | def test_create_item_with_store_id_not_found(client):
  function test_create_item_with_unknown_data (line 26) | def test_create_item_with_unknown_data(client):
  function test_delete_item (line 41) | def test_delete_item(client, created_item_id):
  function test_update_item (line 50) | def test_update_item(client, created_item_id):
  function test_get_all_items (line 61) | def test_get_all_items(client):
  function test_get_all_items_empty (line 82) | def test_get_all_items_empty(client):
  function test_get_item_details (line 91) | def test_get_item_details(client, created_item_id, created_store_id):
  function test_get_item_details_with_tag (line 102) | def test_get_item_details_with_tag(client, created_item_id, created_tag_...
  function test_get_item_detail_not_found (line 114) | def test_get_item_detail_not_found(client):

FILE: docs/docs/08_flask_jwt_extended/05_user_model_and_schema/start/resources/__tests__/test_store.py
  function test_get_store (line 1) | def test_get_store(client, created_store_id):
  function test_get_store_not_found (line 15) | def test_get_store_not_found(client):
  function test_get_store_with_item (line 24) | def test_get_store_with_item(client, created_store_id):
  function test_get_store_with_tag (line 44) | def test_get_store_with_tag(client, created_store_id):
  function test_create_store (line 58) | def test_create_store(client):
  function test_create_store_with_items (line 68) | def test_create_store_with_items(client, created_store_id):
  function test_delete_store (line 89) | def test_delete_store(client, created_store_id):
  function test_delete_store_doesnt_exist (line 98) | def test_delete_store_doesnt_exist(client):
  function test_get_store_list_empty (line 107) | def test_get_store_list_empty(client):
  function test_get_store_list_single (line 116) | def test_get_store_list_single(client):
  function test_get_store_list_multiple (line 130) | def test_get_store_list_multiple(client):
  function test_get_store_list_with_items (line 151) | def test_get_store_list_with_items(client):
  function test_get_store_list_with_tags (line 182) | def test_get_store_list_with_tags(client):
  function test_create_store_duplicate_name (line 206) | def test_create_store_duplicate_name(client):

FILE: docs/docs/08_flask_jwt_extended/05_user_model_and_schema/start/resources/__tests__/test_tag.py
  function created_tag_with_item_id (line 8) | def created_tag_with_item_id(client, created_item_id, created_tag_id):
  function test_get_tag (line 18) | def test_get_tag(client, created_tag_id):
  function test_get_tag_not_found (line 32) | def test_get_tag_not_found(client):
  function test_items_linked_with_tag (line 41) | def test_items_linked_with_tag(client, created_tag_with_item_id):
  function test_unlink_tag_from_item (line 56) | def test_unlink_tag_from_item(client, created_item_id, created_tag_with_...
  function test_delete_tag_without_items (line 67) | def test_delete_tag_without_items(client, created_tag_id):
  function test_delete_tag_still_has_items (line 80) | def test_delete_tag_still_has_items(client, created_tag_with_item_id):
  function test_delete_tag_not_found (line 90) | def test_delete_tag_not_found(client):
  function test_get_all_tags_in_store (line 99) | def test_get_all_tags_in_store(client, created_store_id, created_tag_id):
  function test_get_all_tags_in_store_not_found (line 115) | def test_get_all_tags_in_store_not_found(client):

FILE: docs/docs/08_flask_jwt_extended/05_user_model_and_schema/start/resources/item.py
  class Item (line 13) | class Item(MethodView):
    method get (line 15) | def get(self, item_id):
    method delete (line 19) | def delete(self, item_id):
    method put (line 27) | def put(self, item_data, item_id):
  class ItemList (line 43) | class ItemList(MethodView):
    method get (line 45) | def get(self):
    method post (line 50) | def post(self, item_data):

FILE: docs/docs/08_flask_jwt_extended/05_user_model_and_schema/start/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 20) | def delete(self, store_id):
  class StoreList (line 28) | class StoreList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, store_data):

FILE: docs/docs/08_flask_jwt_extended/05_user_model_and_schema/start/resources/tag.py
  class TagsInStore (line 13) | class TagsInStore(MethodView):
    method get (line 15) | def get(self, store_id):
    method post (line 22) | def post(self, tag_data, store_id):
  class LinkTagsToItem (line 41) | class LinkTagsToItem(MethodView):
    method post (line 43) | def post(self, item_id, tag_id):
    method delete (line 58) | def delete(self, item_id, tag_id):
  class Tag (line 74) | class Tag(MethodView):
    method get (line 76) | def get(self, tag_id):
    method delete (line 90) | def delete(self, tag_id):

FILE: docs/docs/08_flask_jwt_extended/05_user_model_and_schema/start/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class PlainTagSchema (line 15) | class PlainTagSchema(Schema):
  class ItemSchema (line 20) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 26) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 31) | class StoreSchema(PlainStoreSchema):
  class TagSchema (line 36) | class TagSchema(PlainTagSchema):
  class TagAndItemSchema (line 42) | class TagAndItemSchema(Schema):

FILE: docs/docs/08_flask_jwt_extended/06_registering_users_rest_api/end/app.py
  function create_app (line 13) | def create_app(db_url=None):

FILE: docs/docs/08_flask_jwt_extended/06_registering_users_rest_api/end/conftest.py
  function app (line 6) | def app():
  function client (line 18) | def client(app):

FILE: docs/docs/08_flask_jwt_extended/06_registering_users_rest_api/end/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/06_registering_users_rest_api/end/models/item_tags.py
  class ItemsTags (line 4) | class ItemsTags(db.Model):

FILE: docs/docs/08_flask_jwt_extended/06_registering_users_rest_api/end/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/06_registering_users_rest_api/end/models/tag.py
  class TagModel (line 4) | class TagModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/06_registering_users_rest_api/end/models/user.py
  class UserModel (line 4) | class UserModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/06_registering_users_rest_api/end/resources/__tests__/conftest.py
  function created_store_id (line 5) | def created_store_id(client):
  function created_item_id (line 15) | def created_item_id(client, created_store_id):
  function created_tag_id (line 25) | def created_tag_id(client, created_store_id):

FILE: docs/docs/08_flask_jwt_extended/06_registering_users_rest_api/end/resources/__tests__/test_item.py
  function test_create_item_in_store (line 1) | def test_create_item_in_store(client, created_store_id):
  function test_create_item_with_store_id_not_found (line 13) | def test_create_item_with_store_id_not_found(client):
  function test_create_item_with_unknown_data (line 26) | def test_create_item_with_unknown_data(client):
  function test_delete_item (line 41) | def test_delete_item(client, created_item_id):
  function test_update_item (line 50) | def test_update_item(client, created_item_id):
  function test_get_all_items (line 61) | def test_get_all_items(client):
  function test_get_all_items_empty (line 82) | def test_get_all_items_empty(client):
  function test_get_item_details (line 91) | def test_get_item_details(client, created_item_id, created_store_id):
  function test_get_item_details_with_tag (line 102) | def test_get_item_details_with_tag(client, created_item_id, created_tag_...
  function test_get_item_detail_not_found (line 114) | def test_get_item_detail_not_found(client):

FILE: docs/docs/08_flask_jwt_extended/06_registering_users_rest_api/end/resources/__tests__/test_store.py
  function test_get_store (line 1) | def test_get_store(client, created_store_id):
  function test_get_store_not_found (line 15) | def test_get_store_not_found(client):
  function test_get_store_with_item (line 24) | def test_get_store_with_item(client, created_store_id):
  function test_get_store_with_tag (line 44) | def test_get_store_with_tag(client, created_store_id):
  function test_create_store (line 58) | def test_create_store(client):
  function test_create_store_with_items (line 68) | def test_create_store_with_items(client, created_store_id):
  function test_delete_store (line 89) | def test_delete_store(client, created_store_id):
  function test_delete_store_doesnt_exist (line 98) | def test_delete_store_doesnt_exist(client):
  function test_get_store_list_empty (line 107) | def test_get_store_list_empty(client):
  function test_get_store_list_single (line 116) | def test_get_store_list_single(client):
  function test_get_store_list_multiple (line 130) | def test_get_store_list_multiple(client):
  function test_get_store_list_with_items (line 151) | def test_get_store_list_with_items(client):
  function test_get_store_list_with_tags (line 182) | def test_get_store_list_with_tags(client):
  function test_create_store_duplicate_name (line 206) | def test_create_store_duplicate_name(client):

FILE: docs/docs/08_flask_jwt_extended/06_registering_users_rest_api/end/resources/__tests__/test_tag.py
  function created_tag_with_item_id (line 8) | def created_tag_with_item_id(client, created_item_id, created_tag_id):
  function test_get_tag (line 18) | def test_get_tag(client, created_tag_id):
  function test_get_tag_not_found (line 32) | def test_get_tag_not_found(client):
  function test_items_linked_with_tag (line 41) | def test_items_linked_with_tag(client, created_tag_with_item_id):
  function test_unlink_tag_from_item (line 56) | def test_unlink_tag_from_item(client, created_item_id, created_tag_with_...
  function test_delete_tag_without_items (line 67) | def test_delete_tag_without_items(client, created_tag_id):
  function test_delete_tag_still_has_items (line 80) | def test_delete_tag_still_has_items(client, created_tag_with_item_id):
  function test_delete_tag_not_found (line 90) | def test_delete_tag_not_found(client):
  function test_get_all_tags_in_store (line 99) | def test_get_all_tags_in_store(client, created_store_id, created_tag_id):
  function test_get_all_tags_in_store_not_found (line 115) | def test_get_all_tags_in_store_not_found(client):

FILE: docs/docs/08_flask_jwt_extended/06_registering_users_rest_api/end/resources/__tests__/test_user.py
  function created_user_details (line 5) | def created_user_details(client):
  function test_register_user (line 16) | def test_register_user(client):
  function test_register_user_already_exists (line 27) | def test_register_user_already_exists(client):
  function test_register_user_missing_data (line 43) | def test_register_user_missing_data(client):
  function test_get_user_details (line 54) | def test_get_user_details(client, created_user_details):
  function test_get_user_details_missing (line 66) | def test_get_user_details_missing(client):

FILE: docs/docs/08_flask_jwt_extended/06_registering_users_rest_api/end/resources/item.py
  class Item (line 13) | class Item(MethodView):
    method get (line 15) | def get(self, item_id):
    method delete (line 19) | def delete(self, item_id):
    method put (line 27) | def put(self, item_data, item_id):
  class ItemList (line 43) | class ItemList(MethodView):
    method get (line 45) | def get(self):
    method post (line 50) | def post(self, item_data):

FILE: docs/docs/08_flask_jwt_extended/06_registering_users_rest_api/end/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 20) | def delete(self, store_id):
  class StoreList (line 28) | class StoreList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, store_data):

FILE: docs/docs/08_flask_jwt_extended/06_registering_users_rest_api/end/resources/tag.py
  class TagsInStore (line 13) | class TagsInStore(MethodView):
    method get (line 15) | def get(self, store_id):
    method post (line 22) | def post(self, tag_data, store_id):
  class LinkTagsToItem (line 41) | class LinkTagsToItem(MethodView):
    method post (line 43) | def post(self, item_id, tag_id):
    method delete (line 58) | def delete(self, item_id, tag_id):
  class Tag (line 74) | class Tag(MethodView):
    method get (line 76) | def get(self, tag_id):
    method delete (line 90) | def delete(self, tag_id):

FILE: docs/docs/08_flask_jwt_extended/06_registering_users_rest_api/end/resources/user.py
  class UserRegister (line 14) | class UserRegister(MethodView):
    method post (line 16) | def post(self, user_data):
  class User (line 31) | class User(MethodView):
    method get (line 40) | def get(self, user_id):
    method delete (line 44) | def delete(self, user_id):

FILE: docs/docs/08_flask_jwt_extended/06_registering_users_rest_api/end/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class PlainTagSchema (line 15) | class PlainTagSchema(Schema):
  class ItemSchema (line 20) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 26) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 31) | class StoreSchema(PlainStoreSchema):
  class TagSchema (line 36) | class TagSchema(PlainTagSchema):
  class TagAndItemSchema (line 42) | class TagAndItemSchema(Schema):
  class UserSchema (line 48) | class UserSchema(Schema):

FILE: docs/docs/08_flask_jwt_extended/06_registering_users_rest_api/start/app.py
  function create_app (line 12) | def create_app(db_url=None):

FILE: docs/docs/08_flask_jwt_extended/06_registering_users_rest_api/start/conftest.py
  function app (line 6) | def app():
  function client (line 18) | def client(app):

FILE: docs/docs/08_flask_jwt_extended/06_registering_users_rest_api/start/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/06_registering_users_rest_api/start/models/item_tags.py
  class ItemsTags (line 4) | class ItemsTags(db.Model):

FILE: docs/docs/08_flask_jwt_extended/06_registering_users_rest_api/start/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/06_registering_users_rest_api/start/models/tag.py
  class TagModel (line 4) | class TagModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/06_registering_users_rest_api/start/models/user.py
  class UserModel (line 4) | class UserModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/06_registering_users_rest_api/start/resources/__tests__/conftest.py
  function created_store_id (line 5) | def created_store_id(client):
  function created_item_id (line 15) | def created_item_id(client, created_store_id):
  function created_tag_id (line 25) | def created_tag_id(client, created_store_id):

FILE: docs/docs/08_flask_jwt_extended/06_registering_users_rest_api/start/resources/__tests__/test_item.py
  function test_create_item_in_store (line 1) | def test_create_item_in_store(client, created_store_id):
  function test_create_item_with_store_id_not_found (line 13) | def test_create_item_with_store_id_not_found(client):
  function test_create_item_with_unknown_data (line 26) | def test_create_item_with_unknown_data(client):
  function test_delete_item (line 41) | def test_delete_item(client, created_item_id):
  function test_update_item (line 50) | def test_update_item(client, created_item_id):
  function test_get_all_items (line 61) | def test_get_all_items(client):
  function test_get_all_items_empty (line 82) | def test_get_all_items_empty(client):
  function test_get_item_details (line 91) | def test_get_item_details(client, created_item_id, created_store_id):
  function test_get_item_details_with_tag (line 102) | def test_get_item_details_with_tag(client, created_item_id, created_tag_...
  function test_get_item_detail_not_found (line 114) | def test_get_item_detail_not_found(client):

FILE: docs/docs/08_flask_jwt_extended/06_registering_users_rest_api/start/resources/__tests__/test_store.py
  function test_get_store (line 1) | def test_get_store(client, created_store_id):
  function test_get_store_not_found (line 15) | def test_get_store_not_found(client):
  function test_get_store_with_item (line 24) | def test_get_store_with_item(client, created_store_id):
  function test_get_store_with_tag (line 44) | def test_get_store_with_tag(client, created_store_id):
  function test_create_store (line 58) | def test_create_store(client):
  function test_create_store_with_items (line 68) | def test_create_store_with_items(client, created_store_id):
  function test_delete_store (line 89) | def test_delete_store(client, created_store_id):
  function test_delete_store_doesnt_exist (line 98) | def test_delete_store_doesnt_exist(client):
  function test_get_store_list_empty (line 107) | def test_get_store_list_empty(client):
  function test_get_store_list_single (line 116) | def test_get_store_list_single(client):
  function test_get_store_list_multiple (line 130) | def test_get_store_list_multiple(client):
  function test_get_store_list_with_items (line 151) | def test_get_store_list_with_items(client):
  function test_get_store_list_with_tags (line 182) | def test_get_store_list_with_tags(client):
  function test_create_store_duplicate_name (line 206) | def test_create_store_duplicate_name(client):

FILE: docs/docs/08_flask_jwt_extended/06_registering_users_rest_api/start/resources/__tests__/test_tag.py
  function created_tag_with_item_id (line 8) | def created_tag_with_item_id(client, created_item_id, created_tag_id):
  function test_get_tag (line 18) | def test_get_tag(client, created_tag_id):
  function test_get_tag_not_found (line 32) | def test_get_tag_not_found(client):
  function test_items_linked_with_tag (line 41) | def test_items_linked_with_tag(client, created_tag_with_item_id):
  function test_unlink_tag_from_item (line 56) | def test_unlink_tag_from_item(client, created_item_id, created_tag_with_...
  function test_delete_tag_without_items (line 67) | def test_delete_tag_without_items(client, created_tag_id):
  function test_delete_tag_still_has_items (line 80) | def test_delete_tag_still_has_items(client, created_tag_with_item_id):
  function test_delete_tag_not_found (line 90) | def test_delete_tag_not_found(client):
  function test_get_all_tags_in_store (line 99) | def test_get_all_tags_in_store(client, created_store_id, created_tag_id):
  function test_get_all_tags_in_store_not_found (line 115) | def test_get_all_tags_in_store_not_found(client):

FILE: docs/docs/08_flask_jwt_extended/06_registering_users_rest_api/start/resources/item.py
  class Item (line 13) | class Item(MethodView):
    method get (line 15) | def get(self, item_id):
    method delete (line 19) | def delete(self, item_id):
    method put (line 27) | def put(self, item_data, item_id):
  class ItemList (line 43) | class ItemList(MethodView):
    method get (line 45) | def get(self):
    method post (line 50) | def post(self, item_data):

FILE: docs/docs/08_flask_jwt_extended/06_registering_users_rest_api/start/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 20) | def delete(self, store_id):
  class StoreList (line 28) | class StoreList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, store_data):

FILE: docs/docs/08_flask_jwt_extended/06_registering_users_rest_api/start/resources/tag.py
  class TagsInStore (line 13) | class TagsInStore(MethodView):
    method get (line 15) | def get(self, store_id):
    method post (line 22) | def post(self, tag_data, store_id):
  class LinkTagsToItem (line 41) | class LinkTagsToItem(MethodView):
    method post (line 43) | def post(self, item_id, tag_id):
    method delete (line 58) | def delete(self, item_id, tag_id):
  class Tag (line 74) | class Tag(MethodView):
    method get (line 76) | def get(self, tag_id):
    method delete (line 90) | def delete(self, tag_id):

FILE: docs/docs/08_flask_jwt_extended/06_registering_users_rest_api/start/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class PlainTagSchema (line 15) | class PlainTagSchema(Schema):
  class ItemSchema (line 20) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 26) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 31) | class StoreSchema(PlainStoreSchema):
  class TagSchema (line 36) | class TagSchema(PlainTagSchema):
  class TagAndItemSchema (line 42) | class TagAndItemSchema(Schema):
  class UserSchema (line 48) | class UserSchema(Schema):

FILE: docs/docs/08_flask_jwt_extended/07_login_users_rest_api/end/app.py
  function create_app (line 13) | def create_app(db_url=None):

FILE: docs/docs/08_flask_jwt_extended/07_login_users_rest_api/end/conftest.py
  function app (line 6) | def app():
  function client (line 18) | def client(app):

FILE: docs/docs/08_flask_jwt_extended/07_login_users_rest_api/end/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/07_login_users_rest_api/end/models/item_tags.py
  class ItemsTags (line 4) | class ItemsTags(db.Model):

FILE: docs/docs/08_flask_jwt_extended/07_login_users_rest_api/end/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/07_login_users_rest_api/end/models/tag.py
  class TagModel (line 4) | class TagModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/07_login_users_rest_api/end/models/user.py
  class UserModel (line 4) | class UserModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/07_login_users_rest_api/end/resources/__tests__/conftest.py
  function created_store_id (line 5) | def created_store_id(client):
  function created_item_id (line 15) | def created_item_id(client, created_store_id):
  function created_tag_id (line 25) | def created_tag_id(client, created_store_id):

FILE: docs/docs/08_flask_jwt_extended/07_login_users_rest_api/end/resources/__tests__/test_item.py
  function test_create_item_in_store (line 1) | def test_create_item_in_store(client, created_store_id):
  function test_create_item_with_store_id_not_found (line 13) | def test_create_item_with_store_id_not_found(client):
  function test_create_item_with_unknown_data (line 26) | def test_create_item_with_unknown_data(client):
  function test_delete_item (line 41) | def test_delete_item(client, created_item_id):
  function test_update_item (line 50) | def test_update_item(client, created_item_id):
  function test_get_all_items (line 61) | def test_get_all_items(client):
  function test_get_all_items_empty (line 82) | def test_get_all_items_empty(client):
  function test_get_item_details (line 91) | def test_get_item_details(client, created_item_id, created_store_id):
  function test_get_item_details_with_tag (line 102) | def test_get_item_details_with_tag(client, created_item_id, created_tag_...
  function test_get_item_detail_not_found (line 114) | def test_get_item_detail_not_found(client):

FILE: docs/docs/08_flask_jwt_extended/07_login_users_rest_api/end/resources/__tests__/test_store.py
  function test_get_store (line 1) | def test_get_store(client, created_store_id):
  function test_get_store_not_found (line 15) | def test_get_store_not_found(client):
  function test_get_store_with_item (line 24) | def test_get_store_with_item(client, created_store_id):
  function test_get_store_with_tag (line 44) | def test_get_store_with_tag(client, created_store_id):
  function test_create_store (line 58) | def test_create_store(client):
  function test_create_store_with_items (line 68) | def test_create_store_with_items(client, created_store_id):
  function test_delete_store (line 89) | def test_delete_store(client, created_store_id):
  function test_delete_store_doesnt_exist (line 98) | def test_delete_store_doesnt_exist(client):
  function test_get_store_list_empty (line 107) | def test_get_store_list_empty(client):
  function test_get_store_list_single (line 116) | def test_get_store_list_single(client):
  function test_get_store_list_multiple (line 130) | def test_get_store_list_multiple(client):
  function test_get_store_list_with_items (line 151) | def test_get_store_list_with_items(client):
  function test_get_store_list_with_tags (line 182) | def test_get_store_list_with_tags(client):
  function test_create_store_duplicate_name (line 206) | def test_create_store_duplicate_name(client):

FILE: docs/docs/08_flask_jwt_extended/07_login_users_rest_api/end/resources/__tests__/test_tag.py
  function created_tag_with_item_id (line 8) | def created_tag_with_item_id(client, created_item_id, created_tag_id):
  function test_get_tag (line 18) | def test_get_tag(client, created_tag_id):
  function test_get_tag_not_found (line 32) | def test_get_tag_not_found(client):
  function test_items_linked_with_tag (line 41) | def test_items_linked_with_tag(client, created_tag_with_item_id):
  function test_unlink_tag_from_item (line 56) | def test_unlink_tag_from_item(client, created_item_id, created_tag_with_...
  function test_delete_tag_without_items (line 67) | def test_delete_tag_without_items(client, created_tag_id):
  function test_delete_tag_still_has_items (line 80) | def test_delete_tag_still_has_items(client, created_tag_with_item_id):
  function test_delete_tag_not_found (line 90) | def test_delete_tag_not_found(client):
  function test_get_all_tags_in_store (line 99) | def test_get_all_tags_in_store(client, created_store_id, created_tag_id):
  function test_get_all_tags_in_store_not_found (line 115) | def test_get_all_tags_in_store_not_found(client):

FILE: docs/docs/08_flask_jwt_extended/07_login_users_rest_api/end/resources/__tests__/test_user.py
  function created_user_details (line 5) | def created_user_details(client):
  function created_user_jwt (line 17) | def created_user_jwt(client, created_user_details):
  function test_register_user (line 27) | def test_register_user(client):
  function test_register_user_already_exists (line 38) | def test_register_user_already_exists(client):
  function test_register_user_missing_data (line 54) | def test_register_user_missing_data(client):
  function test_login_user (line 65) | def test_login_user(client, created_user_details):
  function test_login_user_bad_password (line 76) | def test_login_user_bad_password(client, created_user_details):
  function test_login_user_bad_username (line 87) | def test_login_user_bad_username(client, created_user_details):
  function test_get_user_details (line 98) | def test_get_user_details(client, created_user_details):
  function test_get_user_details_missing (line 110) | def test_get_user_details_missing(client):

FILE: docs/docs/08_flask_jwt_extended/07_login_users_rest_api/end/resources/item.py
  class Item (line 13) | class Item(MethodView):
    method get (line 15) | def get(self, item_id):
    method delete (line 19) | def delete(self, item_id):
    method put (line 27) | def put(self, item_data, item_id):
  class ItemList (line 43) | class ItemList(MethodView):
    method get (line 45) | def get(self):
    method post (line 50) | def post(self, item_data):

FILE: docs/docs/08_flask_jwt_extended/07_login_users_rest_api/end/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 20) | def delete(self, store_id):
  class StoreList (line 28) | class StoreList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, store_data):

FILE: docs/docs/08_flask_jwt_extended/07_login_users_rest_api/end/resources/tag.py
  class TagsInStore (line 13) | class TagsInStore(MethodView):
    method get (line 15) | def get(self, store_id):
    method post (line 22) | def post(self, tag_data, store_id):
  class LinkTagsToItem (line 41) | class LinkTagsToItem(MethodView):
    method post (line 43) | def post(self, item_id, tag_id):
    method delete (line 58) | def delete(self, item_id, tag_id):
  class Tag (line 74) | class Tag(MethodView):
    method get (line 76) | def get(self, tag_id):
    method delete (line 90) | def delete(self, tag_id):

FILE: docs/docs/08_flask_jwt_extended/07_login_users_rest_api/end/resources/user.py
  class UserRegister (line 15) | class UserRegister(MethodView):
    method post (line 17) | def post(self, user_data):
  class UserLogin (line 32) | class UserLogin(MethodView):
    method post (line 34) | def post(self, user_data):
  class User (line 47) | class User(MethodView):
    method get (line 56) | def get(self, user_id):
    method delete (line 60) | def delete(self, user_id):

FILE: docs/docs/08_flask_jwt_extended/07_login_users_rest_api/end/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class PlainTagSchema (line 15) | class PlainTagSchema(Schema):
  class ItemSchema (line 20) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 26) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 31) | class StoreSchema(PlainStoreSchema):
  class TagSchema (line 36) | class TagSchema(PlainTagSchema):
  class TagAndItemSchema (line 42) | class TagAndItemSchema(Schema):
  class UserSchema (line 48) | class UserSchema(Schema):

FILE: docs/docs/08_flask_jwt_extended/07_login_users_rest_api/start/app.py
  function create_app (line 13) | def create_app(db_url=None):

FILE: docs/docs/08_flask_jwt_extended/07_login_users_rest_api/start/conftest.py
  function app (line 6) | def app():
  function client (line 18) | def client(app):

FILE: docs/docs/08_flask_jwt_extended/07_login_users_rest_api/start/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/07_login_users_rest_api/start/models/item_tags.py
  class ItemsTags (line 4) | class ItemsTags(db.Model):

FILE: docs/docs/08_flask_jwt_extended/07_login_users_rest_api/start/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/07_login_users_rest_api/start/models/tag.py
  class TagModel (line 4) | class TagModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/07_login_users_rest_api/start/models/user.py
  class UserModel (line 4) | class UserModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/07_login_users_rest_api/start/resources/__tests__/conftest.py
  function created_store_id (line 5) | def created_store_id(client):
  function created_item_id (line 15) | def created_item_id(client, created_store_id):
  function created_tag_id (line 25) | def created_tag_id(client, created_store_id):

FILE: docs/docs/08_flask_jwt_extended/07_login_users_rest_api/start/resources/__tests__/test_item.py
  function test_create_item_in_store (line 1) | def test_create_item_in_store(client, created_store_id):
  function test_create_item_with_store_id_not_found (line 13) | def test_create_item_with_store_id_not_found(client):
  function test_create_item_with_unknown_data (line 26) | def test_create_item_with_unknown_data(client):
  function test_delete_item (line 41) | def test_delete_item(client, created_item_id):
  function test_update_item (line 50) | def test_update_item(client, created_item_id):
  function test_get_all_items (line 61) | def test_get_all_items(client):
  function test_get_all_items_empty (line 82) | def test_get_all_items_empty(client):
  function test_get_item_details (line 91) | def test_get_item_details(client, created_item_id, created_store_id):
  function test_get_item_details_with_tag (line 102) | def test_get_item_details_with_tag(client, created_item_id, created_tag_...
  function test_get_item_detail_not_found (line 114) | def test_get_item_detail_not_found(client):

FILE: docs/docs/08_flask_jwt_extended/07_login_users_rest_api/start/resources/__tests__/test_store.py
  function test_get_store (line 1) | def test_get_store(client, created_store_id):
  function test_get_store_not_found (line 15) | def test_get_store_not_found(client):
  function test_get_store_with_item (line 24) | def test_get_store_with_item(client, created_store_id):
  function test_get_store_with_tag (line 44) | def test_get_store_with_tag(client, created_store_id):
  function test_create_store (line 58) | def test_create_store(client):
  function test_create_store_with_items (line 68) | def test_create_store_with_items(client, created_store_id):
  function test_delete_store (line 89) | def test_delete_store(client, created_store_id):
  function test_delete_store_doesnt_exist (line 98) | def test_delete_store_doesnt_exist(client):
  function test_get_store_list_empty (line 107) | def test_get_store_list_empty(client):
  function test_get_store_list_single (line 116) | def test_get_store_list_single(client):
  function test_get_store_list_multiple (line 130) | def test_get_store_list_multiple(client):
  function test_get_store_list_with_items (line 151) | def test_get_store_list_with_items(client):
  function test_get_store_list_with_tags (line 182) | def test_get_store_list_with_tags(client):
  function test_create_store_duplicate_name (line 206) | def test_create_store_duplicate_name(client):

FILE: docs/docs/08_flask_jwt_extended/07_login_users_rest_api/start/resources/__tests__/test_tag.py
  function created_tag_with_item_id (line 8) | def created_tag_with_item_id(client, created_item_id, created_tag_id):
  function test_get_tag (line 18) | def test_get_tag(client, created_tag_id):
  function test_get_tag_not_found (line 32) | def test_get_tag_not_found(client):
  function test_items_linked_with_tag (line 41) | def test_items_linked_with_tag(client, created_tag_with_item_id):
  function test_unlink_tag_from_item (line 56) | def test_unlink_tag_from_item(client, created_item_id, created_tag_with_...
  function test_delete_tag_without_items (line 67) | def test_delete_tag_without_items(client, created_tag_id):
  function test_delete_tag_still_has_items (line 80) | def test_delete_tag_still_has_items(client, created_tag_with_item_id):
  function test_delete_tag_not_found (line 90) | def test_delete_tag_not_found(client):
  function test_get_all_tags_in_store (line 99) | def test_get_all_tags_in_store(client, created_store_id, created_tag_id):
  function test_get_all_tags_in_store_not_found (line 115) | def test_get_all_tags_in_store_not_found(client):

FILE: docs/docs/08_flask_jwt_extended/07_login_users_rest_api/start/resources/__tests__/test_user.py
  function created_user_details (line 5) | def created_user_details(client):
  function test_register_user (line 16) | def test_register_user(client):
  function test_register_user_already_exists (line 27) | def test_register_user_already_exists(client):
  function test_register_user_missing_data (line 43) | def test_register_user_missing_data(client):
  function test_get_user_details (line 54) | def test_get_user_details(client, created_user_details):
  function test_get_user_details_missing (line 66) | def test_get_user_details_missing(client):

FILE: docs/docs/08_flask_jwt_extended/07_login_users_rest_api/start/resources/item.py
  class Item (line 13) | class Item(MethodView):
    method get (line 15) | def get(self, item_id):
    method delete (line 19) | def delete(self, item_id):
    method put (line 27) | def put(self, item_data, item_id):
  class ItemList (line 43) | class ItemList(MethodView):
    method get (line 45) | def get(self):
    method post (line 50) | def post(self, item_data):

FILE: docs/docs/08_flask_jwt_extended/07_login_users_rest_api/start/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 20) | def delete(self, store_id):
  class StoreList (line 28) | class StoreList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, store_data):

FILE: docs/docs/08_flask_jwt_extended/07_login_users_rest_api/start/resources/tag.py
  class TagsInStore (line 13) | class TagsInStore(MethodView):
    method get (line 15) | def get(self, store_id):
    method post (line 22) | def post(self, tag_data, store_id):
  class LinkTagsToItem (line 41) | class LinkTagsToItem(MethodView):
    method post (line 43) | def post(self, item_id, tag_id):
    method delete (line 58) | def delete(self, item_id, tag_id):
  class Tag (line 74) | class Tag(MethodView):
    method get (line 76) | def get(self, tag_id):
    method delete (line 90) | def delete(self, tag_id):

FILE: docs/docs/08_flask_jwt_extended/07_login_users_rest_api/start/resources/user.py
  class UserRegister (line 14) | class UserRegister(MethodView):
    method post (line 16) | def post(self, user_data):
  class User (line 31) | class User(MethodView):
    method get (line 40) | def get(self, user_id):
    method delete (line 44) | def delete(self, user_id):

FILE: docs/docs/08_flask_jwt_extended/07_login_users_rest_api/start/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class PlainTagSchema (line 15) | class PlainTagSchema(Schema):
  class ItemSchema (line 20) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 26) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 31) | class StoreSchema(PlainStoreSchema):
  class TagSchema (line 36) | class TagSchema(PlainTagSchema):
  class TagAndItemSchema (line 42) | class TagAndItemSchema(Schema):
  class UserSchema (line 48) | class UserSchema(Schema):

FILE: docs/docs/08_flask_jwt_extended/08_protect_resources_with_jwt_required/end/app.py
  function create_app (line 13) | def create_app(db_url=None):

FILE: docs/docs/08_flask_jwt_extended/08_protect_resources_with_jwt_required/end/conftest.py
  function app (line 7) | def app():
  function client (line 19) | def client(app):
  function jwt (line 24) | def jwt(app):

FILE: docs/docs/08_flask_jwt_extended/08_protect_resources_with_jwt_required/end/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/08_protect_resources_with_jwt_required/end/models/item_tags.py
  class ItemsTags (line 4) | class ItemsTags(db.Model):

FILE: docs/docs/08_flask_jwt_extended/08_protect_resources_with_jwt_required/end/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/08_protect_resources_with_jwt_required/end/models/tag.py
  class TagModel (line 4) | class TagModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/08_protect_resources_with_jwt_required/end/models/user.py
  class UserModel (line 4) | class UserModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/08_protect_resources_with_jwt_required/end/resources/__tests__/conftest.py
  function created_store_id (line 5) | def created_store_id(client):
  function created_item_id (line 15) | def created_item_id(client, jwt, created_store_id):
  function created_tag_id (line 26) | def created_tag_id(client, created_store_id):

FILE: docs/docs/08_flask_jwt_extended/08_protect_resources_with_jwt_required/end/resources/__tests__/test_item.py
  function test_create_item_in_store (line 1) | def test_create_item_in_store(client, jwt, created_store_id):
  function test_create_item_with_store_id_not_found (line 14) | def test_create_item_with_store_id_not_found(client, jwt):
  function test_create_item_with_unknown_data (line 28) | def test_create_item_with_unknown_data(client, jwt):
  function test_delete_item (line 44) | def test_delete_item(client, jwt, created_item_id):
  function test_update_item (line 54) | def test_update_item(client, jwt, created_item_id):
  function test_get_all_items (line 66) | def test_get_all_items(client, jwt):
  function test_get_all_items_empty (line 90) | def test_get_all_items_empty(client, jwt):
  function test_get_item_details (line 100) | def test_get_item_details(client, jwt, created_item_id, created_store_id):
  function test_get_item_details_with_tag (line 112) | def test_get_item_details_with_tag(client, jwt, created_item_id, created...
  function test_get_item_detail_not_found (line 125) | def test_get_item_detail_not_found(client, jwt):

FILE: docs/docs/08_flask_jwt_extended/08_protect_resources_with_jwt_required/end/resources/__tests__/test_store.py
  function test_get_store (line 1) | def test_get_store(client, created_store_id):
  function test_get_store_not_found (line 15) | def test_get_store_not_found(client):
  function test_get_store_with_item (line 24) | def test_get_store_with_item(client, jwt, created_store_id):
  function test_get_store_with_tag (line 45) | def test_get_store_with_tag(client, created_store_id):
  function test_create_store (line 59) | def test_create_store(client):
  function test_create_store_with_items (line 69) | def test_create_store_with_items(client, created_store_id, jwt):
  function test_delete_store (line 91) | def test_delete_store(client, created_store_id):
  function test_delete_store_doesnt_exist (line 100) | def test_delete_store_doesnt_exist(client):
  function test_get_store_list_empty (line 109) | def test_get_store_list_empty(client):
  function test_get_store_list_single (line 118) | def test_get_store_list_single(client):
  function test_get_store_list_multiple (line 132) | def test_get_store_list_multiple(client):
  function test_get_store_list_with_items (line 153) | def test_get_store_list_with_items(client, jwt):
  function test_get_store_list_with_tags (line 185) | def test_get_store_list_with_tags(client):
  function test_create_store_duplicate_name (line 209) | def test_create_store_duplicate_name(client):

FILE: docs/docs/08_flask_jwt_extended/08_protect_resources_with_jwt_required/end/resources/__tests__/test_tag.py
  function created_tag_with_item_id (line 8) | def created_tag_with_item_id(client, created_item_id, created_tag_id):
  function test_get_tag (line 18) | def test_get_tag(client, created_tag_id):
  function test_get_tag_not_found (line 32) | def test_get_tag_not_found(client):
  function test_items_linked_with_tag (line 41) | def test_items_linked_with_tag(client, created_tag_with_item_id):
  function test_unlink_tag_from_item (line 56) | def test_unlink_tag_from_item(client, created_item_id, created_tag_with_...
  function test_delete_tag_without_items (line 67) | def test_delete_tag_without_items(client, created_tag_id):
  function test_delete_tag_still_has_items (line 80) | def test_delete_tag_still_has_items(client, created_tag_with_item_id):
  function test_delete_tag_not_found (line 90) | def test_delete_tag_not_found(client):
  function test_get_all_tags_in_store (line 99) | def test_get_all_tags_in_store(client, created_store_id, created_tag_id):
  function test_get_all_tags_in_store_not_found (line 115) | def test_get_all_tags_in_store_not_found(client):

FILE: docs/docs/08_flask_jwt_extended/08_protect_resources_with_jwt_required/end/resources/__tests__/test_user.py
  function created_user_details (line 5) | def created_user_details(client):
  function created_user_jwt (line 17) | def created_user_jwt(client, created_user_details):
  function test_register_user (line 27) | def test_register_user(client):
  function test_register_user_already_exists (line 38) | def test_register_user_already_exists(client):
  function test_register_user_missing_data (line 54) | def test_register_user_missing_data(client):
  function test_login_user (line 65) | def test_login_user(client, created_user_details):
  function test_login_user_bad_password (line 76) | def test_login_user_bad_password(client, created_user_details):
  function test_login_user_bad_username (line 87) | def test_login_user_bad_username(client, created_user_details):
  function test_get_user_details (line 98) | def test_get_user_details(client, created_user_details):
  function test_get_user_details_missing (line 110) | def test_get_user_details_missing(client):

FILE: docs/docs/08_flask_jwt_extended/08_protect_resources_with_jwt_required/end/resources/item.py
  class Item (line 14) | class Item(MethodView):
    method get (line 17) | def get(self, item_id):
    method delete (line 22) | def delete(self, item_id):
    method put (line 30) | def put(self, item_data, item_id):
  class ItemList (line 46) | class ItemList(MethodView):
    method get (line 49) | def get(self):
    method post (line 55) | def post(self, item_data):

FILE: docs/docs/08_flask_jwt_extended/08_protect_resources_with_jwt_required/end/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 20) | def delete(self, store_id):
  class StoreList (line 28) | class StoreList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, store_data):

FILE: docs/docs/08_flask_jwt_extended/08_protect_resources_with_jwt_required/end/resources/tag.py
  class TagsInStore (line 13) | class TagsInStore(MethodView):
    method get (line 15) | def get(self, store_id):
    method post (line 22) | def post(self, tag_data, store_id):
  class LinkTagsToItem (line 40) | class LinkTagsToItem(MethodView):
    method post (line 42) | def post(self, item_id, tag_id):
    method delete (line 57) | def delete(self, item_id, tag_id):
  class Tag (line 73) | class Tag(MethodView):
    method get (line 75) | def get(self, tag_id):
    method delete (line 89) | def delete(self, tag_id):

FILE: docs/docs/08_flask_jwt_extended/08_protect_resources_with_jwt_required/end/resources/user.py
  class UserRegister (line 15) | class UserRegister(MethodView):
    method post (line 17) | def post(self, user_data):
  class UserLogin (line 32) | class UserLogin(MethodView):
    method post (line 34) | def post(self, user_data):
  class User (line 47) | class User(MethodView):
    method get (line 56) | def get(self, user_id):
    method delete (line 60) | def delete(self, user_id):

FILE: docs/docs/08_flask_jwt_extended/08_protect_resources_with_jwt_required/end/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class PlainTagSchema (line 15) | class PlainTagSchema(Schema):
  class ItemSchema (line 20) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 26) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 31) | class StoreSchema(PlainStoreSchema):
  class TagSchema (line 36) | class TagSchema(PlainTagSchema):
  class TagAndItemSchema (line 42) | class TagAndItemSchema(Schema):
  class UserSchema (line 48) | class UserSchema(Schema):

FILE: docs/docs/08_flask_jwt_extended/08_protect_resources_with_jwt_required/start/app.py
  function create_app (line 13) | def create_app(db_url=None):

FILE: docs/docs/08_flask_jwt_extended/08_protect_resources_with_jwt_required/start/conftest.py
  function app (line 6) | def app():
  function client (line 18) | def client(app):

FILE: docs/docs/08_flask_jwt_extended/08_protect_resources_with_jwt_required/start/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/08_protect_resources_with_jwt_required/start/models/item_tags.py
  class ItemsTags (line 4) | class ItemsTags(db.Model):

FILE: docs/docs/08_flask_jwt_extended/08_protect_resources_with_jwt_required/start/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/08_protect_resources_with_jwt_required/start/models/tag.py
  class TagModel (line 4) | class TagModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/08_protect_resources_with_jwt_required/start/models/user.py
  class UserModel (line 4) | class UserModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/08_protect_resources_with_jwt_required/start/resources/__tests__/conftest.py
  function created_store_id (line 5) | def created_store_id(client):
  function created_item_id (line 15) | def created_item_id(client, created_store_id):
  function created_tag_id (line 25) | def created_tag_id(client, created_store_id):

FILE: docs/docs/08_flask_jwt_extended/08_protect_resources_with_jwt_required/start/resources/__tests__/test_item.py
  function test_create_item_in_store (line 1) | def test_create_item_in_store(client, created_store_id):
  function test_create_item_with_store_id_not_found (line 13) | def test_create_item_with_store_id_not_found(client):
  function test_create_item_with_unknown_data (line 26) | def test_create_item_with_unknown_data(client):
  function test_delete_item (line 41) | def test_delete_item(client, created_item_id):
  function test_update_item (line 50) | def test_update_item(client, created_item_id):
  function test_get_all_items (line 61) | def test_get_all_items(client):
  function test_get_all_items_empty (line 82) | def test_get_all_items_empty(client):
  function test_get_item_details (line 91) | def test_get_item_details(client, created_item_id, created_store_id):
  function test_get_item_details_with_tag (line 102) | def test_get_item_details_with_tag(client, created_item_id, created_tag_...
  function test_get_item_detail_not_found (line 114) | def test_get_item_detail_not_found(client):

FILE: docs/docs/08_flask_jwt_extended/08_protect_resources_with_jwt_required/start/resources/__tests__/test_store.py
  function test_get_store (line 1) | def test_get_store(client, created_store_id):
  function test_get_store_not_found (line 15) | def test_get_store_not_found(client):
  function test_get_store_with_item (line 24) | def test_get_store_with_item(client, created_store_id):
  function test_get_store_with_tag (line 44) | def test_get_store_with_tag(client, created_store_id):
  function test_create_store (line 58) | def test_create_store(client):
  function test_create_store_with_items (line 68) | def test_create_store_with_items(client, created_store_id):
  function test_delete_store (line 89) | def test_delete_store(client, created_store_id):
  function test_delete_store_doesnt_exist (line 98) | def test_delete_store_doesnt_exist(client):
  function test_get_store_list_empty (line 107) | def test_get_store_list_empty(client):
  function test_get_store_list_single (line 116) | def test_get_store_list_single(client):
  function test_get_store_list_multiple (line 130) | def test_get_store_list_multiple(client):
  function test_get_store_list_with_items (line 151) | def test_get_store_list_with_items(client):
  function test_get_store_list_with_tags (line 182) | def test_get_store_list_with_tags(client):
  function test_create_store_duplicate_name (line 206) | def test_create_store_duplicate_name(client):

FILE: docs/docs/08_flask_jwt_extended/08_protect_resources_with_jwt_required/start/resources/__tests__/test_tag.py
  function created_tag_with_item_id (line 8) | def created_tag_with_item_id(client, created_item_id, created_tag_id):
  function test_get_tag (line 18) | def test_get_tag(client, created_tag_id):
  function test_get_tag_not_found (line 32) | def test_get_tag_not_found(client):
  function test_items_linked_with_tag (line 41) | def test_items_linked_with_tag(client, created_tag_with_item_id):
  function test_unlink_tag_from_item (line 56) | def test_unlink_tag_from_item(client, created_item_id, created_tag_with_...
  function test_delete_tag_without_items (line 67) | def test_delete_tag_without_items(client, created_tag_id):
  function test_delete_tag_still_has_items (line 80) | def test_delete_tag_still_has_items(client, created_tag_with_item_id):
  function test_delete_tag_not_found (line 90) | def test_delete_tag_not_found(client):
  function test_get_all_tags_in_store (line 99) | def test_get_all_tags_in_store(client, created_store_id, created_tag_id):
  function test_get_all_tags_in_store_not_found (line 115) | def test_get_all_tags_in_store_not_found(client):

FILE: docs/docs/08_flask_jwt_extended/08_protect_resources_with_jwt_required/start/resources/__tests__/test_user.py
  function created_user_details (line 5) | def created_user_details(client):
  function created_user_jwt (line 17) | def created_user_jwt(client, created_user_details):
  function test_register_user (line 27) | def test_register_user(client):
  function test_register_user_already_exists (line 38) | def test_register_user_already_exists(client):
  function test_register_user_missing_data (line 54) | def test_register_user_missing_data(client):
  function test_login_user (line 65) | def test_login_user(client, created_user_details):
  function test_login_user_bad_password (line 76) | def test_login_user_bad_password(client, created_user_details):
  function test_login_user_bad_username (line 87) | def test_login_user_bad_username(client, created_user_details):
  function test_get_user_details (line 98) | def test_get_user_details(client, created_user_details):
  function test_get_user_details_missing (line 110) | def test_get_user_details_missing(client):

FILE: docs/docs/08_flask_jwt_extended/08_protect_resources_with_jwt_required/start/resources/item.py
  class Item (line 13) | class Item(MethodView):
    method get (line 15) | def get(self, item_id):
    method delete (line 19) | def delete(self, item_id):
    method put (line 27) | def put(self, item_data, item_id):
  class ItemList (line 43) | class ItemList(MethodView):
    method get (line 45) | def get(self):
    method post (line 50) | def post(self, item_data):

FILE: docs/docs/08_flask_jwt_extended/08_protect_resources_with_jwt_required/start/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 20) | def delete(self, store_id):
  class StoreList (line 28) | class StoreList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, store_data):

FILE: docs/docs/08_flask_jwt_extended/08_protect_resources_with_jwt_required/start/resources/tag.py
  class TagsInStore (line 13) | class TagsInStore(MethodView):
    method get (line 15) | def get(self, store_id):
    method post (line 22) | def post(self, tag_data, store_id):
  class LinkTagsToItem (line 41) | class LinkTagsToItem(MethodView):
    method post (line 43) | def post(self, item_id, tag_id):
    method delete (line 58) | def delete(self, item_id, tag_id):
  class Tag (line 74) | class Tag(MethodView):
    method get (line 76) | def get(self, tag_id):
    method delete (line 90) | def delete(self, tag_id):

FILE: docs/docs/08_flask_jwt_extended/08_protect_resources_with_jwt_required/start/resources/user.py
  class UserRegister (line 15) | class UserRegister(MethodView):
    method post (line 17) | def post(self, user_data):
  class UserLogin (line 32) | class UserLogin(MethodView):
    method post (line 34) | def post(self, user_data):
  class User (line 47) | class User(MethodView):
    method get (line 56) | def get(self, user_id):
    method delete (line 60) | def delete(self, user_id):

FILE: docs/docs/08_flask_jwt_extended/08_protect_resources_with_jwt_required/start/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class PlainTagSchema (line 15) | class PlainTagSchema(Schema):
  class ItemSchema (line 20) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 26) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 31) | class StoreSchema(PlainStoreSchema):
  class TagSchema (line 36) | class TagSchema(PlainTagSchema):
  class TagAndItemSchema (line 42) | class TagAndItemSchema(Schema):
  class UserSchema (line 48) | class UserSchema(Schema):

FILE: docs/docs/08_flask_jwt_extended/09_jwt_claims_and_authorization/end/app.py
  function create_app (line 13) | def create_app(db_url=None):

FILE: docs/docs/08_flask_jwt_extended/09_jwt_claims_and_authorization/end/conftest.py
  function app (line 7) | def app():
  function client (line 19) | def client(app):
  function jwt (line 24) | def jwt(app):
  function admin_jwt (line 31) | def admin_jwt(app):

FILE: docs/docs/08_flask_jwt_extended/09_jwt_claims_and_authorization/end/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/09_jwt_claims_and_authorization/end/models/item_tags.py
  class ItemsTags (line 4) | class ItemsTags(db.Model):

FILE: docs/docs/08_flask_jwt_extended/09_jwt_claims_and_authorization/end/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/09_jwt_claims_and_authorization/end/models/tag.py
  class TagModel (line 4) | class TagModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/09_jwt_claims_and_authorization/end/models/user.py
  class UserModel (line 4) | class UserModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/09_jwt_claims_and_authorization/end/resources/__tests__/conftest.py
  function created_store_id (line 5) | def created_store_id(client):
  function created_item_id (line 15) | def created_item_id(client, jwt, created_store_id):
  function created_tag_id (line 26) | def created_tag_id(client, created_store_id):

FILE: docs/docs/08_flask_jwt_extended/09_jwt_claims_and_authorization/end/resources/__tests__/test_item.py
  function test_create_item_in_store (line 1) | def test_create_item_in_store(client, jwt, created_store_id):
  function test_create_item_with_store_id_not_found (line 14) | def test_create_item_with_store_id_not_found(client, jwt):
  function test_create_item_with_unknown_data (line 28) | def test_create_item_with_unknown_data(client, jwt):
  function test_delete_item (line 44) | def test_delete_item(client, admin_jwt, created_item_id):
  function test_delete_item_without_admin (line 54) | def test_delete_item_without_admin(client, jwt, created_item_id):
  function test_update_item (line 64) | def test_update_item(client, jwt, created_item_id):
  function test_get_all_items (line 76) | def test_get_all_items(client, jwt):
  function test_get_all_items_empty (line 100) | def test_get_all_items_empty(client, jwt):
  function test_get_item_details (line 110) | def test_get_item_details(client, jwt, created_item_id, created_store_id):
  function test_get_item_details_with_tag (line 122) | def test_get_item_details_with_tag(client, jwt, created_item_id, created...
  function test_get_item_detail_not_found (line 135) | def test_get_item_detail_not_found(client, jwt):

FILE: docs/docs/08_flask_jwt_extended/09_jwt_claims_and_authorization/end/resources/__tests__/test_store.py
  function test_get_store (line 1) | def test_get_store(client, created_store_id):
  function test_get_store_not_found (line 15) | def test_get_store_not_found(client):
  function test_get_store_with_item (line 24) | def test_get_store_with_item(client, jwt, created_store_id):
  function test_get_store_with_tag (line 45) | def test_get_store_with_tag(client, created_store_id):
  function test_create_store (line 59) | def test_create_store(client):
  function test_create_store_with_items (line 69) | def test_create_store_with_items(client, created_store_id, jwt):
  function test_delete_store (line 91) | def test_delete_store(client, created_store_id):
  function test_delete_store_doesnt_exist (line 100) | def test_delete_store_doesnt_exist(client):
  function test_get_store_list_empty (line 109) | def test_get_store_list_empty(client):
  function test_get_store_list_single (line 118) | def test_get_store_list_single(client):
  function test_get_store_list_multiple (line 132) | def test_get_store_list_multiple(client):
  function test_get_store_list_with_items (line 153) | def test_get_store_list_with_items(client, jwt):
  function test_get_store_list_with_tags (line 185) | def test_get_store_list_with_tags(client):
  function test_create_store_duplicate_name (line 209) | def test_create_store_duplicate_name(client):

FILE: docs/docs/08_flask_jwt_extended/09_jwt_claims_and_authorization/end/resources/__tests__/test_tag.py
  function created_tag_with_item_id (line 8) | def created_tag_with_item_id(client, created_item_id, created_tag_id):
  function test_get_tag (line 18) | def test_get_tag(client, created_tag_id):
  function test_get_tag_not_found (line 32) | def test_get_tag_not_found(client):
  function test_items_linked_with_tag (line 41) | def test_items_linked_with_tag(client, created_tag_with_item_id):
  function test_unlink_tag_from_item (line 56) | def test_unlink_tag_from_item(client, created_item_id, created_tag_with_...
  function test_delete_tag_without_items (line 67) | def test_delete_tag_without_items(client, created_tag_id):
  function test_delete_tag_still_has_items (line 80) | def test_delete_tag_still_has_items(client, created_tag_with_item_id):
  function test_delete_tag_not_found (line 90) | def test_delete_tag_not_found(client):
  function test_get_all_tags_in_store (line 99) | def test_get_all_tags_in_store(client, created_store_id, created_tag_id):
  function test_get_all_tags_in_store_not_found (line 115) | def test_get_all_tags_in_store_not_found(client):

FILE: docs/docs/08_flask_jwt_extended/09_jwt_claims_and_authorization/end/resources/__tests__/test_user.py
  function created_user_details (line 5) | def created_user_details(client):
  function created_user_jwt (line 17) | def created_user_jwt(client, created_user_details):
  function test_register_user (line 27) | def test_register_user(client):
  function test_register_user_already_exists (line 38) | def test_register_user_already_exists(client):
  function test_register_user_missing_data (line 54) | def test_register_user_missing_data(client):
  function test_login_user (line 65) | def test_login_user(client, created_user_details):
  function test_login_user_bad_password (line 76) | def test_login_user_bad_password(client, created_user_details):
  function test_login_user_bad_username (line 87) | def test_login_user_bad_username(client, created_user_details):
  function test_get_user_details (line 98) | def test_get_user_details(client, created_user_details):
  function test_get_user_details_missing (line 110) | def test_get_user_details_missing(client):

FILE: docs/docs/08_flask_jwt_extended/09_jwt_claims_and_authorization/end/resources/item.py
  class Item (line 14) | class Item(MethodView):
    method get (line 17) | def get(self, item_id):
    method delete (line 22) | def delete(self, item_id):
    method put (line 34) | def put(self, item_data, item_id):
  class ItemList (line 50) | class ItemList(MethodView):
    method get (line 53) | def get(self):
    method post (line 59) | def post(self, item_data):

FILE: docs/docs/08_flask_jwt_extended/09_jwt_claims_and_authorization/end/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 20) | def delete(self, store_id):
  class StoreList (line 28) | class StoreList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, store_data):

FILE: docs/docs/08_flask_jwt_extended/09_jwt_claims_and_authorization/end/resources/tag.py
  class TagsInStore (line 13) | class TagsInStore(MethodView):
    method get (line 15) | def get(self, store_id):
    method post (line 22) | def post(self, tag_data, store_id):
  class LinkTagsToItem (line 41) | class LinkTagsToItem(MethodView):
    method post (line 43) | def post(self, item_id, tag_id):
    method delete (line 58) | def delete(self, item_id, tag_id):
  class Tag (line 74) | class Tag(MethodView):
    method get (line 76) | def get(self, tag_id):
    method delete (line 90) | def delete(self, tag_id):

FILE: docs/docs/08_flask_jwt_extended/09_jwt_claims_and_authorization/end/resources/user.py
  class UserRegister (line 15) | class UserRegister(MethodView):
    method post (line 17) | def post(self, user_data):
  class UserLogin (line 32) | class UserLogin(MethodView):
    method post (line 34) | def post(self, user_data):
  class User (line 47) | class User(MethodView):
    method get (line 56) | def get(self, user_id):
    method delete (line 60) | def delete(self, user_id):

FILE: docs/docs/08_flask_jwt_extended/09_jwt_claims_and_authorization/end/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class PlainTagSchema (line 15) | class PlainTagSchema(Schema):
  class ItemSchema (line 20) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 26) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 31) | class StoreSchema(PlainStoreSchema):
  class TagSchema (line 36) | class TagSchema(PlainTagSchema):
  class TagAndItemSchema (line 42) | class TagAndItemSchema(Schema):
  class UserSchema (line 48) | class UserSchema(Schema):

FILE: docs/docs/08_flask_jwt_extended/09_jwt_claims_and_authorization/start/app.py
  function create_app (line 13) | def create_app(db_url=None):

FILE: docs/docs/08_flask_jwt_extended/09_jwt_claims_and_authorization/start/conftest.py
  function app (line 7) | def app():
  function client (line 19) | def client(app):
  function jwt (line 24) | def jwt(app):

FILE: docs/docs/08_flask_jwt_extended/09_jwt_claims_and_authorization/start/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/09_jwt_claims_and_authorization/start/models/item_tags.py
  class ItemsTags (line 4) | class ItemsTags(db.Model):

FILE: docs/docs/08_flask_jwt_extended/09_jwt_claims_and_authorization/start/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/09_jwt_claims_and_authorization/start/models/tag.py
  class TagModel (line 4) | class TagModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/09_jwt_claims_and_authorization/start/models/user.py
  class UserModel (line 4) | class UserModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/09_jwt_claims_and_authorization/start/resources/__tests__/conftest.py
  function created_store_id (line 5) | def created_store_id(client):
  function created_item_id (line 15) | def created_item_id(client, jwt, created_store_id):
  function created_tag_id (line 26) | def created_tag_id(client, created_store_id):

FILE: docs/docs/08_flask_jwt_extended/09_jwt_claims_and_authorization/start/resources/__tests__/test_item.py
  function test_create_item_in_store (line 1) | def test_create_item_in_store(client, jwt, created_store_id):
  function test_create_item_with_store_id_not_found (line 14) | def test_create_item_with_store_id_not_found(client, jwt):
  function test_create_item_with_unknown_data (line 28) | def test_create_item_with_unknown_data(client, jwt):
  function test_delete_item (line 44) | def test_delete_item(client, jwt, created_item_id):
  function test_update_item (line 54) | def test_update_item(client, jwt, created_item_id):
  function test_get_all_items (line 66) | def test_get_all_items(client, jwt):
  function test_get_all_items_empty (line 90) | def test_get_all_items_empty(client, jwt):
  function test_get_item_details (line 100) | def test_get_item_details(client, jwt, created_item_id, created_store_id):
  function test_get_item_details_with_tag (line 112) | def test_get_item_details_with_tag(client, jwt, created_item_id, created...
  function test_get_item_detail_not_found (line 125) | def test_get_item_detail_not_found(client, jwt):

FILE: docs/docs/08_flask_jwt_extended/09_jwt_claims_and_authorization/start/resources/__tests__/test_store.py
  function test_get_store (line 1) | def test_get_store(client, created_store_id):
  function test_get_store_not_found (line 15) | def test_get_store_not_found(client):
  function test_get_store_with_item (line 24) | def test_get_store_with_item(client, jwt, created_store_id):
  function test_get_store_with_tag (line 45) | def test_get_store_with_tag(client, created_store_id):
  function test_create_store (line 59) | def test_create_store(client):
  function test_create_store_with_items (line 69) | def test_create_store_with_items(client, created_store_id, jwt):
  function test_delete_store (line 91) | def test_delete_store(client, created_store_id):
  function test_delete_store_doesnt_exist (line 100) | def test_delete_store_doesnt_exist(client):
  function test_get_store_list_empty (line 109) | def test_get_store_list_empty(client):
  function test_get_store_list_single (line 118) | def test_get_store_list_single(client):
  function test_get_store_list_multiple (line 132) | def test_get_store_list_multiple(client):
  function test_get_store_list_with_items (line 153) | def test_get_store_list_with_items(client, jwt):
  function test_get_store_list_with_tags (line 185) | def test_get_store_list_with_tags(client):
  function test_create_store_duplicate_name (line 209) | def test_create_store_duplicate_name(client):

FILE: docs/docs/08_flask_jwt_extended/09_jwt_claims_and_authorization/start/resources/__tests__/test_tag.py
  function created_tag_with_item_id (line 8) | def created_tag_with_item_id(client, created_item_id, created_tag_id):
  function test_get_tag (line 18) | def test_get_tag(client, created_tag_id):
  function test_get_tag_not_found (line 32) | def test_get_tag_not_found(client):
  function test_items_linked_with_tag (line 41) | def test_items_linked_with_tag(client, created_tag_with_item_id):
  function test_unlink_tag_from_item (line 56) | def test_unlink_tag_from_item(client, created_item_id, created_tag_with_...
  function test_delete_tag_without_items (line 67) | def test_delete_tag_without_items(client, created_tag_id):
  function test_delete_tag_still_has_items (line 80) | def test_delete_tag_still_has_items(client, created_tag_with_item_id):
  function test_delete_tag_not_found (line 90) | def test_delete_tag_not_found(client):
  function test_get_all_tags_in_store (line 99) | def test_get_all_tags_in_store(client, created_store_id, created_tag_id):
  function test_get_all_tags_in_store_not_found (line 115) | def test_get_all_tags_in_store_not_found(client):

FILE: docs/docs/08_flask_jwt_extended/09_jwt_claims_and_authorization/start/resources/__tests__/test_user.py
  function created_user_details (line 5) | def created_user_details(client):
  function created_user_jwt (line 17) | def created_user_jwt(client, created_user_details):
  function test_register_user (line 27) | def test_register_user(client):
  function test_register_user_already_exists (line 38) | def test_register_user_already_exists(client):
  function test_register_user_missing_data (line 54) | def test_register_user_missing_data(client):
  function test_login_user (line 65) | def test_login_user(client, created_user_details):
  function test_login_user_bad_password (line 76) | def test_login_user_bad_password(client, created_user_details):
  function test_login_user_bad_username (line 87) | def test_login_user_bad_username(client, created_user_details):
  function test_get_user_details (line 98) | def test_get_user_details(client, created_user_details):
  function test_get_user_details_missing (line 110) | def test_get_user_details_missing(client):

FILE: docs/docs/08_flask_jwt_extended/09_jwt_claims_and_authorization/start/resources/item.py
  class Item (line 14) | class Item(MethodView):
    method get (line 17) | def get(self, item_id):
    method delete (line 22) | def delete(self, item_id):
    method put (line 30) | def put(self, item_data, item_id):
  class ItemList (line 46) | class ItemList(MethodView):
    method get (line 49) | def get(self):
    method post (line 55) | def post(self, item_data):

FILE: docs/docs/08_flask_jwt_extended/09_jwt_claims_and_authorization/start/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 20) | def delete(self, store_id):
  class StoreList (line 28) | class StoreList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, store_data):

FILE: docs/docs/08_flask_jwt_extended/09_jwt_claims_and_authorization/start/resources/tag.py
  class TagsInStore (line 13) | class TagsInStore(MethodView):
    method get (line 15) | def get(self, store_id):
    method post (line 22) | def post(self, tag_data, store_id):
  class LinkTagsToItem (line 41) | class LinkTagsToItem(MethodView):
    method post (line 43) | def post(self, item_id, tag_id):
    method delete (line 58) | def delete(self, item_id, tag_id):
  class Tag (line 74) | class Tag(MethodView):
    method get (line 76) | def get(self, tag_id):
    method delete (line 90) | def delete(self, tag_id):

FILE: docs/docs/08_flask_jwt_extended/09_jwt_claims_and_authorization/start/resources/user.py
  class UserRegister (line 15) | class UserRegister(MethodView):
    method post (line 17) | def post(self, user_data):
  class UserLogin (line 32) | class UserLogin(MethodView):
    method post (line 34) | def post(self, user_data):
  class User (line 47) | class User(MethodView):
    method get (line 56) | def get(self, user_id):
    method delete (line 60) | def delete(self, user_id):

FILE: docs/docs/08_flask_jwt_extended/09_jwt_claims_and_authorization/start/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class PlainTagSchema (line 15) | class PlainTagSchema(Schema):
  class ItemSchema (line 20) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 26) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 31) | class StoreSchema(PlainStoreSchema):
  class TagSchema (line 36) | class TagSchema(PlainTagSchema):
  class TagAndItemSchema (line 42) | class TagAndItemSchema(Schema):
  class UserSchema (line 48) | class UserSchema(Schema):

FILE: docs/docs/08_flask_jwt_extended/10_logout_users_rest_api/end/app.py
  function create_app (line 14) | def create_app(db_url=None):

FILE: docs/docs/08_flask_jwt_extended/10_logout_users_rest_api/end/conftest.py
  function app (line 7) | def app():
  function client (line 19) | def client(app):
  function jwt (line 24) | def jwt(app):
  function admin_jwt (line 31) | def admin_jwt(app):

FILE: docs/docs/08_flask_jwt_extended/10_logout_users_rest_api/end/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/10_logout_users_rest_api/end/models/item_tags.py
  class ItemsTags (line 4) | class ItemsTags(db.Model):

FILE: docs/docs/08_flask_jwt_extended/10_logout_users_rest_api/end/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/10_logout_users_rest_api/end/models/tag.py
  class TagModel (line 4) | class TagModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/10_logout_users_rest_api/end/models/user.py
  class UserModel (line 4) | class UserModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/10_logout_users_rest_api/end/resources/__tests__/conftest.py
  function created_store_id (line 5) | def created_store_id(client):
  function created_item_id (line 15) | def created_item_id(client, jwt, created_store_id):
  function created_tag_id (line 26) | def created_tag_id(client, created_store_id):

FILE: docs/docs/08_flask_jwt_extended/10_logout_users_rest_api/end/resources/__tests__/test_item.py
  function test_create_item_in_store (line 1) | def test_create_item_in_store(client, jwt, created_store_id):
  function test_create_item_with_store_id_not_found (line 14) | def test_create_item_with_store_id_not_found(client, jwt):
  function test_create_item_with_unknown_data (line 28) | def test_create_item_with_unknown_data(client, jwt):
  function test_delete_item (line 44) | def test_delete_item(client, admin_jwt, created_item_id):
  function test_delete_item_without_admin (line 54) | def test_delete_item_without_admin(client, jwt, created_item_id):
  function test_update_item (line 64) | def test_update_item(client, jwt, created_item_id):
  function test_get_all_items (line 76) | def test_get_all_items(client, jwt):
  function test_get_all_items_empty (line 100) | def test_get_all_items_empty(client, jwt):
  function test_get_item_details (line 110) | def test_get_item_details(client, jwt, created_item_id, created_store_id):
  function test_get_item_details_with_tag (line 122) | def test_get_item_details_with_tag(client, jwt, created_item_id, created...
  function test_get_item_detail_not_found (line 135) | def test_get_item_detail_not_found(client, jwt):

FILE: docs/docs/08_flask_jwt_extended/10_logout_users_rest_api/end/resources/__tests__/test_store.py
  function test_get_store (line 1) | def test_get_store(client, created_store_id):
  function test_get_store_not_found (line 15) | def test_get_store_not_found(client):
  function test_get_store_with_item (line 24) | def test_get_store_with_item(client, jwt, created_store_id):
  function test_get_store_with_tag (line 45) | def test_get_store_with_tag(client, created_store_id):
  function test_create_store (line 59) | def test_create_store(client):
  function test_create_store_with_items (line 69) | def test_create_store_with_items(client, created_store_id, jwt):
  function test_delete_store (line 91) | def test_delete_store(client, created_store_id):
  function test_delete_store_doesnt_exist (line 100) | def test_delete_store_doesnt_exist(client):
  function test_get_store_list_empty (line 109) | def test_get_store_list_empty(client):
  function test_get_store_list_single (line 118) | def test_get_store_list_single(client):
  function test_get_store_list_multiple (line 132) | def test_get_store_list_multiple(client):
  function test_get_store_list_with_items (line 153) | def test_get_store_list_with_items(client, jwt):
  function test_get_store_list_with_tags (line 185) | def test_get_store_list_with_tags(client):
  function test_create_store_duplicate_name (line 209) | def test_create_store_duplicate_name(client):

FILE: docs/docs/08_flask_jwt_extended/10_logout_users_rest_api/end/resources/__tests__/test_tag.py
  function created_tag_with_item_id (line 8) | def created_tag_with_item_id(client, created_item_id, created_tag_id):
  function test_get_tag (line 18) | def test_get_tag(client, created_tag_id):
  function test_get_tag_not_found (line 32) | def test_get_tag_not_found(client):
  function test_items_linked_with_tag (line 41) | def test_items_linked_with_tag(client, created_tag_with_item_id):
  function test_unlink_tag_from_item (line 56) | def test_unlink_tag_from_item(client, created_item_id, created_tag_with_...
  function test_delete_tag_without_items (line 67) | def test_delete_tag_without_items(client, created_tag_id):
  function test_delete_tag_still_has_items (line 80) | def test_delete_tag_still_has_items(client, created_tag_with_item_id):
  function test_delete_tag_not_found (line 90) | def test_delete_tag_not_found(client):
  function test_get_all_tags_in_store (line 99) | def test_get_all_tags_in_store(client, created_store_id, created_tag_id):
  function test_get_all_tags_in_store_not_found (line 115) | def test_get_all_tags_in_store_not_found(client):

FILE: docs/docs/08_flask_jwt_extended/10_logout_users_rest_api/end/resources/__tests__/test_user.py
  function created_user_details (line 5) | def created_user_details(client):
  function created_user_jwt (line 17) | def created_user_jwt(client, created_user_details):
  function test_register_user (line 27) | def test_register_user(client):
  function test_register_user_already_exists (line 38) | def test_register_user_already_exists(client):
  function test_register_user_missing_data (line 54) | def test_register_user_missing_data(client):
  function test_login_user (line 65) | def test_login_user(client, created_user_details):
  function test_login_user_bad_password (line 76) | def test_login_user_bad_password(client, created_user_details):
  function test_login_user_bad_username (line 87) | def test_login_user_bad_username(client, created_user_details):
  function test_logout_user (line 98) | def test_logout_user(client, created_user_jwt):
  function test_logout_user_twice (line 108) | def test_logout_user_twice(client, created_user_jwt):
  function test_logout_user_no_token (line 125) | def test_logout_user_no_token(client):
  function test_logout_user_invalid_token (line 134) | def test_logout_user_invalid_token(client):
  function test_get_user_details (line 147) | def test_get_user_details(client, created_user_details):
  function test_get_user_details_missing (line 159) | def test_get_user_details_missing(client):

FILE: docs/docs/08_flask_jwt_extended/10_logout_users_rest_api/end/resources/item.py
  class Item (line 14) | class Item(MethodView):
    method get (line 17) | def get(self, item_id):
    method delete (line 22) | def delete(self, item_id):
    method put (line 34) | def put(self, item_data, item_id):
  class ItemList (line 50) | class ItemList(MethodView):
    method get (line 53) | def get(self):
    method post (line 59) | def post(self, item_data):

FILE: docs/docs/08_flask_jwt_extended/10_logout_users_rest_api/end/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 20) | def delete(self, store_id):
  class StoreList (line 28) | class StoreList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, store_data):

FILE: docs/docs/08_flask_jwt_extended/10_logout_users_rest_api/end/resources/tag.py
  class TagsInStore (line 13) | class TagsInStore(MethodView):
    method get (line 15) | def get(self, store_id):
    method post (line 22) | def post(self, tag_data, store_id):
  class LinkTagsToItem (line 41) | class LinkTagsToItem(MethodView):
    method post (line 43) | def post(self, item_id, tag_id):
    method delete (line 58) | def delete(self, item_id, tag_id):
  class Tag (line 74) | class Tag(MethodView):
    method get (line 76) | def get(self, tag_id):
    method delete (line 90) | def delete(self, tag_id):

FILE: docs/docs/08_flask_jwt_extended/10_logout_users_rest_api/end/resources/user.py
  class UserRegister (line 20) | class UserRegister(MethodView):
    method post (line 22) | def post(self, user_data):
  class UserLogin (line 37) | class UserLogin(MethodView):
    method post (line 39) | def post(self, user_data):
  class UserLogout (line 52) | class UserLogout(MethodView):
    method post (line 54) | def post(self):
  class User (line 61) | class User(MethodView):
    method get (line 70) | def get(self, user_id):
    method delete (line 74) | def delete(self, user_id):

FILE: docs/docs/08_flask_jwt_extended/10_logout_users_rest_api/end/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class PlainTagSchema (line 15) | class PlainTagSchema(Schema):
  class ItemSchema (line 20) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 26) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 31) | class StoreSchema(PlainStoreSchema):
  class TagSchema (line 36) | class TagSchema(PlainTagSchema):
  class TagAndItemSchema (line 42) | class TagAndItemSchema(Schema):
  class UserSchema (line 48) | class UserSchema(Schema):

FILE: docs/docs/08_flask_jwt_extended/10_logout_users_rest_api/start/app.py
  function create_app (line 13) | def create_app(db_url=None):

FILE: docs/docs/08_flask_jwt_extended/10_logout_users_rest_api/start/conftest.py
  function app (line 7) | def app():
  function client (line 19) | def client(app):
  function jwt (line 24) | def jwt(app):
  function admin_jwt (line 31) | def admin_jwt(app):

FILE: docs/docs/08_flask_jwt_extended/10_logout_users_rest_api/start/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/10_logout_users_rest_api/start/models/item_tags.py
  class ItemsTags (line 4) | class ItemsTags(db.Model):

FILE: docs/docs/08_flask_jwt_extended/10_logout_users_rest_api/start/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/10_logout_users_rest_api/start/models/tag.py
  class TagModel (line 4) | class TagModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/10_logout_users_rest_api/start/models/user.py
  class UserModel (line 4) | class UserModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/10_logout_users_rest_api/start/resources/__tests__/conftest.py
  function created_store_id (line 5) | def created_store_id(client):
  function created_item_id (line 15) | def created_item_id(client, jwt, created_store_id):
  function created_tag_id (line 26) | def created_tag_id(client, created_store_id):

FILE: docs/docs/08_flask_jwt_extended/10_logout_users_rest_api/start/resources/__tests__/test_item.py
  function test_create_item_in_store (line 1) | def test_create_item_in_store(client, jwt, created_store_id):
  function test_create_item_with_store_id_not_found (line 14) | def test_create_item_with_store_id_not_found(client, jwt):
  function test_create_item_with_unknown_data (line 28) | def test_create_item_with_unknown_data(client, jwt):
  function test_delete_item (line 44) | def test_delete_item(client, admin_jwt, created_item_id):
  function test_delete_item_without_admin (line 54) | def test_delete_item_without_admin(client, jwt, created_item_id):
  function test_update_item (line 64) | def test_update_item(client, jwt, created_item_id):
  function test_get_all_items (line 76) | def test_get_all_items(client, jwt):
  function test_get_all_items_empty (line 100) | def test_get_all_items_empty(client, jwt):
  function test_get_item_details (line 110) | def test_get_item_details(client, jwt, created_item_id, created_store_id):
  function test_get_item_details_with_tag (line 122) | def test_get_item_details_with_tag(client, jwt, created_item_id, created...
  function test_get_item_detail_not_found (line 135) | def test_get_item_detail_not_found(client, jwt):

FILE: docs/docs/08_flask_jwt_extended/10_logout_users_rest_api/start/resources/__tests__/test_store.py
  function test_get_store (line 1) | def test_get_store(client, created_store_id):
  function test_get_store_not_found (line 15) | def test_get_store_not_found(client):
  function test_get_store_with_item (line 24) | def test_get_store_with_item(client, jwt, created_store_id):
  function test_get_store_with_tag (line 45) | def test_get_store_with_tag(client, created_store_id):
  function test_create_store (line 59) | def test_create_store(client):
  function test_create_store_with_items (line 69) | def test_create_store_with_items(client, created_store_id, jwt):
  function test_delete_store (line 91) | def test_delete_store(client, created_store_id):
  function test_delete_store_doesnt_exist (line 100) | def test_delete_store_doesnt_exist(client):
  function test_get_store_list_empty (line 109) | def test_get_store_list_empty(client):
  function test_get_store_list_single (line 118) | def test_get_store_list_single(client):
  function test_get_store_list_multiple (line 132) | def test_get_store_list_multiple(client):
  function test_get_store_list_with_items (line 153) | def test_get_store_list_with_items(client, jwt):
  function test_get_store_list_with_tags (line 185) | def test_get_store_list_with_tags(client):
  function test_create_store_duplicate_name (line 209) | def test_create_store_duplicate_name(client):

FILE: docs/docs/08_flask_jwt_extended/10_logout_users_rest_api/start/resources/__tests__/test_tag.py
  function created_tag_with_item_id (line 8) | def created_tag_with_item_id(client, created_item_id, created_tag_id):
  function test_get_tag (line 18) | def test_get_tag(client, created_tag_id):
  function test_get_tag_not_found (line 32) | def test_get_tag_not_found(client):
  function test_items_linked_with_tag (line 41) | def test_items_linked_with_tag(client, created_tag_with_item_id):
  function test_unlink_tag_from_item (line 56) | def test_unlink_tag_from_item(client, created_item_id, created_tag_with_...
  function test_delete_tag_without_items (line 67) | def test_delete_tag_without_items(client, created_tag_id):
  function test_delete_tag_still_has_items (line 80) | def test_delete_tag_still_has_items(client, created_tag_with_item_id):
  function test_delete_tag_not_found (line 90) | def test_delete_tag_not_found(client):
  function test_get_all_tags_in_store (line 99) | def test_get_all_tags_in_store(client, created_store_id, created_tag_id):
  function test_get_all_tags_in_store_not_found (line 115) | def test_get_all_tags_in_store_not_found(client):

FILE: docs/docs/08_flask_jwt_extended/10_logout_users_rest_api/start/resources/__tests__/test_user.py
  function created_user_details (line 5) | def created_user_details(client):
  function created_user_jwt (line 17) | def created_user_jwt(client, created_user_details):
  function test_register_user (line 27) | def test_register_user(client):
  function test_register_user_already_exists (line 38) | def test_register_user_already_exists(client):
  function test_register_user_missing_data (line 54) | def test_register_user_missing_data(client):
  function test_login_user (line 65) | def test_login_user(client, created_user_details):
  function test_login_user_bad_password (line 76) | def test_login_user_bad_password(client, created_user_details):
  function test_login_user_bad_username (line 87) | def test_login_user_bad_username(client, created_user_details):
  function test_get_user_details (line 98) | def test_get_user_details(client, created_user_details):
  function test_get_user_details_missing (line 110) | def test_get_user_details_missing(client):

FILE: docs/docs/08_flask_jwt_extended/10_logout_users_rest_api/start/resources/item.py
  class Item (line 14) | class Item(MethodView):
    method get (line 17) | def get(self, item_id):
    method delete (line 22) | def delete(self, item_id):
    method put (line 34) | def put(self, item_data, item_id):
  class ItemList (line 50) | class ItemList(MethodView):
    method get (line 53) | def get(self):
    method post (line 59) | def post(self, item_data):

FILE: docs/docs/08_flask_jwt_extended/10_logout_users_rest_api/start/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 20) | def delete(self, store_id):
  class StoreList (line 28) | class StoreList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, store_data):

FILE: docs/docs/08_flask_jwt_extended/10_logout_users_rest_api/start/resources/tag.py
  class TagsInStore (line 13) | class TagsInStore(MethodView):
    method get (line 15) | def get(self, store_id):
    method post (line 22) | def post(self, tag_data, store_id):
  class LinkTagsToItem (line 41) | class LinkTagsToItem(MethodView):
    method post (line 43) | def post(self, item_id, tag_id):
    method delete (line 58) | def delete(self, item_id, tag_id):
  class Tag (line 74) | class Tag(MethodView):
    method get (line 76) | def get(self, tag_id):
    method delete (line 90) | def delete(self, tag_id):

FILE: docs/docs/08_flask_jwt_extended/10_logout_users_rest_api/start/resources/user.py
  class UserRegister (line 15) | class UserRegister(MethodView):
    method post (line 17) | def post(self, user_data):
  class UserLogin (line 32) | class UserLogin(MethodView):
    method post (line 34) | def post(self, user_data):
  class User (line 47) | class User(MethodView):
    method get (line 56) | def get(self, user_id):
    method delete (line 60) | def delete(self, user_id):

FILE: docs/docs/08_flask_jwt_extended/10_logout_users_rest_api/start/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class PlainTagSchema (line 15) | class PlainTagSchema(Schema):
  class ItemSchema (line 20) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 26) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 31) | class StoreSchema(PlainStoreSchema):
  class TagSchema (line 36) | class TagSchema(PlainTagSchema):
  class TagAndItemSchema (line 42) | class TagAndItemSchema(Schema):
  class UserSchema (line 48) | class UserSchema(Schema):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/end/app.py
  function create_app (line 14) | def create_app(db_url=None):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/end/conftest.py
  function app (line 7) | def app():
  function client (line 19) | def client(app):
  function fresh_jwt (line 24) | def fresh_jwt(app):
  function jwt (line 31) | def jwt(app):
  function admin_jwt (line 38) | def admin_jwt(app):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/end/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/end/models/item_tags.py
  class ItemsTags (line 4) | class ItemsTags(db.Model):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/end/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/end/models/tag.py
  class TagModel (line 4) | class TagModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/end/models/user.py
  class UserModel (line 4) | class UserModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/end/resources/__tests__/conftest.py
  function created_store_id (line 5) | def created_store_id(client):
  function created_item_id (line 15) | def created_item_id(client, fresh_jwt, created_store_id):
  function created_tag_id (line 26) | def created_tag_id(client, created_store_id):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/end/resources/__tests__/test_item.py
  function test_create_item_in_store (line 1) | def test_create_item_in_store(client, fresh_jwt, created_store_id):
  function test_create_item_with_store_id_not_found (line 14) | def test_create_item_with_store_id_not_found(client, fresh_jwt):
  function test_create_item_with_unknown_data (line 28) | def test_create_item_with_unknown_data(client, fresh_jwt):
  function test_create_item_with_non_fresh_jwt (line 44) | def test_create_item_with_non_fresh_jwt(client, jwt):
  function test_delete_item (line 58) | def test_delete_item(client, admin_jwt, created_item_id):
  function test_delete_item_without_admin (line 68) | def test_delete_item_without_admin(client, jwt, created_item_id):
  function test_update_item (line 78) | def test_update_item(client, jwt, created_item_id):
  function test_get_all_items (line 90) | def test_get_all_items(client, fresh_jwt, jwt):
  function test_get_all_items_empty (line 114) | def test_get_all_items_empty(client, jwt):
  function test_get_item_details (line 124) | def test_get_item_details(client, jwt, created_item_id, created_store_id):
  function test_get_item_details_with_tag (line 136) | def test_get_item_details_with_tag(client, jwt, created_item_id, created...
  function test_get_item_detail_not_found (line 149) | def test_get_item_detail_not_found(client, jwt):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/end/resources/__tests__/test_store.py
  function test_get_store (line 1) | def test_get_store(client, created_store_id):
  function test_get_store_not_found (line 15) | def test_get_store_not_found(client):
  function test_get_store_with_item (line 24) | def test_get_store_with_item(client, fresh_jwt, created_store_id):
  function test_get_store_with_tag (line 45) | def test_get_store_with_tag(client, created_store_id):
  function test_create_store (line 59) | def test_create_store(client):
  function test_create_store_with_items (line 69) | def test_create_store_with_items(client, created_store_id, fresh_jwt):
  function test_delete_store (line 91) | def test_delete_store(client, created_store_id):
  function test_delete_store_doesnt_exist (line 100) | def test_delete_store_doesnt_exist(client):
  function test_get_store_list_empty (line 109) | def test_get_store_list_empty(client):
  function test_get_store_list_single (line 118) | def test_get_store_list_single(client):
  function test_get_store_list_multiple (line 132) | def test_get_store_list_multiple(client):
  function test_get_store_list_with_items (line 153) | def test_get_store_list_with_items(client, fresh_jwt):
  function test_get_store_list_with_tags (line 185) | def test_get_store_list_with_tags(client):
  function test_create_store_duplicate_name (line 209) | def test_create_store_duplicate_name(client):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/end/resources/__tests__/test_tag.py
  function created_tag_with_item_id (line 8) | def created_tag_with_item_id(client, created_item_id, created_tag_id):
  function test_get_tag (line 18) | def test_get_tag(client, created_tag_id):
  function test_get_tag_not_found (line 32) | def test_get_tag_not_found(client):
  function test_items_linked_with_tag (line 41) | def test_items_linked_with_tag(client, created_tag_with_item_id):
  function test_unlink_tag_from_item (line 56) | def test_unlink_tag_from_item(client, created_item_id, created_tag_with_...
  function test_delete_tag_without_items (line 67) | def test_delete_tag_without_items(client, created_tag_id):
  function test_delete_tag_still_has_items (line 80) | def test_delete_tag_still_has_items(client, created_tag_with_item_id):
  function test_delete_tag_not_found (line 90) | def test_delete_tag_not_found(client):
  function test_get_all_tags_in_store (line 99) | def test_get_all_tags_in_store(client, created_store_id, created_tag_id):
  function test_get_all_tags_in_store_not_found (line 115) | def test_get_all_tags_in_store_not_found(client):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/end/resources/__tests__/test_user.py
  function created_user_details (line 5) | def created_user_details(client):
  function created_user_jwts (line 17) | def created_user_jwts(client, created_user_details):
  function test_register_user (line 27) | def test_register_user(client):
  function test_register_user_already_exists (line 38) | def test_register_user_already_exists(client):
  function test_register_user_missing_data (line 54) | def test_register_user_missing_data(client):
  function test_login_user (line 65) | def test_login_user(client, created_user_details):
  function test_login_user_bad_password (line 76) | def test_login_user_bad_password(client, created_user_details):
  function test_login_user_bad_username (line 87) | def test_login_user_bad_username(client, created_user_details):
  function test_logout_user (line 98) | def test_logout_user(client, created_user_jwts):
  function test_logout_user_twice (line 108) | def test_logout_user_twice(client, created_user_jwts):
  function test_logout_user_no_token (line 125) | def test_logout_user_no_token(client):
  function test_logout_user_invalid_token (line 134) | def test_logout_user_invalid_token(client):
  function test_get_user_details (line 147) | def test_get_user_details(client, created_user_details):
  function test_get_user_details_missing (line 159) | def test_get_user_details_missing(client):
  function test_refresh_token_invalid (line 168) | def test_refresh_token_invalid(client):
  function test_refresh_token (line 177) | def test_refresh_token(client, created_user_jwts):
  function test_refresh_token_twice (line 187) | def test_refresh_token_twice(client, created_user_jwts):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/end/resources/item.py
  class Item (line 14) | class Item(MethodView):
    method get (line 17) | def get(self, item_id):
    method delete (line 22) | def delete(self, item_id):
    method put (line 34) | def put(self, item_data, item_id):
  class ItemList (line 50) | class ItemList(MethodView):
    method get (line 53) | def get(self):
    method post (line 59) | def post(self, item_data):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/end/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 20) | def delete(self, store_id):
  class StoreList (line 28) | class StoreList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, store_data):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/end/resources/tag.py
  class TagsInStore (line 13) | class TagsInStore(MethodView):
    method get (line 15) | def get(self, store_id):
    method post (line 22) | def post(self, tag_data, store_id):
  class LinkTagsToItem (line 41) | class LinkTagsToItem(MethodView):
    method post (line 43) | def post(self, item_id, tag_id):
    method delete (line 58) | def delete(self, item_id, tag_id):
  class Tag (line 74) | class Tag(MethodView):
    method get (line 76) | def get(self, tag_id):
    method delete (line 90) | def delete(self, tag_id):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/end/resources/user.py
  class UserRegister (line 22) | class UserRegister(MethodView):
    method post (line 24) | def post(self, user_data):
  class UserLogin (line 39) | class UserLogin(MethodView):
    method post (line 41) | def post(self, user_data):
  class UserLogout (line 55) | class UserLogout(MethodView):
    method post (line 57) | def post(self):
  class User (line 64) | class User(MethodView):
    method get (line 73) | def get(self, user_id):
    method delete (line 77) | def delete(self, user_id):
  class TokenRefresh (line 85) | class TokenRefresh(MethodView):
    method post (line 87) | def post(self):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/end/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class PlainTagSchema (line 15) | class PlainTagSchema(Schema):
  class ItemSchema (line 20) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 26) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 31) | class StoreSchema(PlainStoreSchema):
  class TagSchema (line 36) | class TagSchema(PlainTagSchema):
  class TagAndItemSchema (line 42) | class TagAndItemSchema(Schema):
  class UserSchema (line 48) | class UserSchema(Schema):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/end_video/app.py
  function create_app (line 14) | def create_app(db_url=None):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/end_video/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/end_video/models/item_tags.py
  class ItemsTags (line 4) | class ItemsTags(db.Model):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/end_video/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/end_video/models/tag.py
  class TagModel (line 4) | class TagModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/end_video/models/user.py
  class UserModel (line 4) | class UserModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/end_video/resources/item.py
  class Item (line 14) | class Item(MethodView):
    method get (line 17) | def get(self, item_id):
    method delete (line 22) | def delete(self, item_id):
    method put (line 34) | def put(self, item_data, item_id):
  class ItemList (line 50) | class ItemList(MethodView):
    method get (line 53) | def get(self):
    method post (line 59) | def post(self, item_data):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/end_video/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 20) | def delete(self, store_id):
  class StoreList (line 28) | class StoreList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, store_data):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/end_video/resources/tag.py
  class TagsInStore (line 13) | class TagsInStore(MethodView):
    method get (line 15) | def get(self, store_id):
    method post (line 22) | def post(self, tag_data, store_id):
  class LinkTagsToItem (line 41) | class LinkTagsToItem(MethodView):
    method post (line 43) | def post(self, item_id, tag_id):
    method delete (line 58) | def delete(self, item_id, tag_id):
  class Tag (line 74) | class Tag(MethodView):
    method get (line 76) | def get(self, tag_id):
    method delete (line 90) | def delete(self, tag_id):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/end_video/resources/user.py
  class UserRegister (line 22) | class UserRegister(MethodView):
    method post (line 24) | def post(self, user_data):
  class UserLogin (line 39) | class UserLogin(MethodView):
    method post (line 41) | def post(self, user_data):
  class UserLogout (line 55) | class UserLogout(MethodView):
    method post (line 57) | def post(self):
  class User (line 64) | class User(MethodView):
    method get (line 73) | def get(self, user_id):
    method delete (line 77) | def delete(self, user_id):
  class TokenRefresh (line 85) | class TokenRefresh(MethodView):
    method post (line 87) | def post(self):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/end_video/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class PlainTagSchema (line 15) | class PlainTagSchema(Schema):
  class ItemSchema (line 20) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 26) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 31) | class StoreSchema(PlainStoreSchema):
  class TagSchema (line 36) | class TagSchema(PlainTagSchema):
  class TagAndItemSchema (line 42) | class TagAndItemSchema(Schema):
  class UserSchema (line 48) | class UserSchema(Schema):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/start/app.py
  function create_app (line 14) | def create_app(db_url=None):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/start/conftest.py
  function app (line 7) | def app():
  function client (line 19) | def client(app):
  function jwt (line 24) | def jwt(app):
  function admin_jwt (line 31) | def admin_jwt(app):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/start/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/start/models/item_tags.py
  class ItemsTags (line 4) | class ItemsTags(db.Model):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/start/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/start/models/tag.py
  class TagModel (line 4) | class TagModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/start/models/user.py
  class UserModel (line 4) | class UserModel(db.Model):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/start/resources/__tests__/conftest.py
  function created_store_id (line 5) | def created_store_id(client):
  function created_item_id (line 15) | def created_item_id(client, jwt, created_store_id):
  function created_tag_id (line 26) | def created_tag_id(client, created_store_id):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/start/resources/__tests__/test_item.py
  function test_create_item_in_store (line 1) | def test_create_item_in_store(client, jwt, created_store_id):
  function test_create_item_with_store_id_not_found (line 14) | def test_create_item_with_store_id_not_found(client, jwt):
  function test_create_item_with_unknown_data (line 28) | def test_create_item_with_unknown_data(client, jwt):
  function test_delete_item (line 44) | def test_delete_item(client, admin_jwt, created_item_id):
  function test_delete_item_without_admin (line 54) | def test_delete_item_without_admin(client, jwt, created_item_id):
  function test_update_item (line 64) | def test_update_item(client, jwt, created_item_id):
  function test_get_all_items (line 76) | def test_get_all_items(client, jwt):
  function test_get_all_items_empty (line 100) | def test_get_all_items_empty(client, jwt):
  function test_get_item_details (line 110) | def test_get_item_details(client, jwt, created_item_id, created_store_id):
  function test_get_item_details_with_tag (line 122) | def test_get_item_details_with_tag(client, jwt, created_item_id, created...
  function test_get_item_detail_not_found (line 135) | def test_get_item_detail_not_found(client, jwt):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/start/resources/__tests__/test_store.py
  function test_get_store (line 1) | def test_get_store(client, created_store_id):
  function test_get_store_not_found (line 15) | def test_get_store_not_found(client):
  function test_get_store_with_item (line 24) | def test_get_store_with_item(client, jwt, created_store_id):
  function test_get_store_with_tag (line 45) | def test_get_store_with_tag(client, created_store_id):
  function test_create_store (line 59) | def test_create_store(client):
  function test_create_store_with_items (line 69) | def test_create_store_with_items(client, created_store_id, jwt):
  function test_delete_store (line 91) | def test_delete_store(client, created_store_id):
  function test_delete_store_doesnt_exist (line 100) | def test_delete_store_doesnt_exist(client):
  function test_get_store_list_empty (line 109) | def test_get_store_list_empty(client):
  function test_get_store_list_single (line 118) | def test_get_store_list_single(client):
  function test_get_store_list_multiple (line 132) | def test_get_store_list_multiple(client):
  function test_get_store_list_with_items (line 153) | def test_get_store_list_with_items(client, jwt):
  function test_get_store_list_with_tags (line 185) | def test_get_store_list_with_tags(client):
  function test_create_store_duplicate_name (line 209) | def test_create_store_duplicate_name(client):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/start/resources/__tests__/test_tag.py
  function created_tag_with_item_id (line 8) | def created_tag_with_item_id(client, created_item_id, created_tag_id):
  function test_get_tag (line 18) | def test_get_tag(client, created_tag_id):
  function test_get_tag_not_found (line 32) | def test_get_tag_not_found(client):
  function test_items_linked_with_tag (line 41) | def test_items_linked_with_tag(client, created_tag_with_item_id):
  function test_unlink_tag_from_item (line 56) | def test_unlink_tag_from_item(client, created_item_id, created_tag_with_...
  function test_delete_tag_without_items (line 67) | def test_delete_tag_without_items(client, created_tag_id):
  function test_delete_tag_still_has_items (line 80) | def test_delete_tag_still_has_items(client, created_tag_with_item_id):
  function test_delete_tag_not_found (line 90) | def test_delete_tag_not_found(client):
  function test_get_all_tags_in_store (line 99) | def test_get_all_tags_in_store(client, created_store_id, created_tag_id):
  function test_get_all_tags_in_store_not_found (line 115) | def test_get_all_tags_in_store_not_found(client):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/start/resources/__tests__/test_user.py
  function created_user_details (line 5) | def created_user_details(client):
  function created_user_jwt (line 17) | def created_user_jwt(client, created_user_details):
  function test_register_user (line 27) | def test_register_user(client):
  function test_register_user_already_exists (line 38) | def test_register_user_already_exists(client):
  function test_register_user_missing_data (line 54) | def test_register_user_missing_data(client):
  function test_login_user (line 65) | def test_login_user(client, created_user_details):
  function test_login_user_bad_password (line 76) | def test_login_user_bad_password(client, created_user_details):
  function test_login_user_bad_username (line 87) | def test_login_user_bad_username(client, created_user_details):
  function test_logout_user (line 98) | def test_logout_user(client, created_user_jwt):
  function test_logout_user_twice (line 108) | def test_logout_user_twice(client, created_user_jwt):
  function test_logout_user_no_token (line 125) | def test_logout_user_no_token(client):
  function test_logout_user_invalid_token (line 134) | def test_logout_user_invalid_token(client):
  function test_get_user_details (line 147) | def test_get_user_details(client, created_user_details):
  function test_get_user_details_missing (line 159) | def test_get_user_details_missing(client):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/start/resources/item.py
  class Item (line 14) | class Item(MethodView):
    method get (line 17) | def get(self, item_id):
    method delete (line 22) | def delete(self, item_id):
    method put (line 34) | def put(self, item_data, item_id):
  class ItemList (line 50) | class ItemList(MethodView):
    method get (line 53) | def get(self):
    method post (line 59) | def post(self, item_data):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/start/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 20) | def delete(self, store_id):
  class StoreList (line 28) | class StoreList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, store_data):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/start/resources/tag.py
  class TagsInStore (line 13) | class TagsInStore(MethodView):
    method get (line 15) | def get(self, store_id):
    method post (line 22) | def post(self, tag_data, store_id):
  class LinkTagsToItem (line 41) | class LinkTagsToItem(MethodView):
    method post (line 43) | def post(self, item_id, tag_id):
    method delete (line 58) | def delete(self, item_id, tag_id):
  class Tag (line 74) | class Tag(MethodView):
    method get (line 76) | def get(self, tag_id):
    method delete (line 90) | def delete(self, tag_id):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/start/resources/user.py
  class UserRegister (line 20) | class UserRegister(MethodView):
    method post (line 22) | def post(self, user_data):
  class UserLogin (line 37) | class UserLogin(MethodView):
    method post (line 39) | def post(self, user_data):
  class UserLogout (line 52) | class UserLogout(MethodView):
    method post (line 54) | def post(self):
  class User (line 61) | class User(MethodView):
    method get (line 70) | def get(self, user_id):
    method delete (line 74) | def delete(self, user_id):

FILE: docs/docs/08_flask_jwt_extended/12_token_refreshing_flask_jwt_extended/start/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class PlainTagSchema (line 15) | class PlainTagSchema(Schema):
  class ItemSchema (line 20) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 26) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 31) | class StoreSchema(PlainStoreSchema):
  class TagSchema (line 36) | class TagSchema(PlainTagSchema):
  class TagAndItemSchema (line 42) | class TagAndItemSchema(Schema):
  class UserSchema (line 48) | class UserSchema(Schema):

FILE: docs/docs/09_flask_migrate/02_add_flask_migrate_to_app/end/app.py
  function create_app (line 15) | def create_app(db_url=None):

FILE: docs/docs/09_flask_migrate/02_add_flask_migrate_to_app/end/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/09_flask_migrate/02_add_flask_migrate_to_app/end/models/item_tags.py
  class ItemsTags (line 4) | class ItemsTags(db.Model):

FILE: docs/docs/09_flask_migrate/02_add_flask_migrate_to_app/end/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/09_flask_migrate/02_add_flask_migrate_to_app/end/models/tag.py
  class TagModel (line 4) | class TagModel(db.Model):

FILE: docs/docs/09_flask_migrate/02_add_flask_migrate_to_app/end/models/user.py
  class UserModel (line 4) | class UserModel(db.Model):

FILE: docs/docs/09_flask_migrate/02_add_flask_migrate_to_app/end/resources/item.py
  class Item (line 14) | class Item(MethodView):
    method get (line 17) | def get(self, item_id):
    method delete (line 22) | def delete(self, item_id):
    method put (line 34) | def put(self, item_data, item_id):
  class ItemList (line 50) | class ItemList(MethodView):
    method get (line 53) | def get(self):
    method post (line 59) | def post(self, item_data):

FILE: docs/docs/09_flask_migrate/02_add_flask_migrate_to_app/end/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 20) | def delete(self, store_id):
  class StoreList (line 28) | class StoreList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, store_data):

FILE: docs/docs/09_flask_migrate/02_add_flask_migrate_to_app/end/resources/tag.py
  class TagsInStore (line 13) | class TagsInStore(MethodView):
    method get (line 15) | def get(self, store_id):
    method post (line 22) | def post(self, tag_data, store_id):
  class LinkTagsToItem (line 41) | class LinkTagsToItem(MethodView):
    method post (line 43) | def post(self, item_id, tag_id):
    method delete (line 58) | def delete(self, item_id, tag_id):
  class Tag (line 74) | class Tag(MethodView):
    method get (line 76) | def get(self, tag_id):
    method delete (line 90) | def delete(self, tag_id):

FILE: docs/docs/09_flask_migrate/02_add_flask_migrate_to_app/end/resources/user.py
  class UserRegister (line 22) | class UserRegister(MethodView):
    method post (line 24) | def post(self, user_data):
  class UserLogin (line 39) | class UserLogin(MethodView):
    method post (line 41) | def post(self, user_data):
  class UserLogout (line 55) | class UserLogout(MethodView):
    method post (line 57) | def post(self):
  class User (line 64) | class User(MethodView):
    method get (line 73) | def get(self, user_id):
    method delete (line 77) | def delete(self, user_id):
  class TokenRefresh (line 85) | class TokenRefresh(MethodView):
    method post (line 87) | def post(self):

FILE: docs/docs/09_flask_migrate/02_add_flask_migrate_to_app/end/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  class PlainTagSchema (line 15) | class PlainTagSchema(Schema):
  class ItemSchema (line 20) | class ItemSchema(PlainItemSchema):
  class ItemUpdateSchema (line 26) | class ItemUpdateSchema(Schema):
  class StoreSchema (line 31) | class StoreSchema(PlainStoreSchema):
  class TagSchema (line 36) | class TagSchema(PlainTagSchema):
  class TagAndItemSchema (line 42) | class TagAndItemSchema(Schema):
  class UserSchema (line 48) | class UserSchema(Schema):

FILE: docs/docs/09_flask_migrate/02_add_flask_migrate_to_app/start/app.py
  function create_app (line 14) | def create_app(db_url=None):

FILE: docs/docs/09_flask_migrate/02_add_flask_migrate_to_app/start/models/item.py
  class ItemModel (line 4) | class ItemModel(db.Model):

FILE: docs/docs/09_flask_migrate/02_add_flask_migrate_to_app/start/models/item_tags.py
  class ItemsTags (line 4) | class ItemsTags(db.Model):

FILE: docs/docs/09_flask_migrate/02_add_flask_migrate_to_app/start/models/store.py
  class StoreModel (line 4) | class StoreModel(db.Model):

FILE: docs/docs/09_flask_migrate/02_add_flask_migrate_to_app/start/models/tag.py
  class TagModel (line 4) | class TagModel(db.Model):

FILE: docs/docs/09_flask_migrate/02_add_flask_migrate_to_app/start/models/user.py
  class UserModel (line 4) | class UserModel(db.Model):

FILE: docs/docs/09_flask_migrate/02_add_flask_migrate_to_app/start/resources/item.py
  class Item (line 14) | class Item(MethodView):
    method get (line 17) | def get(self, item_id):
    method delete (line 22) | def delete(self, item_id):
    method put (line 34) | def put(self, item_data, item_id):
  class ItemList (line 50) | class ItemList(MethodView):
    method get (line 53) | def get(self):
    method post (line 59) | def post(self, item_data):

FILE: docs/docs/09_flask_migrate/02_add_flask_migrate_to_app/start/resources/store.py
  class Store (line 14) | class Store(MethodView):
    method get (line 16) | def get(self, store_id):
    method delete (line 20) | def delete(self, store_id):
  class StoreList (line 28) | class StoreList(MethodView):
    method get (line 30) | def get(self):
    method post (line 35) | def post(self, store_data):

FILE: docs/docs/09_flask_migrate/02_add_flask_migrate_to_app/start/resources/tag.py
  class TagsInStore (line 13) | class TagsInStore(MethodView):
    method get (line 15) | def get(self, store_id):
    method post (line 22) | def post(self, tag_data, store_id):
  class LinkTagsToItem (line 41) | class LinkTagsToItem(MethodView):
    method post (line 43) | def post(self, item_id, tag_id):
    method delete (line 58) | def delete(self, item_id, tag_id):
  class Tag (line 74) | class Tag(MethodView):
    method get (line 76) | def get(self, tag_id):
    method delete (line 90) | def delete(self, tag_id):

FILE: docs/docs/09_flask_migrate/02_add_flask_migrate_to_app/start/resources/user.py
  class UserRegister (line 22) | class UserRegister(MethodView):
    method post (line 24) | def post(self, user_data):
  class UserLogin (line 39) | class UserLogin(MethodView):
    method post (line 41) | def post(self, user_data):
  class UserLogout (line 55) | class UserLogout(MethodView):
    method post (line 57) | def post(self):
  class User (line 64) | class User(MethodView):
    method get (line 73) | def get(self, user_id):
    method delete (line 77) | def delete(self, user_id):
  class TokenRefresh (line 85) | class TokenRefresh(MethodView):
    method post (line 87) | def post(self):

FILE: docs/docs/09_flask_migrate/02_add_flask_migrate_to_app/start/schemas.py
  class PlainItemSchema (line 4) | class PlainItemSchema(Schema):
  class PlainStoreSchema (line 10) | class PlainStoreSchema(Schema):
  c
Condensed preview — 1594 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,154K chars).
[
  {
    "path": ".flake8",
    "chars": 76,
    "preview": "[flake8]\nmax-line-length = 88\nexclude = .git,__pycache__\nmax-complexity = 10"
  },
  {
    "path": ".github/workflows/algolia-scraper.yml",
    "chars": 469,
    "preview": "name: Run Algolia Scraper\n\non:\n  push:\n    branches: [\"master\", \"develop\"]\n  pull_request:\n    branches: [\"master\", \"dev"
  },
  {
    "path": ".gitignore",
    "chars": 133,
    "preview": ".vscode/\n*.pyc\n.idea/\n__pycache__/\n*.db\n.DS_Store\nvenv/\n.venv/\ndocs/docs/.nota/config.ini\nsection-start-code.zip\nsection"
  },
  {
    "path": ".gitmodules",
    "chars": 139,
    "preview": "[submodule \"Flask-Smorest Docker\"]\n\tpath = project/using-flask-smorest-docker\n\turl = https://github.com/tecladocode/rest"
  },
  {
    "path": ".python-version",
    "chars": 7,
    "preview": "3.10.0\n"
  },
  {
    "path": ".templates/lecture.md",
    "chars": 319,
    "preview": "---\ntitle: The lecture title goes here\ndescription: A brief description of the lecture goes here.\n---\n\n- [ ] Set metadat"
  },
  {
    "path": ".templates/section.md",
    "chars": 93,
    "preview": "---\nname: \"Section name here\"\n---\n\n# Section name here\n\nDescription of the section goes here."
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 823,
    "preview": "# How to contribute to this course\n\n## E-book contributions\n\n### How to run the e-book\n\nClone the repo and navigate to t"
  },
  {
    "path": "README.md",
    "chars": 3883,
    "preview": "# REST APIs with Flask and Python\n\n<p align=\"center\">\n <img src=\"assets/course-image.png\" alt=\"REST APIs with Flask and "
  },
  {
    "path": "dependabot.yml",
    "chars": 303,
    "preview": "version: 2\nupdates:\n  - package-ecosystem: \"npm\"\n    directory: \"/docs\"\n    schedule:\n      interval: \"weekly\"\n      # C"
  },
  {
    "path": "docs/.gitignore",
    "chars": 233,
    "preview": "# Dependencies\n/node_modules\n\n# Production\n/build\n\n# Generated files\n.docusaurus\n.cache-loader\n\n# Misc\n.DS_Store\n.env.lo"
  },
  {
    "path": "docs/README.md",
    "chars": 789,
    "preview": "# Website\n\nThis website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator.\n\n### I"
  },
  {
    "path": "docs/algolia.config.json",
    "chars": 1374,
    "preview": "{\n    \"index_name\": \"docusaurus-2\",\n    \"start_urls\": [\n        \"https://rest-apis-flask.teclado.com/\"\n    ],\n    \"sitem"
  },
  {
    "path": "docs/babel.config.js",
    "chars": 89,
    "preview": "module.exports = {\n  presets: [require.resolve('@docusaurus/core/lib/babel/preset')],\n};\n"
  },
  {
    "path": "docs/docs/01_course_intro/02_how_to_install_python/README.md",
    "chars": 1826,
    "preview": "---\ntitle: How to install Python\ndescription: A brief description of the lecture goes here.\nctslug: how-to-install-pytho"
  },
  {
    "path": "docs/docs/01_course_intro/03_how_to_install_ide/README.md",
    "chars": 1824,
    "preview": "---\ntitle: How to install an IDE\ndescription: What IDE should you use? How do you install it? Let me show you in this qu"
  },
  {
    "path": "docs/docs/01_course_intro/04_what_is_rest_api/README.md",
    "chars": 10751,
    "preview": "---\ntitle: \"What is a REST API?\"\ndescription: \"There's a lot of confusion around what is and isn't a REST API. Let's tak"
  },
  {
    "path": "docs/docs/01_course_intro/_category_.json",
    "chars": 58,
    "preview": "{\n    \"label\": \"Course Introduction\",\n    \"position\": 1\n}\n"
  },
  {
    "path": "docs/docs/01_course_intro/index.md",
    "chars": 2768,
    "preview": "---\nid: intro\n---\n\n# REST APIs with Flask and Python\n\nimport VideoEmbed from \"@site/src/components/VideoEmbed\";\n\n<div st"
  },
  {
    "path": "docs/docs/02_python_refresher/_category_.json",
    "chars": 55,
    "preview": "{\n    \"label\": \"Python Refresher\",\n    \"position\": 2\n}\n"
  },
  {
    "path": "docs/docs/02_python_refresher/index.md",
    "chars": 577,
    "preview": "---\nname: \"A Complete Python Refresher\"\n---\n\n# Python Refresher\n\nWe've included a Python Refresher section in this cours"
  },
  {
    "path": "docs/docs/03_first_rest_api/01_project_overview/README.md",
    "chars": 2125,
    "preview": "---\ntitle: Project Overview\ndescription: A first look at the project we'll build in this section.\nctslug: overview-of-yo"
  },
  {
    "path": "docs/docs/03_first_rest_api/02_getting_set_up/README.md",
    "chars": 1061,
    "preview": "---\ntitle: Getting set up\ndescription: Set up a Flask project and create the Flask app.\nctslug: getting-set-up\n---\n\n# Ge"
  },
  {
    "path": "docs/docs/03_first_rest_api/03_first_rest_api_endpoint/README.md",
    "chars": 1625,
    "preview": "---\ntitle: Your First REST API Endpoint\ndescription: Learn how to define a REST API endpoint using Flask.\nctslug: your-f"
  },
  {
    "path": "docs/docs/03_first_rest_api/04_what_is_json/README.md",
    "chars": 1687,
    "preview": "---\ntitle: \"What is JSON?\"\ndescription: JSON is the way we normally transfer data to and from REST APIs.\nctslug: what-is"
  },
  {
    "path": "docs/docs/03_first_rest_api/05_make_request_to_rest_api/README.md",
    "chars": 4429,
    "preview": "---\ntitle: How to interact with your REST API\ndescription: Use Postman and Insomnia REST Client to interact with your RE"
  },
  {
    "path": "docs/docs/03_first_rest_api/06_creating_stores/README.md",
    "chars": 2231,
    "preview": "---\ntitle: How to create stores\ndescription: Learn how to add data to our REST API.\nctslug: how-to-create-stores\n---\n\n# "
  },
  {
    "path": "docs/docs/03_first_rest_api/07_creating_items/README.md",
    "chars": 3116,
    "preview": "---\ntitle: How to create items in each store\ndescription: A brief description of the lecture goes here.\nctslug: how-to-c"
  },
  {
    "path": "docs/docs/03_first_rest_api/08_return_data_from_rest_api/README.md",
    "chars": 938,
    "preview": "---\ntitle: Get a specific store and its items\ndescription: How to use Flask to return data from your REST API to your cl"
  },
  {
    "path": "docs/docs/03_first_rest_api/09_final_code/README.md",
    "chars": 1527,
    "preview": "---\ntitle: Final code of this section\ndescription: Overview of the project we've built and all the code in it.\nctslug: f"
  },
  {
    "path": "docs/docs/03_first_rest_api/09_final_code/end/app.py",
    "chars": 1177,
    "preview": "from flask import Flask, request\n\napp = Flask(__name__)\n\nstores = [{\"name\": \"My Store\", \"items\": [{\"name\": \"Chair\", \"pri"
  },
  {
    "path": "docs/docs/03_first_rest_api/Insomnia_section3.json",
    "chars": 4395,
    "preview": "{\"_type\":\"export\",\"__export_format\":4,\"__export_date\":\"2022-11-09T15:36:47.360Z\",\"__export_source\":\"insomnia.desktop.app"
  },
  {
    "path": "docs/docs/03_first_rest_api/_category_.json",
    "chars": 58,
    "preview": "{\n    \"label\": \"Your First REST API\",\n    \"position\": 3\n}\n"
  },
  {
    "path": "docs/docs/04_docker_intro/01_what_is_docker_container/README.md",
    "chars": 9458,
    "preview": "---\nctslug: what-is-a-docker-container\ndescription: Learn what Docker images and containers are, and how we can use them"
  },
  {
    "path": "docs/docs/04_docker_intro/02_run_docker_container/README.md",
    "chars": 6420,
    "preview": "---\nctslug: how-to-run-a-docker-container\ndescription: Learn how to run a Docker container with your REST API using Dock"
  },
  {
    "path": "docs/docs/04_docker_intro/02_run_docker_container/end/Dockerfile",
    "chars": 114,
    "preview": "FROM python:3.10\nEXPOSE 5000\nWORKDIR /app\nRUN pip install flask\nCOPY . .\nCMD [\"flask\", \"run\", \"--host\", \"0.0.0.0\"]"
  },
  {
    "path": "docs/docs/04_docker_intro/02_run_docker_container/end/app.py",
    "chars": 1177,
    "preview": "from flask import Flask, request\n\napp = Flask(__name__)\n\nstores = [{\"name\": \"My Store\", \"items\": [{\"name\": \"Chair\", \"pri"
  },
  {
    "path": "docs/docs/04_docker_intro/02_run_docker_container/start/app.py",
    "chars": 1177,
    "preview": "from flask import Flask, request\n\napp = Flask(__name__)\n\nstores = [{\"name\": \"My Store\", \"items\": [{\"name\": \"Chair\", \"pri"
  },
  {
    "path": "docs/docs/04_docker_intro/03_in_depth_docker_tutorial/README.md",
    "chars": 10770,
    "preview": "---\nctslug: in-depth-docker-tutorial\ndescription: My notes from the official Docker tutorial.\n---\n\n# In-depth Docker Tut"
  },
  {
    "path": "docs/docs/04_docker_intro/04_run_with_docker_compose/README.md",
    "chars": 2615,
    "preview": "# Run the REST API using Docker Compose\n\nNow that we've got a Docker container for our REST API, we can set up Docker Co"
  },
  {
    "path": "docs/docs/04_docker_intro/04_run_with_docker_compose/end/Dockerfile",
    "chars": 114,
    "preview": "FROM python:3.10\nEXPOSE 5000\nWORKDIR /app\nRUN pip install flask\nCOPY . .\nCMD [\"flask\", \"run\", \"--host\", \"0.0.0.0\"]"
  },
  {
    "path": "docs/docs/04_docker_intro/04_run_with_docker_compose/end/app.py",
    "chars": 1177,
    "preview": "from flask import Flask, request\n\napp = Flask(__name__)\n\nstores = [{\"name\": \"My Store\", \"items\": [{\"name\": \"Chair\", \"pri"
  },
  {
    "path": "docs/docs/04_docker_intro/04_run_with_docker_compose/end/docker-compose.yml",
    "chars": 88,
    "preview": "services:\n  web:\n    build: .\n    ports:\n      - \"5000:5000\"\n    volumes:\n      - .:/app"
  },
  {
    "path": "docs/docs/04_docker_intro/04_run_with_docker_compose/start/Dockerfile",
    "chars": 114,
    "preview": "FROM python:3.10\nEXPOSE 5000\nWORKDIR /app\nRUN pip install flask\nCOPY . .\nCMD [\"flask\", \"run\", \"--host\", \"0.0.0.0\"]"
  },
  {
    "path": "docs/docs/04_docker_intro/04_run_with_docker_compose/start/app.py",
    "chars": 1177,
    "preview": "from flask import Flask, request\n\napp = Flask(__name__)\n\nstores = [{\"name\": \"My Store\", \"items\": [{\"name\": \"Chair\", \"pri"
  },
  {
    "path": "docs/docs/04_docker_intro/05_run_commands_in_docker_containers/README.md",
    "chars": 1104,
    "preview": "# How to run commands inside a Docker container\n\nIf you run your API using Docker Compose, with the `docker compose up` "
  },
  {
    "path": "docs/docs/04_docker_intro/README.md",
    "chars": 797,
    "preview": "# An Introduction to Docker\n\n:::caution Not a Docker course\nAn important foreword: this is not a Docker course, and I'm "
  },
  {
    "path": "docs/docs/04_docker_intro/_category_.json",
    "chars": 61,
    "preview": "{\n    \"label\": \"Introduction to Docker\",\n    \"position\": 4\n}\n"
  },
  {
    "path": "docs/docs/05_flask_smorest/01_why_flask_smorest/README.md",
    "chars": 4028,
    "preview": "---\nctslug: why-use-flask-smorest\n---\n\n# Why use Flask-Smorest\n\nThere are many different REST API libraries for Flask. I"
  },
  {
    "path": "docs/docs/05_flask_smorest/02_data_model_improvements/README.md",
    "chars": 8762,
    "preview": "---\ntitle: \"Data model improvements\"\ndescription: \"Use dictionaries instead of lists for data storage, and store stores "
  },
  {
    "path": "docs/docs/05_flask_smorest/02_data_model_improvements/end/.flaskenv",
    "chars": 30,
    "preview": "FLASK_APP=app\nFLASK_DEBUG=True"
  },
  {
    "path": "docs/docs/05_flask_smorest/02_data_model_improvements/end/Dockerfile",
    "chars": 179,
    "preview": "# In the course we run the app outside Docker\n# until lecture 5.\nFROM python:3.10\nEXPOSE 5000\nWORKDIR /app\nRUN pip insta"
  },
  {
    "path": "docs/docs/05_flask_smorest/02_data_model_improvements/end/app.py",
    "chars": 1212,
    "preview": "import uuid\nfrom flask import Flask, request\n\nfrom db import stores, items\n\n\napp = Flask(__name__)\n\n\n@app.get(\"/item/<st"
  },
  {
    "path": "docs/docs/05_flask_smorest/02_data_model_improvements/end/db.py",
    "chars": 251,
    "preview": "\"\"\"\ndb.py\n---\n\nLater on, this file will be replaced by SQLAlchemy. For now, it mimics a database.\nOur data storage is:\n "
  },
  {
    "path": "docs/docs/05_flask_smorest/02_data_model_improvements/end/requirements.txt",
    "chars": 33,
    "preview": "flask\nflask-smorest\npython-dotenv"
  },
  {
    "path": "docs/docs/05_flask_smorest/02_data_model_improvements/start/Dockerfile",
    "chars": 114,
    "preview": "FROM python:3.10\nEXPOSE 5000\nWORKDIR /app\nRUN pip install flask\nCOPY . .\nCMD [\"flask\", \"run\", \"--host\", \"0.0.0.0\"]"
  },
  {
    "path": "docs/docs/05_flask_smorest/02_data_model_improvements/start/app.py",
    "chars": 1208,
    "preview": "from flask import Flask, request\n\napp = Flask(__name__)\n\nstores = [{\"name\": \"My Store\", \"items\": [{\"name\": \"Chair\", \"pri"
  },
  {
    "path": "docs/docs/05_flask_smorest/03_improvements_on_first_rest_api/README.md",
    "chars": 3554,
    "preview": "---\ntitle: \"Improvements to our first REST API\"\ndescription: \"Add new error handling and code improvements to the REST A"
  },
  {
    "path": "docs/docs/05_flask_smorest/03_improvements_on_first_rest_api/end/.flaskenv",
    "chars": 30,
    "preview": "FLASK_APP=app\nFLASK_DEBUG=True"
  },
  {
    "path": "docs/docs/05_flask_smorest/03_improvements_on_first_rest_api/end/Dockerfile",
    "chars": 114,
    "preview": "FROM python:3.10\nEXPOSE 5000\nWORKDIR /app\nRUN pip install flask\nCOPY . .\nCMD [\"flask\", \"run\", \"--host\", \"0.0.0.0\"]"
  },
  {
    "path": "docs/docs/05_flask_smorest/03_improvements_on_first_rest_api/end/app.py",
    "chars": 2060,
    "preview": "import uuid\nfrom flask import Flask, request\nfrom flask_smorest import abort\n\nfrom db import stores, items\n\n\napp = Flask"
  },
  {
    "path": "docs/docs/05_flask_smorest/03_improvements_on_first_rest_api/end/db.py",
    "chars": 251,
    "preview": "\"\"\"\ndb.py\n---\n\nLater on, this file will be replaced by SQLAlchemy. For now, it mimics a database.\nOur data storage is:\n "
  },
  {
    "path": "docs/docs/05_flask_smorest/03_improvements_on_first_rest_api/end/requirements.txt",
    "chars": 33,
    "preview": "flask\nflask-smorest\npython-dotenv"
  },
  {
    "path": "docs/docs/05_flask_smorest/03_improvements_on_first_rest_api/start/.flaskenv",
    "chars": 30,
    "preview": "FLASK_APP=app\nFLASK_DEBUG=True"
  },
  {
    "path": "docs/docs/05_flask_smorest/03_improvements_on_first_rest_api/start/Dockerfile",
    "chars": 114,
    "preview": "FROM python:3.10\nEXPOSE 5000\nWORKDIR /app\nRUN pip install flask\nCOPY . .\nCMD [\"flask\", \"run\", \"--host\", \"0.0.0.0\"]"
  },
  {
    "path": "docs/docs/05_flask_smorest/03_improvements_on_first_rest_api/start/app.py",
    "chars": 1212,
    "preview": "import uuid\nfrom flask import Flask, request\n\nfrom db import stores, items\n\n\napp = Flask(__name__)\n\n\n@app.get(\"/item/<st"
  },
  {
    "path": "docs/docs/05_flask_smorest/03_improvements_on_first_rest_api/start/db.py",
    "chars": 251,
    "preview": "\"\"\"\ndb.py\n---\n\nLater on, this file will be replaced by SQLAlchemy. For now, it mimics a database.\nOur data storage is:\n "
  },
  {
    "path": "docs/docs/05_flask_smorest/03_improvements_on_first_rest_api/start/requirements.txt",
    "chars": 33,
    "preview": "flask\nflask-smorest\npython-dotenv"
  },
  {
    "path": "docs/docs/05_flask_smorest/04_new_endpoints_for_api/README.md",
    "chars": 2447,
    "preview": "---\ntitle: \"New endpoints for our REST API\"\ndescription: \"Let's add a few routes to our first REST API, so it better mat"
  },
  {
    "path": "docs/docs/05_flask_smorest/04_new_endpoints_for_api/end/.flaskenv",
    "chars": 30,
    "preview": "FLASK_APP=app\nFLASK_DEBUG=True"
  },
  {
    "path": "docs/docs/05_flask_smorest/04_new_endpoints_for_api/end/Dockerfile",
    "chars": 114,
    "preview": "FROM python:3.10\nEXPOSE 5000\nWORKDIR /app\nRUN pip install flask\nCOPY . .\nCMD [\"flask\", \"run\", \"--host\", \"0.0.0.0\"]"
  },
  {
    "path": "docs/docs/05_flask_smorest/04_new_endpoints_for_api/end/app.py",
    "chars": 3186,
    "preview": "import uuid\nfrom flask import Flask, request\nfrom flask_smorest import abort\n\nfrom db import stores, items\n\n\napp = Flask"
  },
  {
    "path": "docs/docs/05_flask_smorest/04_new_endpoints_for_api/end/db.py",
    "chars": 251,
    "preview": "\"\"\"\ndb.py\n---\n\nLater on, this file will be replaced by SQLAlchemy. For now, it mimics a database.\nOur data storage is:\n "
  },
  {
    "path": "docs/docs/05_flask_smorest/04_new_endpoints_for_api/end/requirements.txt",
    "chars": 33,
    "preview": "flask\nflask-smorest\npython-dotenv"
  },
  {
    "path": "docs/docs/05_flask_smorest/04_new_endpoints_for_api/start/.flaskenv",
    "chars": 30,
    "preview": "FLASK_APP=app\nFLASK_DEBUG=True"
  },
  {
    "path": "docs/docs/05_flask_smorest/04_new_endpoints_for_api/start/Dockerfile",
    "chars": 114,
    "preview": "FROM python:3.10\nEXPOSE 5000\nWORKDIR /app\nRUN pip install flask\nCOPY . .\nCMD [\"flask\", \"run\", \"--host\", \"0.0.0.0\"]"
  },
  {
    "path": "docs/docs/05_flask_smorest/04_new_endpoints_for_api/start/app.py",
    "chars": 2060,
    "preview": "import uuid\nfrom flask import Flask, request\nfrom flask_smorest import abort\n\nfrom db import stores, items\n\n\napp = Flask"
  },
  {
    "path": "docs/docs/05_flask_smorest/04_new_endpoints_for_api/start/db.py",
    "chars": 251,
    "preview": "\"\"\"\ndb.py\n---\n\nLater on, this file will be replaced by SQLAlchemy. For now, it mimics a database.\nOur data storage is:\n "
  },
  {
    "path": "docs/docs/05_flask_smorest/04_new_endpoints_for_api/start/requirements.txt",
    "chars": 33,
    "preview": "flask\nflask-smorest\npython-dotenv"
  },
  {
    "path": "docs/docs/05_flask_smorest/05_reload_api_docker_container/README.md",
    "chars": 5022,
    "preview": "---\ntitle: \"Reloading API code in Docker container\"\ndescription: \"Learn how to get your code instantly synced up to the "
  },
  {
    "path": "docs/docs/05_flask_smorest/05_reload_api_docker_container/end/.flaskenv",
    "chars": 30,
    "preview": "FLASK_APP=app\nFLASK_DEBUG=True"
  },
  {
    "path": "docs/docs/05_flask_smorest/05_reload_api_docker_container/end/Dockerfile",
    "chars": 194,
    "preview": "FROM python:3.10\nEXPOSE 5000\nWORKDIR /app\nCOPY ./requirements.txt requirements.txt\nRUN pip install --no-cache-dir --upgr"
  },
  {
    "path": "docs/docs/05_flask_smorest/05_reload_api_docker_container/end/app.py",
    "chars": 3186,
    "preview": "import uuid\nfrom flask import Flask, request\nfrom flask_smorest import abort\n\nfrom db import stores, items\n\n\napp = Flask"
  },
  {
    "path": "docs/docs/05_flask_smorest/05_reload_api_docker_container/end/db.py",
    "chars": 251,
    "preview": "\"\"\"\ndb.py\n---\n\nLater on, this file will be replaced by SQLAlchemy. For now, it mimics a database.\nOur data storage is:\n "
  },
  {
    "path": "docs/docs/05_flask_smorest/05_reload_api_docker_container/end/requirements.txt",
    "chars": 33,
    "preview": "flask\nflask-smorest\npython-dotenv"
  },
  {
    "path": "docs/docs/05_flask_smorest/05_reload_api_docker_container/start/.flaskenv",
    "chars": 30,
    "preview": "FLASK_APP=app\nFLASK_DEBUG=True"
  },
  {
    "path": "docs/docs/05_flask_smorest/05_reload_api_docker_container/start/Dockerfile",
    "chars": 114,
    "preview": "FROM python:3.10\nEXPOSE 5000\nWORKDIR /app\nRUN pip install flask\nCOPY . .\nCMD [\"flask\", \"run\", \"--host\", \"0.0.0.0\"]"
  },
  {
    "path": "docs/docs/05_flask_smorest/05_reload_api_docker_container/start/app.py",
    "chars": 3186,
    "preview": "import uuid\nfrom flask import Flask, request\nfrom flask_smorest import abort\n\nfrom db import stores, items\n\n\napp = Flask"
  },
  {
    "path": "docs/docs/05_flask_smorest/05_reload_api_docker_container/start/db.py",
    "chars": 251,
    "preview": "\"\"\"\ndb.py\n---\n\nLater on, this file will be replaced by SQLAlchemy. For now, it mimics a database.\nOur data storage is:\n "
  },
  {
    "path": "docs/docs/05_flask_smorest/05_reload_api_docker_container/start/requirements.txt",
    "chars": 33,
    "preview": "flask\nflask-smorest\npython-dotenv"
  },
  {
    "path": "docs/docs/05_flask_smorest/06_api_with_method_views/README.md",
    "chars": 7200,
    "preview": "---\ntitle: How to use Blueprints and MethodViews\ndescription: Flask-Smorest MethodViews allow us to simplify API Resourc"
  },
  {
    "path": "docs/docs/05_flask_smorest/06_api_with_method_views/end/.flaskenv",
    "chars": 30,
    "preview": "FLASK_APP=app\nFLASK_DEBUG=True"
  },
  {
    "path": "docs/docs/05_flask_smorest/06_api_with_method_views/end/Dockerfile",
    "chars": 194,
    "preview": "FROM python:3.10\nEXPOSE 5000\nWORKDIR /app\nCOPY ./requirements.txt requirements.txt\nRUN pip install --no-cache-dir --upgr"
  },
  {
    "path": "docs/docs/05_flask_smorest/06_api_with_method_views/end/app.py",
    "chars": 611,
    "preview": "from flask import Flask\nfrom flask_smorest import Api\n\nfrom resources.item import blp as ItemBlueprint\nfrom resources.st"
  },
  {
    "path": "docs/docs/05_flask_smorest/06_api_with_method_views/end/db.py",
    "chars": 251,
    "preview": "\"\"\"\ndb.py\n---\n\nLater on, this file will be replaced by SQLAlchemy. For now, it mimics a database.\nOur data storage is:\n "
  },
  {
    "path": "docs/docs/05_flask_smorest/06_api_with_method_views/end/requirements.txt",
    "chars": 33,
    "preview": "flask\nflask-smorest\npython-dotenv"
  },
  {
    "path": "docs/docs/05_flask_smorest/06_api_with_method_views/end/resources/__init__.py",
    "chars": 1,
    "preview": "\n"
  },
  {
    "path": "docs/docs/05_flask_smorest/06_api_with_method_views/end/resources/item.py",
    "chars": 2343,
    "preview": "import uuid\nfrom flask import request\nfrom flask.views import MethodView\nfrom flask_smorest import Blueprint, abort\n\nfro"
  },
  {
    "path": "docs/docs/05_flask_smorest/06_api_with_method_views/end/resources/store.py",
    "chars": 1416,
    "preview": "import uuid\nfrom flask import request\nfrom flask.views import MethodView\nfrom flask_smorest import Blueprint, abort\nfrom"
  },
  {
    "path": "docs/docs/05_flask_smorest/06_api_with_method_views/start/.flaskenv",
    "chars": 30,
    "preview": "FLASK_APP=app\nFLASK_DEBUG=True"
  },
  {
    "path": "docs/docs/05_flask_smorest/06_api_with_method_views/start/Dockerfile",
    "chars": 194,
    "preview": "FROM python:3.10\nEXPOSE 5000\nWORKDIR /app\nCOPY ./requirements.txt requirements.txt\nRUN pip install --no-cache-dir --upgr"
  },
  {
    "path": "docs/docs/05_flask_smorest/06_api_with_method_views/start/app.py",
    "chars": 3169,
    "preview": "import uuid\nfrom flask import Flask, request\nfrom flask_smorest import abort\n\nfrom db import stores, items\n\n\napp = Flask"
  },
  {
    "path": "docs/docs/05_flask_smorest/06_api_with_method_views/start/db.py",
    "chars": 251,
    "preview": "\"\"\"\ndb.py\n---\n\nLater on, this file will be replaced by SQLAlchemy. For now, it mimics a database.\nOur data storage is:\n "
  },
  {
    "path": "docs/docs/05_flask_smorest/06_api_with_method_views/start/requirements.txt",
    "chars": 19,
    "preview": "flask\npython-dotenv"
  },
  {
    "path": "docs/docs/05_flask_smorest/07_marshmallow_schemas/README.md",
    "chars": 3485,
    "preview": "---\ntitle: Adding marshmallow schemas\ndescription: A marshmallow schema is useful for validation and serialization. Lear"
  },
  {
    "path": "docs/docs/05_flask_smorest/07_marshmallow_schemas/end/.flaskenv",
    "chars": 30,
    "preview": "FLASK_APP=app\nFLASK_DEBUG=True"
  },
  {
    "path": "docs/docs/05_flask_smorest/07_marshmallow_schemas/end/Dockerfile",
    "chars": 194,
    "preview": "FROM python:3.10\nEXPOSE 5000\nWORKDIR /app\nCOPY ./requirements.txt requirements.txt\nRUN pip install --no-cache-dir --upgr"
  },
  {
    "path": "docs/docs/05_flask_smorest/07_marshmallow_schemas/end/app.py",
    "chars": 611,
    "preview": "from flask import Flask\nfrom flask_smorest import Api\n\nfrom resources.item import blp as ItemBlueprint\nfrom resources.st"
  },
  {
    "path": "docs/docs/05_flask_smorest/07_marshmallow_schemas/end/db.py",
    "chars": 251,
    "preview": "\"\"\"\ndb.py\n---\n\nLater on, this file will be replaced by SQLAlchemy. For now, it mimics a database.\nOur data storage is:\n "
  },
  {
    "path": "docs/docs/05_flask_smorest/07_marshmallow_schemas/end/requirements.txt",
    "chars": 45,
    "preview": "flask\nflask-smorest\npython-dotenv\nmarshmallow"
  },
  {
    "path": "docs/docs/05_flask_smorest/07_marshmallow_schemas/end/resources/__init__.py",
    "chars": 1,
    "preview": "\n"
  },
  {
    "path": "docs/docs/05_flask_smorest/07_marshmallow_schemas/end/resources/item.py",
    "chars": 2343,
    "preview": "import uuid\nfrom flask import request\nfrom flask.views import MethodView\nfrom flask_smorest import Blueprint, abort\n\nfro"
  },
  {
    "path": "docs/docs/05_flask_smorest/07_marshmallow_schemas/end/resources/store.py",
    "chars": 1412,
    "preview": "import uuid\nfrom flask import request\nfrom flask.views import MethodView\nfrom flask_smorest import Blueprint, abort\nfrom"
  },
  {
    "path": "docs/docs/05_flask_smorest/07_marshmallow_schemas/end/schemas.py",
    "chars": 408,
    "preview": "from marshmallow import Schema, fields\n\n\nclass ItemSchema(Schema):\n    id = fields.Str(dump_only=True)\n    name = fields"
  },
  {
    "path": "docs/docs/05_flask_smorest/07_marshmallow_schemas/start/.flaskenv",
    "chars": 30,
    "preview": "FLASK_APP=app\nFLASK_DEBUG=True"
  },
  {
    "path": "docs/docs/05_flask_smorest/07_marshmallow_schemas/start/Dockerfile",
    "chars": 194,
    "preview": "FROM python:3.10\nEXPOSE 5000\nWORKDIR /app\nCOPY ./requirements.txt requirements.txt\nRUN pip install --no-cache-dir --upgr"
  },
  {
    "path": "docs/docs/05_flask_smorest/07_marshmallow_schemas/start/app.py",
    "chars": 611,
    "preview": "from flask import Flask\nfrom flask_smorest import Api\n\nfrom resources.item import blp as ItemBlueprint\nfrom resources.st"
  },
  {
    "path": "docs/docs/05_flask_smorest/07_marshmallow_schemas/start/db.py",
    "chars": 251,
    "preview": "\"\"\"\ndb.py\n---\n\nLater on, this file will be replaced by SQLAlchemy. For now, it mimics a database.\nOur data storage is:\n "
  },
  {
    "path": "docs/docs/05_flask_smorest/07_marshmallow_schemas/start/requirements.txt",
    "chars": 33,
    "preview": "flask\nflask-smorest\npython-dotenv"
  },
  {
    "path": "docs/docs/05_flask_smorest/07_marshmallow_schemas/start/resources/__init__.py",
    "chars": 1,
    "preview": "\n"
  },
  {
    "path": "docs/docs/05_flask_smorest/07_marshmallow_schemas/start/resources/item.py",
    "chars": 2343,
    "preview": "import uuid\nfrom flask import request\nfrom flask.views import MethodView\nfrom flask_smorest import Blueprint, abort\n\nfro"
  },
  {
    "path": "docs/docs/05_flask_smorest/07_marshmallow_schemas/start/resources/store.py",
    "chars": 1412,
    "preview": "import uuid\nfrom flask import request\nfrom flask.views import MethodView\nfrom flask_smorest import Blueprint, abort\nfrom"
  },
  {
    "path": "docs/docs/05_flask_smorest/08_validation_with_marshmallow/README.md",
    "chars": 3367,
    "preview": "---\ntitle: Validation with marshmallow\ndescription: We can use the marshmallow library to validate request data from our"
  },
  {
    "path": "docs/docs/05_flask_smorest/08_validation_with_marshmallow/end/.flaskenv",
    "chars": 30,
    "preview": "FLASK_APP=app\nFLASK_DEBUG=True"
  },
  {
    "path": "docs/docs/05_flask_smorest/08_validation_with_marshmallow/end/Dockerfile",
    "chars": 194,
    "preview": "FROM python:3.10\nEXPOSE 5000\nWORKDIR /app\nCOPY ./requirements.txt requirements.txt\nRUN pip install --no-cache-dir --upgr"
  },
  {
    "path": "docs/docs/05_flask_smorest/08_validation_with_marshmallow/end/app.py",
    "chars": 611,
    "preview": "from flask import Flask\nfrom flask_smorest import Api\n\nfrom resources.item import blp as ItemBlueprint\nfrom resources.st"
  },
  {
    "path": "docs/docs/05_flask_smorest/08_validation_with_marshmallow/end/db.py",
    "chars": 251,
    "preview": "\"\"\"\ndb.py\n---\n\nLater on, this file will be replaced by SQLAlchemy. For now, it mimics a database.\nOur data storage is:\n "
  },
  {
    "path": "docs/docs/05_flask_smorest/08_validation_with_marshmallow/end/requirements.txt",
    "chars": 45,
    "preview": "flask\nflask-smorest\npython-dotenv\nmarshmallow"
  },
  {
    "path": "docs/docs/05_flask_smorest/08_validation_with_marshmallow/end/resources/__init__.py",
    "chars": 1,
    "preview": "\n"
  },
  {
    "path": "docs/docs/05_flask_smorest/08_validation_with_marshmallow/end/resources/item.py",
    "chars": 1530,
    "preview": "import uuid\nfrom flask.views import MethodView\nfrom flask_smorest import Blueprint, abort\n\nfrom schemas import ItemSchem"
  },
  {
    "path": "docs/docs/05_flask_smorest/08_validation_with_marshmallow/end/resources/store.py",
    "chars": 1244,
    "preview": "import uuid\nfrom flask.views import MethodView\nfrom flask_smorest import Blueprint, abort\nfrom db import stores\nfrom sch"
  },
  {
    "path": "docs/docs/05_flask_smorest/08_validation_with_marshmallow/end/schemas.py",
    "chars": 408,
    "preview": "from marshmallow import Schema, fields\n\n\nclass ItemSchema(Schema):\n    id = fields.Str(dump_only=True)\n    name = fields"
  },
  {
    "path": "docs/docs/05_flask_smorest/08_validation_with_marshmallow/start/.flaskenv",
    "chars": 30,
    "preview": "FLASK_APP=app\nFLASK_DEBUG=True"
  },
  {
    "path": "docs/docs/05_flask_smorest/08_validation_with_marshmallow/start/Dockerfile",
    "chars": 194,
    "preview": "FROM python:3.10\nEXPOSE 5000\nWORKDIR /app\nCOPY ./requirements.txt requirements.txt\nRUN pip install --no-cache-dir --upgr"
  },
  {
    "path": "docs/docs/05_flask_smorest/08_validation_with_marshmallow/start/app.py",
    "chars": 611,
    "preview": "from flask import Flask\nfrom flask_smorest import Api\n\nfrom resources.item import blp as ItemBlueprint\nfrom resources.st"
  },
  {
    "path": "docs/docs/05_flask_smorest/08_validation_with_marshmallow/start/db.py",
    "chars": 251,
    "preview": "\"\"\"\ndb.py\n---\n\nLater on, this file will be replaced by SQLAlchemy. For now, it mimics a database.\nOur data storage is:\n "
  },
  {
    "path": "docs/docs/05_flask_smorest/08_validation_with_marshmallow/start/requirements.txt",
    "chars": 45,
    "preview": "flask\nflask-smorest\npython-dotenv\nmarshmallow"
  },
  {
    "path": "docs/docs/05_flask_smorest/08_validation_with_marshmallow/start/resources/__init__.py",
    "chars": 1,
    "preview": "\n"
  },
  {
    "path": "docs/docs/05_flask_smorest/08_validation_with_marshmallow/start/resources/item.py",
    "chars": 2343,
    "preview": "import uuid\nfrom flask import request\nfrom flask.views import MethodView\nfrom flask_smorest import Blueprint, abort\n\nfro"
  },
  {
    "path": "docs/docs/05_flask_smorest/08_validation_with_marshmallow/start/resources/store.py",
    "chars": 1412,
    "preview": "import uuid\nfrom flask import request\nfrom flask.views import MethodView\nfrom flask_smorest import Blueprint, abort\nfrom"
  },
  {
    "path": "docs/docs/05_flask_smorest/08_validation_with_marshmallow/start/schemas.py",
    "chars": 408,
    "preview": "from marshmallow import Schema, fields\n\n\nclass ItemSchema(Schema):\n    id = fields.Str(dump_only=True)\n    name = fields"
  },
  {
    "path": "docs/docs/05_flask_smorest/09_decorating_responses/README.md",
    "chars": 4398,
    "preview": "---\ntitle: Decorating responses with Flask-Smorest\ndescription: Add response serialization and status code to API endpoi"
  },
  {
    "path": "docs/docs/05_flask_smorest/09_decorating_responses/end/.flaskenv",
    "chars": 30,
    "preview": "FLASK_APP=app\nFLASK_DEBUG=True"
  },
  {
    "path": "docs/docs/05_flask_smorest/09_decorating_responses/end/Dockerfile",
    "chars": 194,
    "preview": "FROM python:3.10\nEXPOSE 5000\nWORKDIR /app\nCOPY ./requirements.txt requirements.txt\nRUN pip install --no-cache-dir --upgr"
  },
  {
    "path": "docs/docs/05_flask_smorest/09_decorating_responses/end/app.py",
    "chars": 611,
    "preview": "from flask import Flask\nfrom flask_smorest import Api\n\nfrom resources.item import blp as ItemBlueprint\nfrom resources.st"
  },
  {
    "path": "docs/docs/05_flask_smorest/09_decorating_responses/end/db.py",
    "chars": 251,
    "preview": "\"\"\"\ndb.py\n---\n\nLater on, this file will be replaced by SQLAlchemy. For now, it mimics a database.\nOur data storage is:\n "
  },
  {
    "path": "docs/docs/05_flask_smorest/09_decorating_responses/end/requirements.txt",
    "chars": 45,
    "preview": "flask\nflask-smorest\npython-dotenv\nmarshmallow"
  },
  {
    "path": "docs/docs/05_flask_smorest/09_decorating_responses/end/resources/__init__.py",
    "chars": 1,
    "preview": "\n"
  },
  {
    "path": "docs/docs/05_flask_smorest/09_decorating_responses/end/resources/item.py",
    "chars": 1664,
    "preview": "import uuid\nfrom flask.views import MethodView\nfrom flask_smorest import Blueprint, abort\n\nfrom schemas import ItemSchem"
  },
  {
    "path": "docs/docs/05_flask_smorest/09_decorating_responses/end/resources/store.py",
    "chars": 1345,
    "preview": "import uuid\nfrom flask.views import MethodView\nfrom flask_smorest import Blueprint, abort\nfrom db import stores\nfrom sch"
  },
  {
    "path": "docs/docs/05_flask_smorest/09_decorating_responses/end/schemas.py",
    "chars": 408,
    "preview": "from marshmallow import Schema, fields\n\n\nclass ItemSchema(Schema):\n    id = fields.Str(dump_only=True)\n    name = fields"
  },
  {
    "path": "docs/docs/05_flask_smorest/09_decorating_responses/start/.flaskenv",
    "chars": 30,
    "preview": "FLASK_APP=app\nFLASK_DEBUG=True"
  },
  {
    "path": "docs/docs/05_flask_smorest/09_decorating_responses/start/Dockerfile",
    "chars": 194,
    "preview": "FROM python:3.10\nEXPOSE 5000\nWORKDIR /app\nCOPY ./requirements.txt requirements.txt\nRUN pip install --no-cache-dir --upgr"
  },
  {
    "path": "docs/docs/05_flask_smorest/09_decorating_responses/start/app.py",
    "chars": 611,
    "preview": "from flask import Flask\nfrom flask_smorest import Api\n\nfrom resources.item import blp as ItemBlueprint\nfrom resources.st"
  },
  {
    "path": "docs/docs/05_flask_smorest/09_decorating_responses/start/db.py",
    "chars": 251,
    "preview": "\"\"\"\ndb.py\n---\n\nLater on, this file will be replaced by SQLAlchemy. For now, it mimics a database.\nOur data storage is:\n "
  },
  {
    "path": "docs/docs/05_flask_smorest/09_decorating_responses/start/requirements.txt",
    "chars": 45,
    "preview": "flask\nflask-smorest\npython-dotenv\nmarshmallow"
  },
  {
    "path": "docs/docs/05_flask_smorest/09_decorating_responses/start/resources/__init__.py",
    "chars": 1,
    "preview": "\n"
  },
  {
    "path": "docs/docs/05_flask_smorest/09_decorating_responses/start/resources/item.py",
    "chars": 1530,
    "preview": "import uuid\nfrom flask.views import MethodView\nfrom flask_smorest import Blueprint, abort\n\nfrom schemas import ItemSchem"
  },
  {
    "path": "docs/docs/05_flask_smorest/09_decorating_responses/start/resources/store.py",
    "chars": 1244,
    "preview": "import uuid\nfrom flask.views import MethodView\nfrom flask_smorest import Blueprint, abort\nfrom db import stores\nfrom sch"
  },
  {
    "path": "docs/docs/05_flask_smorest/09_decorating_responses/start/schemas.py",
    "chars": 408,
    "preview": "from marshmallow import Schema, fields\n\n\nclass ItemSchema(Schema):\n    id = fields.Str(dump_only=True)\n    name = fields"
  },
  {
    "path": "docs/docs/05_flask_smorest/Insomnia_section5_Docker.json",
    "chars": 6956,
    "preview": "{\"_type\":\"export\",\"__export_format\":4,\"__export_date\":\"2022-11-09T15:36:20.139Z\",\"__export_source\":\"insomnia.desktop.app"
  },
  {
    "path": "docs/docs/05_flask_smorest/Insomnia_section5_before_Docker.json",
    "chars": 7042,
    "preview": "{\"_type\":\"export\",\"__export_format\":4,\"__export_date\":\"2022-11-09T15:35:47.649Z\",\"__export_source\":\"insomnia.desktop.app"
  },
  {
    "path": "docs/docs/05_flask_smorest/_category_.json",
    "chars": 83,
    "preview": "{\n    \"label\": \"Flask-Smorest for More Efficient Development\",\n    \"position\": 5\n}\n"
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/01_project_overview_sqlalchemy/README.md",
    "chars": 2394,
    "preview": "---\ntitle: Project Overview, and why use SQLAlchemy\ndescription: Let's look at what we'll do in this section. There are "
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/02_create_simple_sqlalchemy_model/README.md",
    "chars": 1342,
    "preview": "---\ntitle: Create a simple SQLAlchemy Model\ndescription: Lecture description goes here.\nctslug: create-a-simple-sqlalche"
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/02_create_simple_sqlalchemy_model/end/.flaskenv",
    "chars": 30,
    "preview": "FLASK_APP=app\nFLASK_DEBUG=True"
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/02_create_simple_sqlalchemy_model/end/Dockerfile",
    "chars": 194,
    "preview": "FROM python:3.10\nEXPOSE 5000\nWORKDIR /app\nCOPY ./requirements.txt requirements.txt\nRUN pip install --no-cache-dir --upgr"
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/02_create_simple_sqlalchemy_model/end/app.py",
    "chars": 611,
    "preview": "from flask import Flask\nfrom flask_smorest import Api\n\nfrom resources.item import blp as ItemBlueprint\nfrom resources.st"
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/02_create_simple_sqlalchemy_model/end/db.py",
    "chars": 59,
    "preview": "from flask_sqlalchemy import SQLAlchemy\n\ndb = SQLAlchemy()\n"
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/02_create_simple_sqlalchemy_model/end/models/__init__.py",
    "chars": 70,
    "preview": "from models.item import ItemModel\nfrom models.store import StoreModel\n"
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/02_create_simple_sqlalchemy_model/end/models/item.py",
    "chars": 333,
    "preview": "from db import db\n\n\nclass ItemModel(db.Model):\n    __tablename__ = \"items\"\n\n    id = db.Column(db.Integer, primary_key=T"
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/02_create_simple_sqlalchemy_model/end/models/store.py",
    "chars": 192,
    "preview": "from db import db\n\n\nclass StoreModel(db.Model):\n    __tablename__ = \"stores\"\n\n    id = db.Column(db.Integer, primary_key"
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/02_create_simple_sqlalchemy_model/end/requirements.txt",
    "chars": 62,
    "preview": "flask\nflask-sqlalchemy\nflask-smorest\npython-dotenv\nmarshmallow"
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/02_create_simple_sqlalchemy_model/end/resources/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/02_create_simple_sqlalchemy_model/end/resources/item.py",
    "chars": 1138,
    "preview": "from flask.views import MethodView\nfrom flask_smorest import Blueprint, abort\nfrom sqlalchemy.exc import SQLAlchemyError"
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/02_create_simple_sqlalchemy_model/end/resources/store.py",
    "chars": 979,
    "preview": "from flask.views import MethodView\nfrom flask_smorest import Blueprint, abort\nfrom sqlalchemy.exc import SQLAlchemyError"
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/02_create_simple_sqlalchemy_model/end/schemas.py",
    "chars": 408,
    "preview": "from marshmallow import Schema, fields\n\n\nclass ItemSchema(Schema):\n    id = fields.Str(dump_only=True)\n    name = fields"
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/02_create_simple_sqlalchemy_model/start/.flaskenv",
    "chars": 30,
    "preview": "FLASK_APP=app\nFLASK_DEBUG=True"
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/02_create_simple_sqlalchemy_model/start/Dockerfile",
    "chars": 194,
    "preview": "FROM python:3.10\nEXPOSE 5000\nWORKDIR /app\nCOPY ./requirements.txt requirements.txt\nRUN pip install --no-cache-dir --upgr"
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/02_create_simple_sqlalchemy_model/start/app.py",
    "chars": 611,
    "preview": "from flask import Flask\nfrom flask_smorest import Api\n\nfrom resources.item import blp as ItemBlueprint\nfrom resources.st"
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/02_create_simple_sqlalchemy_model/start/db.py",
    "chars": 59,
    "preview": "from flask_sqlalchemy import SQLAlchemy\n\ndb = SQLAlchemy()\n"
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/02_create_simple_sqlalchemy_model/start/requirements.txt",
    "chars": 45,
    "preview": "flask\nflask-smorest\npython-dotenv\nmarshmallow"
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/02_create_simple_sqlalchemy_model/start/resources/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/02_create_simple_sqlalchemy_model/start/resources/item.py",
    "chars": 1138,
    "preview": "from flask.views import MethodView\nfrom flask_smorest import Blueprint, abort\nfrom sqlalchemy.exc import SQLAlchemyError"
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/02_create_simple_sqlalchemy_model/start/resources/store.py",
    "chars": 979,
    "preview": "from flask.views import MethodView\nfrom flask_smorest import Blueprint, abort\nfrom sqlalchemy.exc import SQLAlchemyError"
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/02_create_simple_sqlalchemy_model/start/schemas.py",
    "chars": 408,
    "preview": "from marshmallow import Schema, fields\n\n\nclass ItemSchema(Schema):\n    id = fields.Str(dump_only=True)\n    name = fields"
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/03_one_to_many_relationships_sqlalchemy/README.md",
    "chars": 3719,
    "preview": "---\ntitle: One-to-many relationships with SQLAlchemy\ndescription: Model relationships let us easily retrieve information"
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/03_one_to_many_relationships_sqlalchemy/end/.flaskenv",
    "chars": 30,
    "preview": "FLASK_APP=app\nFLASK_DEBUG=True"
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/03_one_to_many_relationships_sqlalchemy/end/Dockerfile",
    "chars": 194,
    "preview": "FROM python:3.10\nEXPOSE 5000\nWORKDIR /app\nCOPY ./requirements.txt requirements.txt\nRUN pip install --no-cache-dir --upgr"
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/03_one_to_many_relationships_sqlalchemy/end/app.py",
    "chars": 611,
    "preview": "from flask import Flask\nfrom flask_smorest import Api\n\nfrom resources.item import blp as ItemBlueprint\nfrom resources.st"
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/03_one_to_many_relationships_sqlalchemy/end/db.py",
    "chars": 59,
    "preview": "from flask_sqlalchemy import SQLAlchemy\n\ndb = SQLAlchemy()\n"
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/03_one_to_many_relationships_sqlalchemy/end/models/__init__.py",
    "chars": 70,
    "preview": "from models.item import ItemModel\nfrom models.store import StoreModel\n"
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/03_one_to_many_relationships_sqlalchemy/end/models/item.py",
    "chars": 442,
    "preview": "from db import db\n\n\nclass ItemModel(db.Model):\n    __tablename__ = \"items\"\n\n    id = db.Column(db.Integer, primary_key=T"
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/03_one_to_many_relationships_sqlalchemy/end/models/store.py",
    "chars": 274,
    "preview": "from db import db\n\n\nclass StoreModel(db.Model):\n    __tablename__ = \"stores\"\n\n    id = db.Column(db.Integer, primary_key"
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/03_one_to_many_relationships_sqlalchemy/end/requirements.txt",
    "chars": 62,
    "preview": "flask\nflask-sqlalchemy\nflask-smorest\npython-dotenv\nmarshmallow"
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/03_one_to_many_relationships_sqlalchemy/end/resources/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/03_one_to_many_relationships_sqlalchemy/end/resources/item.py",
    "chars": 1138,
    "preview": "from flask.views import MethodView\nfrom flask_smorest import Blueprint, abort\nfrom sqlalchemy.exc import SQLAlchemyError"
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/03_one_to_many_relationships_sqlalchemy/end/resources/store.py",
    "chars": 979,
    "preview": "from flask.views import MethodView\nfrom flask_smorest import Blueprint, abort\nfrom sqlalchemy.exc import SQLAlchemyError"
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/03_one_to_many_relationships_sqlalchemy/end/schemas.py",
    "chars": 633,
    "preview": "from marshmallow import Schema, fields\n\n\nclass PlainItemSchema(Schema):\n    id = fields.Int(dump_only=True)\n    name = f"
  },
  {
    "path": "docs/docs/06_sql_storage_sqlalchemy/03_one_to_many_relationships_sqlalchemy/start/.flaskenv",
    "chars": 30,
    "preview": "FLASK_APP=app\nFLASK_DEBUG=True"
  }
]

// ... and 1394 more files (download for full content)

About this extraction

This page contains the full source code of the tecladocode/rest-api-sections GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1594 files (19.0 MB), approximately 568.9k tokens, and a symbol index with 3696 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!