├── .env.example
├── .github
└── workflows
│ ├── python-app.yml
│ └── static.yml
├── .gitignore
├── .pre-commit-config.yaml
├── .vscode
└── settings.json
├── LICENSE
├── README.md
├── alembic.ini
├── alembic
├── README
├── env.py
├── script.py.mako
└── versions
│ └── 0ca47c9b66bd_adding_professionsdbmodel.py
├── cli_memory_process_handler.py
├── configs
├── __init__.py
└── config.py
├── docs
├── Makefile
├── build
│ ├── doctrees
│ │ ├── cli_memory_process_handler.doctree
│ │ ├── configs.doctree
│ │ ├── environment.pickle
│ │ ├── flask_memory_process_handler.doctree
│ │ ├── flask_postgresql_process_handler.doctree
│ │ ├── index.doctree
│ │ ├── modules.doctree
│ │ ├── src.app.cli_memory.controllers.doctree
│ │ ├── src.app.cli_memory.doctree
│ │ ├── src.app.cli_memory.presenters.doctree
│ │ ├── src.app.cli_memory.views.doctree
│ │ ├── src.app.doctree
│ │ ├── src.app.flask_memory.blueprints.doctree
│ │ ├── src.app.flask_memory.controllers.doctree
│ │ ├── src.app.flask_memory.doctree
│ │ ├── src.app.flask_memory.interfaces.doctree
│ │ ├── src.app.flask_memory.presenters.doctree
│ │ ├── src.app.flask_postgresql.blueprints.doctree
│ │ ├── src.app.flask_postgresql.controllers.doctree
│ │ ├── src.app.flask_postgresql.doctree
│ │ ├── src.app.flask_postgresql.interfaces.doctree
│ │ ├── src.app.flask_postgresql.presenters.doctree
│ │ ├── src.doctree
│ │ ├── src.domain.doctree
│ │ ├── src.domain.entities.doctree
│ │ ├── src.infra.db_models.doctree
│ │ ├── src.infra.doctree
│ │ ├── src.infra.repositories.doctree
│ │ ├── src.interactor.doctree
│ │ ├── src.interactor.dtos.doctree
│ │ ├── src.interactor.errors.doctree
│ │ ├── src.interactor.interfaces.doctree
│ │ ├── src.interactor.interfaces.logger.doctree
│ │ ├── src.interactor.interfaces.presenters.doctree
│ │ ├── src.interactor.interfaces.repositories.doctree
│ │ ├── src.interactor.use_cases.doctree
│ │ └── src.interactor.validations.doctree
│ └── html
│ │ ├── .buildinfo
│ │ ├── _sources
│ │ ├── cli_memory_process_handler.rst.txt
│ │ ├── configs.rst.txt
│ │ ├── flask_memory_process_handler.rst.txt
│ │ ├── flask_postgresql_process_handler.rst.txt
│ │ ├── index.rst.txt
│ │ ├── modules.rst.txt
│ │ ├── src.app.cli_memory.controllers.rst.txt
│ │ ├── src.app.cli_memory.presenters.rst.txt
│ │ ├── src.app.cli_memory.rst.txt
│ │ ├── src.app.cli_memory.views.rst.txt
│ │ ├── src.app.flask_memory.blueprints.rst.txt
│ │ ├── src.app.flask_memory.controllers.rst.txt
│ │ ├── src.app.flask_memory.interfaces.rst.txt
│ │ ├── src.app.flask_memory.presenters.rst.txt
│ │ ├── src.app.flask_memory.rst.txt
│ │ ├── src.app.flask_postgresql.blueprints.rst.txt
│ │ ├── src.app.flask_postgresql.controllers.rst.txt
│ │ ├── src.app.flask_postgresql.interfaces.rst.txt
│ │ ├── src.app.flask_postgresql.presenters.rst.txt
│ │ ├── src.app.flask_postgresql.rst.txt
│ │ ├── src.app.rst.txt
│ │ ├── src.domain.entities.rst.txt
│ │ ├── src.domain.rst.txt
│ │ ├── src.infra.db_models.rst.txt
│ │ ├── src.infra.repositories.rst.txt
│ │ ├── src.infra.rst.txt
│ │ ├── src.interactor.dtos.rst.txt
│ │ ├── src.interactor.errors.rst.txt
│ │ ├── src.interactor.interfaces.logger.rst.txt
│ │ ├── src.interactor.interfaces.presenters.rst.txt
│ │ ├── src.interactor.interfaces.repositories.rst.txt
│ │ ├── src.interactor.interfaces.rst.txt
│ │ ├── src.interactor.rst.txt
│ │ ├── src.interactor.use_cases.rst.txt
│ │ ├── src.interactor.validations.rst.txt
│ │ └── src.rst.txt
│ │ ├── _static
│ │ ├── _sphinx_javascript_frameworks_compat.js
│ │ ├── basic.css
│ │ ├── css
│ │ │ ├── badge_only.css
│ │ │ ├── fonts
│ │ │ │ ├── Roboto-Slab-Bold.woff
│ │ │ │ ├── Roboto-Slab-Bold.woff2
│ │ │ │ ├── Roboto-Slab-Regular.woff
│ │ │ │ ├── Roboto-Slab-Regular.woff2
│ │ │ │ ├── fontawesome-webfont.eot
│ │ │ │ ├── fontawesome-webfont.svg
│ │ │ │ ├── fontawesome-webfont.ttf
│ │ │ │ ├── fontawesome-webfont.woff
│ │ │ │ ├── fontawesome-webfont.woff2
│ │ │ │ ├── lato-bold-italic.woff
│ │ │ │ ├── lato-bold-italic.woff2
│ │ │ │ ├── lato-bold.woff
│ │ │ │ ├── lato-bold.woff2
│ │ │ │ ├── lato-normal-italic.woff
│ │ │ │ ├── lato-normal-italic.woff2
│ │ │ │ ├── lato-normal.woff
│ │ │ │ └── lato-normal.woff2
│ │ │ └── theme.css
│ │ ├── doctools.js
│ │ ├── documentation_options.js
│ │ ├── file.png
│ │ ├── jquery.js
│ │ ├── js
│ │ │ ├── badge_only.js
│ │ │ ├── html5shiv-printshiv.min.js
│ │ │ ├── html5shiv.min.js
│ │ │ └── theme.js
│ │ ├── language_data.js
│ │ ├── minus.png
│ │ ├── plus.png
│ │ ├── pygments.css
│ │ ├── searchtools.js
│ │ └── sphinx_highlight.js
│ │ ├── cli_memory_process_handler.html
│ │ ├── configs.html
│ │ ├── flask_memory_process_handler.html
│ │ ├── flask_postgresql_process_handler.html
│ │ ├── genindex.html
│ │ ├── index.html
│ │ ├── modules.html
│ │ ├── objects.inv
│ │ ├── py-modindex.html
│ │ ├── search.html
│ │ ├── searchindex.js
│ │ ├── src.app.cli_memory.controllers.html
│ │ ├── src.app.cli_memory.html
│ │ ├── src.app.cli_memory.presenters.html
│ │ ├── src.app.cli_memory.views.html
│ │ ├── src.app.flask_memory.blueprints.html
│ │ ├── src.app.flask_memory.controllers.html
│ │ ├── src.app.flask_memory.html
│ │ ├── src.app.flask_memory.interfaces.html
│ │ ├── src.app.flask_memory.presenters.html
│ │ ├── src.app.flask_postgresql.blueprints.html
│ │ ├── src.app.flask_postgresql.controllers.html
│ │ ├── src.app.flask_postgresql.html
│ │ ├── src.app.flask_postgresql.interfaces.html
│ │ ├── src.app.flask_postgresql.presenters.html
│ │ ├── src.app.html
│ │ ├── src.domain.entities.html
│ │ ├── src.domain.html
│ │ ├── src.html
│ │ ├── src.infra.db_models.html
│ │ ├── src.infra.html
│ │ ├── src.infra.repositories.html
│ │ ├── src.interactor.dtos.html
│ │ ├── src.interactor.errors.html
│ │ ├── src.interactor.html
│ │ ├── src.interactor.interfaces.html
│ │ ├── src.interactor.interfaces.logger.html
│ │ ├── src.interactor.interfaces.presenters.html
│ │ ├── src.interactor.interfaces.repositories.html
│ │ ├── src.interactor.use_cases.html
│ │ └── src.interactor.validations.html
├── make.bat
└── source
│ ├── cli_memory_process_handler.rst
│ ├── conf.py
│ ├── configs.rst
│ ├── flask_memory_process_handler.rst
│ ├── flask_postgresql_process_handler.rst
│ ├── index.rst
│ ├── modules.rst
│ ├── src.app.cli_memory.controllers.rst
│ ├── src.app.cli_memory.presenters.rst
│ ├── src.app.cli_memory.rst
│ ├── src.app.cli_memory.views.rst
│ ├── src.app.flask_memory.blueprints.rst
│ ├── src.app.flask_memory.controllers.rst
│ ├── src.app.flask_memory.interfaces.rst
│ ├── src.app.flask_memory.presenters.rst
│ ├── src.app.flask_memory.rst
│ ├── src.app.flask_postgresql.blueprints.rst
│ ├── src.app.flask_postgresql.controllers.rst
│ ├── src.app.flask_postgresql.interfaces.rst
│ ├── src.app.flask_postgresql.presenters.rst
│ ├── src.app.flask_postgresql.rst
│ ├── src.app.rst
│ ├── src.domain.entities.rst
│ ├── src.domain.rst
│ ├── src.infra.db_models.rst
│ ├── src.infra.repositories.rst
│ ├── src.infra.rst
│ ├── src.interactor.dtos.rst
│ ├── src.interactor.errors.rst
│ ├── src.interactor.interfaces.logger.rst
│ ├── src.interactor.interfaces.presenters.rst
│ ├── src.interactor.interfaces.repositories.rst
│ ├── src.interactor.interfaces.rst
│ ├── src.interactor.rst
│ ├── src.interactor.use_cases.rst
│ ├── src.interactor.validations.rst
│ └── src.rst
├── flask_memory_process_handler.py
├── flask_postgresql_process_handler.py
├── requirements.txt
└── src
├── __init__.py
├── app
├── __init__.py
├── cli_memory
│ ├── __init__.py
│ ├── controllers
│ │ ├── __init__.py
│ │ ├── create_profession_controller.py
│ │ ├── create_profession_controller_test.py
│ │ └── exit_controller.py
│ ├── interfaces
│ │ └── cli_memory_controller_interface.py
│ ├── presenters
│ │ ├── __init__.py
│ │ ├── create_profession_presenter.py
│ │ └── create_profession_presenter_test.py
│ └── views
│ │ ├── __init__.py
│ │ ├── create_profession_view.py
│ │ └── create_profession_view_test.py
├── flask_memory
│ ├── __init__.py
│ ├── blueprints
│ │ ├── __init__.py
│ │ └── create_profession_blueprint.py
│ ├── controllers
│ │ ├── __init__.py
│ │ ├── create_profession_controller.py
│ │ └── create_profession_controller_test.py
│ ├── create_flask_memory_app.py
│ ├── create_flask_memory_app_test.py
│ ├── interfaces
│ │ ├── __init__.py
│ │ └── flask_memory_controller_interface.py
│ └── presenters
│ │ ├── __init__.py
│ │ ├── create_profession_presenter.py
│ │ └── create_profession_presenter_test.py
└── flask_postgresql
│ ├── __init__.py
│ ├── blueprints
│ ├── __init__.py
│ └── create_profession_blueprint.py
│ ├── controllers
│ ├── __init__.py
│ ├── create_profession_controller.py
│ └── create_profession_controller_test.py
│ ├── create_flask_postgresql_app.py
│ ├── create_flask_postgresql_app_test.py
│ ├── interfaces
│ ├── __init__.py
│ └── flask_postgresql_controller_interface.py
│ └── presenters
│ ├── __init__.py
│ ├── create_profession_presenter.py
│ └── create_profession_presenter_test.py
├── conftest.py
├── domain
├── __init__.py
├── entities
│ ├── __init__.py
│ ├── profession.py
│ └── profession_test.py
└── value_objects.py
├── infra
├── __init__.py
├── db_models
│ ├── __init__.py
│ ├── db_base.py
│ └── profession_db_model.py
├── loggers
│ ├── logger_default.py
│ └── logger_default_test.py
└── repositories
│ ├── __init__.py
│ ├── profession_in_memory_repository.py
│ ├── profession_in_memory_repository_test.py
│ ├── profession_postgresql_repository.py
│ └── profession_postgresql_repository_test.py
└── interactor
├── __init__.py
├── dtos
├── __init__.py
├── create_profession_dtos.py
└── create_profession_dtos_test.py
├── errors
├── __init__.py
├── error_classes.py
└── error_classes_test.py
├── interfaces
├── __init__.py
├── logger
│ ├── __init__.py
│ └── logger.py
├── presenters
│ ├── __init__.py
│ └── create_profession_presenter.py
└── repositories
│ ├── __init__.py
│ └── profession_repository.py
├── use_cases
├── __init__.py
├── create_profession.py
└── create_profession_test.py
└── validations
├── __init__.py
├── base_input_validator.py
├── base_input_validator_test.py
├── create_profession_validator.py
└── create_profession_validator_test.py
/.env.example:
--------------------------------------------------------------------------------
1 | DATABASE_USER="db_user"
2 | DATABASE_PASSWORD="db_pass"
3 | DATABASE_NAME="db_name"
4 | DATABASE_HOST="localhost"
5 |
--------------------------------------------------------------------------------
/.github/workflows/python-app.yml:
--------------------------------------------------------------------------------
1 | # This workflow will install Python dependencies, run tests and lint with a single version of Python
2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
3 |
4 | name: pytesting
5 |
6 | on:
7 | push:
8 | branches: [ "main" ]
9 | pull_request:
10 | branches: [ "main" ]
11 |
12 | permissions:
13 | contents: write
14 |
15 | jobs:
16 | build:
17 |
18 | runs-on: ubuntu-latest
19 |
20 | steps:
21 | - uses: actions/checkout@v3
22 | - name: Set up Python 3.10
23 | uses: actions/setup-python@v3
24 | with:
25 | python-version: "3.10"
26 | - name: Install dependencies
27 | run: |
28 | python -m pip install --upgrade pip
29 | pip install pytest pytest-cov pytest-mock pytest-coverage
30 | if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
31 | - name: Test with pytest
32 | run: |
33 | pytest --cov
34 | - name: Creating coverage folder
35 | run: |
36 | mkdir -p coverage
37 | - name: Coverage Bagdge
38 | uses: tj-actions/coverage-badge-py@v1.8
39 | with:
40 | output: coverage/coverage.svg
41 | - name: Publish coverage report to coverage-badge branch
42 | uses: JamesIves/github-pages-deploy-action@v4
43 | with:
44 | branch: coverage-badge
45 | folder: coverage
46 |
--------------------------------------------------------------------------------
/.github/workflows/static.yml:
--------------------------------------------------------------------------------
1 | # Simple workflow for deploying static content to GitHub Pages
2 | name: Deploy static content to Pages
3 |
4 | on:
5 | # Runs on pushes targeting the default branch
6 | push:
7 | branches: ["main"]
8 |
9 | # Allows you to run this workflow manually from the Actions tab
10 | workflow_dispatch:
11 |
12 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
13 | permissions:
14 | contents: read
15 | pages: write
16 | id-token: write
17 |
18 | # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
19 | # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
20 | concurrency:
21 | group: "pages"
22 | cancel-in-progress: false
23 |
24 | jobs:
25 | # Single deploy job since we're just deploying
26 | deploy:
27 | environment:
28 | name: github-pages
29 | url: ${{ steps.deployment.outputs.page_url }}
30 | runs-on: ubuntu-latest
31 | steps:
32 | - name: Checkout
33 | uses: actions/checkout@v3
34 | - name: Setup Pages
35 | uses: actions/configure-pages@v3
36 | - name: Upload artifact
37 | uses: actions/upload-pages-artifact@v1
38 | with:
39 | # Upload entire repository
40 | path: '.'
41 | - name: Deploy to GitHub Pages
42 | id: deployment
43 | uses: actions/deploy-pages@v2
44 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | **/__pycache__
2 | .pytest_cache
3 | venv
4 | .env
5 |
6 | .coverage
7 |
8 | ##### Specific to this application #####
9 | # Log
10 | app.log
--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | repos:
2 | - repo: https://gitlab.com/pycqa/flake8
3 | rev: 3.7.9
4 | hooks:
5 | - id: flake8
6 | stages: [commit]
7 | exclude: '(migrations|alembic|docs)/.*'
8 | - repo: local
9 | hooks:
10 | - id: pytest
11 | name: pytest
12 | language: system
13 | entry: pytest -v -s --cov --cov-fail-under=100
14 | always_run: true
15 | pass_filenames: false
16 | stages: [commit]
17 | - repo: local
18 | hooks:
19 | - id: requirements
20 | name: requirements
21 | entry: bash -c 'pip3 freeze > requirements.txt; git add requirements.txt'
22 | language: system
23 | pass_filenames: false
24 | stages: [commit]
25 | - repo: local
26 | hooks:
27 | - id: mypy
28 | name: mypy
29 | entry: "mypy --exclude '(docs|venv|alembic)' --explicit-package-bases ./"
30 | language: python
31 | # trigger for commits changing Python files
32 | types: [python]
33 | # use require_serial so that script
34 | # is only called once per commit
35 | require_serial: true
36 | # print the number of files as a sanity-check
37 | verbose: true
38 | pass_filenames: false
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "python.linting.enabled": true,
3 | "python.linting.pylintEnabled": true,
4 | "python.linting.pylintArgs": [
5 | "--max-line-length=79",
6 | "--load-plugins",
7 | "pylint_pytest",
8 | "--ignore-patterns=alembic/versions/*"
9 | ],
10 | "python.linting.mypyEnabled": true,
11 | "files.exclude": {
12 | "**/*.pyc": {"when": "$(basename).py"},
13 | "**/__pycache__": true,
14 | "**/*.pytest_cache": true
15 | },
16 | "[python]": {
17 | "editor.rulers": [
18 | 79
19 | ]
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Claudio Shigueo Watanabe
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |  
2 |
3 | # About
4 | This repository is a simple example of an implementation Clean Architecture using Python.
5 |
6 | # Articles about this project
7 | I am writing a series of Linkedin articles related to this project:
8 | * [Python Clean Architecture In-memory CLI implementation](https://www.linkedin.com/pulse/implementation-clean-architecture-python-part-1-cli-watanabe/): I wrote [this article](https://www.linkedin.com/pulse/implementation-clean-architecture-python-part-1-cli-watanabe/) explaining the Clean Architecture, its layers and a Python implementation of an in-memory CLI.
9 | * [Error Handling, Logging and Validation implementation in Python Clean Architecture](https://www.linkedin.com/pulse/implementation-clean-architecture-python-part-2-error-watanabe/): I wrote [this article](https://www.linkedin.com/pulse/implementation-clean-architecture-python-part-2-error-watanabe/) about error handling, logging and validation, including some Python best practices around these topics. I complemented our Python Clean Architecture implementation with those topics.
10 | * [Python Clean Architecture Flask Web API In-memory implementation](https://www.linkedin.com/pulse/implementation-clean-architecture-python-part-3-adding-watanabe/): In [this article](https://www.linkedin.com/pulse/implementation-clean-architecture-python-part-3-adding-watanabe/), I wrote about basic Flask concepts, Flask blueprints and how to test a Flask application. I also talked about the addition of a Flask web API to our Python Clean Architecture implementation.
11 | * [Python Clean Architecture Flask Web API Postgresql implementation](https//www.linkedin.com/pulse/implementation-clean-architecture-python-part-4-adding-watanabe/): In [this article](https//www.linkedin.com/pulse/implementation-clean-architecture-python-part-4-adding-watanabe/), I wrote about about the inclusion of the Flask PostgreSQL flavour in my Python Clean Architecture repository. I talked about the SQLAlchemy model, Alembic database migrations, using .env files to protect sensitive information and also how to close the database connection when the http connection is closed.
12 |
13 | Also, [check this repository](https://github.com/claudiosw/python-best-practices) where you can find examples and explanations of Python best practices that complement this repository and its articles.
14 |
15 | # Instalation
16 |
17 | ## On prompt, acess the directory that want to download the project
18 | ```
19 | git clone https://github.com/claudiosw/python-clean-architecture-example-1.git
20 | ```
21 |
22 | ## Create the virtual environment:
23 | ```
24 | python -m venv venv
25 |
26 | ```
27 |
28 | ## Run the virtual environment:
29 | ### Windows
30 | ```
31 | venv\Scripts\activate
32 |
33 | ```
34 | ### Linux/MacOS
35 | ```
36 | source venv/bin/activate
37 | ```
38 |
39 | ## Install the required Python packages:
40 | ```
41 | pip install -r requirements.txt
42 | pre-commit install
43 | ```
44 |
45 | # Run the In-Memory CLI
46 | ```
47 | python .\cli_memory_process_handler.py
48 | ```
49 |
50 | # Run the In-Memory Flask API
51 | ```
52 | python .\flask_memory_process_handler.py
53 | ```
54 |
55 | # Prepare the PostgreSQL database
56 |
57 | To use the PostgreSQL flavour of our app, we need to install PostgreSQL software. It can be in other machine as well. We will need a database and a user to access this database.
58 |
59 | Create a .env file. Use the .env.example file as a template. Set the values considering your scenario.
60 |
61 | ## Apply database migrations
62 |
63 | With the PostgreSQL database installed and configured, you can apply the database migrations with the command below:
64 |
65 | ```
66 | alembic upgrade head
67 | ```
68 |
69 | # Run the PostgreSQL Flask API
70 | ```
71 | python .\flask_postgresql_process_handler.py
72 | ```
73 |
74 | # Documentation
75 |
76 | ## API Documentation of the Flask PostgreSQL flavor of this project:
77 | You can access the API documentation [here](https://documenter.getpostman.com/view/27866946/2s93saZYEK).
78 |
79 | ## Documentation Generated by Sphinx
80 | You can see the documentation of this project generated by Sphinx in [here](https://claudiosw.github.io/python-clean-architecture-example/docs/build/html/index.html).
81 |
82 |
83 | # Closing
84 |
85 | I hope this repository and my article series were valuable to you. If that was the case, please star it.
86 |
87 | If you want to contact me, reach me on [LinkedIn](https://www.linkedin.com/in/claudiosw/) or [Twitter](https://twitter.com/ClaudioShigueoW).
88 |
89 | I am looking for a Python position. I also offer paid mentoring.
--------------------------------------------------------------------------------
/alembic.ini:
--------------------------------------------------------------------------------
1 | # A generic, single database configuration.
2 |
3 | [alembic]
4 | # path to migration scripts
5 | script_location = alembic
6 |
7 | # template used to generate migration file names; The default value is %%(rev)s_%%(slug)s
8 | # Uncomment the line below if you want the files to be prepended with date and time
9 | # see https://alembic.sqlalchemy.org/en/latest/tutorial.html#editing-the-ini-file
10 | # for all available tokens
11 | # file_template = %%(year)d_%%(month).2d_%%(day).2d_%%(hour).2d%%(minute).2d-%%(rev)s_%%(slug)s
12 |
13 | # sys.path path, will be prepended to sys.path if present.
14 | # defaults to the current working directory.
15 | prepend_sys_path = .
16 |
17 | # timezone to use when rendering the date within the migration file
18 | # as well as the filename.
19 | # If specified, requires the python-dateutil library that can be
20 | # installed by adding `alembic[tz]` to the pip requirements
21 | # string value is passed to dateutil.tz.gettz()
22 | # leave blank for localtime
23 | # timezone =
24 |
25 | # max length of characters to apply to the
26 | # "slug" field
27 | # truncate_slug_length = 40
28 |
29 | # set to 'true' to run the environment during
30 | # the 'revision' command, regardless of autogenerate
31 | # revision_environment = false
32 |
33 | # set to 'true' to allow .pyc and .pyo files without
34 | # a source .py file to be detected as revisions in the
35 | # versions/ directory
36 | # sourceless = false
37 |
38 | # version location specification; This defaults
39 | # to alembic/versions. When using multiple version
40 | # directories, initial revisions must be specified with --version-path.
41 | # The path separator used here should be the separator specified by "version_path_separator" below.
42 | # version_locations = %(here)s/bar:%(here)s/bat:alembic/versions
43 |
44 | # version path separator; As mentioned above, this is the character used to split
45 | # version_locations. The default within new alembic.ini files is "os", which uses os.pathsep.
46 | # If this key is omitted entirely, it falls back to the legacy behavior of splitting on spaces and/or commas.
47 | # Valid values for version_path_separator are:
48 | #
49 | # version_path_separator = :
50 | # version_path_separator = ;
51 | # version_path_separator = space
52 | version_path_separator = os # Use os.pathsep. Default configuration used for new projects.
53 |
54 | # set to 'true' to search source files recursively
55 | # in each "version_locations" directory
56 | # new in Alembic version 1.10
57 | # recursive_version_locations = false
58 |
59 | # the output encoding used when revision files
60 | # are written from script.py.mako
61 | # output_encoding = utf-8
62 |
63 | # sqlalchemy.url = driver://user:pass@localhost/dbname
64 | # sqlalchemy.echo = True
65 |
66 |
67 | [post_write_hooks]
68 | # post_write_hooks defines scripts or Python functions that are run
69 | # on newly generated revision scripts. See the documentation for further
70 | # detail and examples
71 |
72 | # format using "black" - use the console_scripts runner, against the "black" entrypoint
73 | # hooks = black
74 | # black.type = console_scripts
75 | # black.entrypoint = black
76 | # black.options = -l 79 REVISION_SCRIPT_FILENAME
77 |
78 | # Logging configuration
79 | [loggers]
80 | keys = root,sqlalchemy,alembic
81 |
82 | [handlers]
83 | keys = console
84 |
85 | [formatters]
86 | keys = generic
87 |
88 | [logger_root]
89 | level = WARN
90 | handlers = console
91 | qualname =
92 |
93 | [logger_sqlalchemy]
94 | level = WARN
95 | handlers =
96 | qualname = sqlalchemy.engine
97 |
98 | [logger_alembic]
99 | level = INFO
100 | handlers =
101 | qualname = alembic
102 |
103 | [handler_console]
104 | class = StreamHandler
105 | args = (sys.stderr,)
106 | level = NOTSET
107 | formatter = generic
108 |
109 | [formatter_generic]
110 | format = %(levelname)-5.5s [%(name)s] %(message)s
111 | datefmt = %H:%M:%S
112 |
--------------------------------------------------------------------------------
/alembic/README:
--------------------------------------------------------------------------------
1 | Generic single-database configuration.
--------------------------------------------------------------------------------
/alembic/env.py:
--------------------------------------------------------------------------------
1 | # pylint: disable=no-member
2 | # pylint: disable=missing-module-docstring
3 |
4 |
5 | from logging.config import fileConfig
6 |
7 | from sqlalchemy import engine_from_config
8 | from sqlalchemy import pool
9 |
10 | from alembic import context
11 |
12 | from configs import config as config_app
13 | from src.infra.db_models.db_base import Base
14 | from src.infra.db_models.profession_db_model import ProfessionsDBModel
15 |
16 |
17 | # this is the Alembic Config object, which provides
18 | # access to the values within the .ini file in use.
19 | config = context.config
20 |
21 |
22 | config.set_main_option('sqlalchemy.url', config_app.DB_URI)
23 |
24 |
25 | # Interpret the config file for Python logging.
26 | # This line sets up loggers basically.
27 | if config.config_file_name is not None:
28 | fileConfig(config.config_file_name)
29 |
30 | # add your model's MetaData object here
31 | # for 'autogenerate' support
32 | # from myapp import mymodel
33 | # target_metadata = mymodel.Base.metadata
34 | target_metadata = Base.metadata
35 |
36 | # other values from the config, defined by the needs of env.py,
37 | # can be acquired:
38 | # my_important_option = config.get_main_option("my_important_option")
39 | # ... etc.
40 |
41 |
42 | def run_migrations_offline() -> None:
43 | """Run migrations in 'offline' mode.
44 |
45 | This configures the context with just a URL
46 | and not an Engine, though an Engine is acceptable
47 | here as well. By skipping the Engine creation
48 | we don't even need a DBAPI to be available.
49 |
50 | Calls to context.execute() here emit the given string to the
51 | script output.
52 |
53 | """
54 | url = config.get_main_option("sqlalchemy.url")
55 | context.configure(
56 | url=url,
57 | target_metadata=target_metadata,
58 | literal_binds=True,
59 | dialect_opts={"paramstyle": "named"},
60 | )
61 |
62 | with context.begin_transaction():
63 | context.run_migrations()
64 |
65 |
66 | def run_migrations_online() -> None:
67 | """Run migrations in 'online' mode.
68 |
69 | In this scenario we need to create an Engine
70 | and associate a connection with the context.
71 |
72 | """
73 | connectable = engine_from_config(
74 | config.get_section(config.config_ini_section, {}),
75 | prefix="sqlalchemy.",
76 | poolclass=pool.NullPool,
77 | )
78 |
79 | with connectable.connect() as connection:
80 | context.configure(
81 | connection=connection, target_metadata=target_metadata
82 | )
83 |
84 | with context.begin_transaction():
85 | context.run_migrations()
86 |
87 |
88 | if context.is_offline_mode():
89 | run_migrations_offline()
90 | else:
91 | run_migrations_online()
92 |
--------------------------------------------------------------------------------
/alembic/script.py.mako:
--------------------------------------------------------------------------------
1 | """${message}
2 |
3 | Revision ID: ${up_revision}
4 | Revises: ${down_revision | comma,n}
5 | Create Date: ${create_date}
6 |
7 | """
8 | from alembic import op
9 | import sqlalchemy as sa
10 | ${imports if imports else ""}
11 |
12 | # revision identifiers, used by Alembic.
13 | revision = ${repr(up_revision)}
14 | down_revision = ${repr(down_revision)}
15 | branch_labels = ${repr(branch_labels)}
16 | depends_on = ${repr(depends_on)}
17 |
18 |
19 | def upgrade() -> None:
20 | ${upgrades if upgrades else "pass"}
21 |
22 |
23 | def downgrade() -> None:
24 | ${downgrades if downgrades else "pass"}
25 |
--------------------------------------------------------------------------------
/alembic/versions/0ca47c9b66bd_adding_professionsdbmodel.py:
--------------------------------------------------------------------------------
1 | """Adding ProfessionsDBModel
2 |
3 | Revision ID: 0ca47c9b66bd
4 | Revises:
5 | Create Date: 2023-05-31 15:27:45.862478
6 |
7 | """
8 | from alembic import op
9 | import sqlalchemy as sa
10 |
11 |
12 | # revision identifiers, used by Alembic.
13 | revision = '0ca47c9b66bd'
14 | down_revision = None
15 | branch_labels = None
16 | depends_on = None
17 |
18 |
19 | def upgrade() -> None:
20 | # ### commands auto generated by Alembic - please adjust! ###
21 | op.create_table('professions',
22 | sa.Column('profession_id', sa.UUID(), nullable=False),
23 | sa.Column('name', sa.String(length=80), nullable=False),
24 | sa.Column('description', sa.String(length=200), nullable=False),
25 | sa.PrimaryKeyConstraint('profession_id'),
26 | sa.UniqueConstraint('name')
27 | )
28 | # ### end Alembic commands ###
29 |
30 |
31 | def downgrade() -> None:
32 | # ### commands auto generated by Alembic - please adjust! ###
33 | op.drop_table('professions')
34 | # ### end Alembic commands ###
35 |
--------------------------------------------------------------------------------
/cli_memory_process_handler.py:
--------------------------------------------------------------------------------
1 | """ This module contains the ProcessHandler for Cli that uses Memory repository
2 | """
3 |
4 |
5 | from typing import Dict
6 | from src.app.cli_memory.interfaces.cli_memory_controller_interface \
7 | import CliMemoryControllerInterface
8 | from src.app.cli_memory.controllers.exit_controller \
9 | import ExitController
10 | from src.app.cli_memory.controllers.create_profession_controller \
11 | import CreateProfessionController
12 | from src.interactor.errors.error_classes import FieldValueNotPermittedException
13 | from src.interactor.interfaces.logger.logger import LoggerInterface
14 | from src.infra.loggers.logger_default import LoggerDefault
15 |
16 |
17 | class CliMemoryProcessHandler:
18 | """ The ProcessHandler for Cli that uses Memory repository
19 | """
20 | def __init__(self, logger: LoggerInterface) -> None:
21 | self.logger = logger
22 | self.options: Dict = {}
23 |
24 | def add_option(
25 | self,
26 | option: str,
27 | controller: CliMemoryControllerInterface
28 | ) -> None:
29 | """ Add an option to the ProcessHandler
30 | :param option: The option
31 | :param controller: The controller for the option
32 | :return: None
33 | """
34 | self.options[option] = controller
35 |
36 | def show_options(self):
37 | """ Print the options to the ProcessHandler
38 | :return: None
39 | """
40 | for option, controller in self.options.items():
41 | print(f"{option}: {controller.__class__.__name__}")
42 |
43 | def execute(self) -> None:
44 | """ Execute the ProcessHandler
45 | :return: None
46 | """
47 | while True:
48 | print("Please choose an option:")
49 | self.show_options()
50 | choice = input("> ")
51 | option = self.options.get(choice)
52 | if option:
53 | try:
54 | option.execute()
55 | except (
56 | ValueError,
57 | FieldValueNotPermittedException
58 | ) as exception:
59 | print(f'\nERROR: {str(exception)}\n')
60 | self.logger.log_exception(str(exception))
61 | else:
62 | print("Invalid choice.")
63 | self.logger.log_info(f"Invalid user choice: {option}")
64 |
65 |
66 | if __name__ == "__main__":
67 | logger_default = LoggerDefault()
68 | process = CliMemoryProcessHandler(logger_default)
69 | process.add_option("0", ExitController())
70 | process.add_option("1", CreateProfessionController(logger_default))
71 | process.execute()
72 |
--------------------------------------------------------------------------------
/configs/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/configs/__init__.py
--------------------------------------------------------------------------------
/configs/config.py:
--------------------------------------------------------------------------------
1 | """ Configuration file
2 | """
3 |
4 |
5 | import os
6 | from dotenv import load_dotenv
7 |
8 |
9 | load_dotenv()
10 |
11 |
12 | DB_USER = os.getenv("DATABASE_USER")
13 | DB_PASS = os.getenv("DATABASE_PASSWORD")
14 | DB_NAME = os.getenv("DATABASE_NAME")
15 | DB_HOST = os.getenv("DATABASE_HOST")
16 | DB_PORT = os.getenv("DATABASE_PORT")
17 | DB_DRIVER = "postgresql+psycopg2"
18 |
19 |
20 | DB_URI = f"{DB_DRIVER}://{DB_USER}:{DB_PASS}@{DB_HOST}:{DB_PORT}/{DB_NAME}"
21 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Minimal makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line, and also
5 | # from the environment for the first two.
6 | SPHINXOPTS ?=
7 | SPHINXBUILD ?= sphinx-build
8 | SOURCEDIR = source
9 | BUILDDIR = build
10 |
11 | # Put it first so that "make" without argument is like "make help".
12 | help:
13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14 |
15 | .PHONY: help Makefile
16 |
17 | # Catch-all target: route all unknown targets to Sphinx using the new
18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19 | %: Makefile
20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
21 |
--------------------------------------------------------------------------------
/docs/build/doctrees/cli_memory_process_handler.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/cli_memory_process_handler.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/configs.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/configs.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/environment.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/environment.pickle
--------------------------------------------------------------------------------
/docs/build/doctrees/flask_memory_process_handler.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/flask_memory_process_handler.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/flask_postgresql_process_handler.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/flask_postgresql_process_handler.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/index.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/index.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/modules.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/modules.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/src.app.cli_memory.controllers.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/src.app.cli_memory.controllers.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/src.app.cli_memory.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/src.app.cli_memory.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/src.app.cli_memory.presenters.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/src.app.cli_memory.presenters.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/src.app.cli_memory.views.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/src.app.cli_memory.views.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/src.app.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/src.app.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/src.app.flask_memory.blueprints.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/src.app.flask_memory.blueprints.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/src.app.flask_memory.controllers.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/src.app.flask_memory.controllers.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/src.app.flask_memory.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/src.app.flask_memory.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/src.app.flask_memory.interfaces.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/src.app.flask_memory.interfaces.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/src.app.flask_memory.presenters.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/src.app.flask_memory.presenters.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/src.app.flask_postgresql.blueprints.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/src.app.flask_postgresql.blueprints.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/src.app.flask_postgresql.controllers.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/src.app.flask_postgresql.controllers.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/src.app.flask_postgresql.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/src.app.flask_postgresql.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/src.app.flask_postgresql.interfaces.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/src.app.flask_postgresql.interfaces.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/src.app.flask_postgresql.presenters.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/src.app.flask_postgresql.presenters.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/src.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/src.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/src.domain.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/src.domain.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/src.domain.entities.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/src.domain.entities.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/src.infra.db_models.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/src.infra.db_models.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/src.infra.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/src.infra.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/src.infra.repositories.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/src.infra.repositories.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/src.interactor.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/src.interactor.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/src.interactor.dtos.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/src.interactor.dtos.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/src.interactor.errors.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/src.interactor.errors.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/src.interactor.interfaces.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/src.interactor.interfaces.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/src.interactor.interfaces.logger.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/src.interactor.interfaces.logger.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/src.interactor.interfaces.presenters.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/src.interactor.interfaces.presenters.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/src.interactor.interfaces.repositories.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/src.interactor.interfaces.repositories.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/src.interactor.use_cases.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/src.interactor.use_cases.doctree
--------------------------------------------------------------------------------
/docs/build/doctrees/src.interactor.validations.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/doctrees/src.interactor.validations.doctree
--------------------------------------------------------------------------------
/docs/build/html/.buildinfo:
--------------------------------------------------------------------------------
1 | # Sphinx build info version 1
2 | # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
3 | config: b2150682404517c2bb08c35bea2b3281
4 | tags: 645f666f9bcd5a90fca523b33c5a78b7
5 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/cli_memory_process_handler.rst.txt:
--------------------------------------------------------------------------------
1 | cli\_memory\_process\_handler module
2 | ====================================
3 |
4 | .. automodule:: cli_memory_process_handler
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/configs.rst.txt:
--------------------------------------------------------------------------------
1 | configs package
2 | ===============
3 |
4 | Submodules
5 | ----------
6 |
7 | configs.config module
8 | ---------------------
9 |
10 | .. automodule:: configs.config
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | Module contents
16 | ---------------
17 |
18 | .. automodule:: configs
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/flask_memory_process_handler.rst.txt:
--------------------------------------------------------------------------------
1 | flask\_memory\_process\_handler module
2 | ======================================
3 |
4 | .. automodule:: flask_memory_process_handler
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/flask_postgresql_process_handler.rst.txt:
--------------------------------------------------------------------------------
1 | flask\_postgresql\_process\_handler module
2 | ==========================================
3 |
4 | .. automodule:: flask_postgresql_process_handler
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/index.rst.txt:
--------------------------------------------------------------------------------
1 | .. Python Clean Architecture example documentation master file, created by
2 | sphinx-quickstart on Thu Jun 8 19:17:15 2023.
3 | You can adapt this file completely to your liking, but it should at least
4 | contain the root `toctree` directive.
5 |
6 | Welcome to Python Clean Architecture example's documentation!
7 | =============================================================
8 |
9 | .. toctree::
10 | :maxdepth: 7
11 | :caption: Contents:
12 |
13 | modules
14 |
15 | Indices and tables
16 | ==================
17 |
18 | * :ref:`genindex`
19 | * :ref:`modindex`
20 | * :ref:`search`
21 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/modules.rst.txt:
--------------------------------------------------------------------------------
1 | python-clean-architecture-example
2 | =================================
3 |
4 | .. toctree::
5 | :maxdepth: 4
6 |
7 | cli_memory_process_handler
8 | configs
9 | flask_memory_process_handler
10 | flask_postgresql_process_handler
11 | src
12 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/src.app.cli_memory.controllers.rst.txt:
--------------------------------------------------------------------------------
1 | src.app.cli\_memory.controllers package
2 | =======================================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.app.cli\_memory.controllers.create\_profession\_controller module
8 | ---------------------------------------------------------------------
9 |
10 | .. automodule:: src.app.cli_memory.controllers.create_profession_controller
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | src.app.cli\_memory.controllers.create\_profession\_controller\_test module
16 | ---------------------------------------------------------------------------
17 |
18 | .. automodule:: src.app.cli_memory.controllers.create_profession_controller_test
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
23 | src.app.cli\_memory.controllers.exit\_controller module
24 | -------------------------------------------------------
25 |
26 | .. automodule:: src.app.cli_memory.controllers.exit_controller
27 | :members:
28 | :undoc-members:
29 | :show-inheritance:
30 |
31 | Module contents
32 | ---------------
33 |
34 | .. automodule:: src.app.cli_memory.controllers
35 | :members:
36 | :undoc-members:
37 | :show-inheritance:
38 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/src.app.cli_memory.presenters.rst.txt:
--------------------------------------------------------------------------------
1 | src.app.cli\_memory.presenters package
2 | ======================================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.app.cli\_memory.presenters.create\_profession\_presenter module
8 | -------------------------------------------------------------------
9 |
10 | .. automodule:: src.app.cli_memory.presenters.create_profession_presenter
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | src.app.cli\_memory.presenters.create\_profession\_presenter\_test module
16 | -------------------------------------------------------------------------
17 |
18 | .. automodule:: src.app.cli_memory.presenters.create_profession_presenter_test
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
23 | Module contents
24 | ---------------
25 |
26 | .. automodule:: src.app.cli_memory.presenters
27 | :members:
28 | :undoc-members:
29 | :show-inheritance:
30 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/src.app.cli_memory.rst.txt:
--------------------------------------------------------------------------------
1 | src.app.cli\_memory package
2 | ===========================
3 |
4 | Subpackages
5 | -----------
6 |
7 | .. toctree::
8 | :maxdepth: 4
9 |
10 | src.app.cli_memory.controllers
11 | src.app.cli_memory.presenters
12 | src.app.cli_memory.views
13 |
14 | Module contents
15 | ---------------
16 |
17 | .. automodule:: src.app.cli_memory
18 | :members:
19 | :undoc-members:
20 | :show-inheritance:
21 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/src.app.cli_memory.views.rst.txt:
--------------------------------------------------------------------------------
1 | src.app.cli\_memory.views package
2 | =================================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.app.cli\_memory.views.create\_profession\_view module
8 | ---------------------------------------------------------
9 |
10 | .. automodule:: src.app.cli_memory.views.create_profession_view
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | src.app.cli\_memory.views.create\_profession\_view\_test module
16 | ---------------------------------------------------------------
17 |
18 | .. automodule:: src.app.cli_memory.views.create_profession_view_test
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
23 | Module contents
24 | ---------------
25 |
26 | .. automodule:: src.app.cli_memory.views
27 | :members:
28 | :undoc-members:
29 | :show-inheritance:
30 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/src.app.flask_memory.blueprints.rst.txt:
--------------------------------------------------------------------------------
1 | src.app.flask\_memory.blueprints package
2 | ========================================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.app.flask\_memory.blueprints.create\_profession\_blueprint module
8 | ---------------------------------------------------------------------
9 |
10 | .. automodule:: src.app.flask_memory.blueprints.create_profession_blueprint
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | Module contents
16 | ---------------
17 |
18 | .. automodule:: src.app.flask_memory.blueprints
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/src.app.flask_memory.controllers.rst.txt:
--------------------------------------------------------------------------------
1 | src.app.flask\_memory.controllers package
2 | =========================================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.app.flask\_memory.controllers.create\_profession\_controller module
8 | -----------------------------------------------------------------------
9 |
10 | .. automodule:: src.app.flask_memory.controllers.create_profession_controller
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | src.app.flask\_memory.controllers.create\_profession\_controller\_test module
16 | -----------------------------------------------------------------------------
17 |
18 | .. automodule:: src.app.flask_memory.controllers.create_profession_controller_test
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
23 | Module contents
24 | ---------------
25 |
26 | .. automodule:: src.app.flask_memory.controllers
27 | :members:
28 | :undoc-members:
29 | :show-inheritance:
30 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/src.app.flask_memory.interfaces.rst.txt:
--------------------------------------------------------------------------------
1 | src.app.flask\_memory.interfaces package
2 | ========================================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.app.flask\_memory.interfaces.flask\_memory\_controller\_interface module
8 | ----------------------------------------------------------------------------
9 |
10 | .. automodule:: src.app.flask_memory.interfaces.flask_memory_controller_interface
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | Module contents
16 | ---------------
17 |
18 | .. automodule:: src.app.flask_memory.interfaces
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/src.app.flask_memory.presenters.rst.txt:
--------------------------------------------------------------------------------
1 | src.app.flask\_memory.presenters package
2 | ========================================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.app.flask\_memory.presenters.create\_profession\_presenter module
8 | ---------------------------------------------------------------------
9 |
10 | .. automodule:: src.app.flask_memory.presenters.create_profession_presenter
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | src.app.flask\_memory.presenters.create\_profession\_presenter\_test module
16 | ---------------------------------------------------------------------------
17 |
18 | .. automodule:: src.app.flask_memory.presenters.create_profession_presenter_test
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
23 | Module contents
24 | ---------------
25 |
26 | .. automodule:: src.app.flask_memory.presenters
27 | :members:
28 | :undoc-members:
29 | :show-inheritance:
30 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/src.app.flask_memory.rst.txt:
--------------------------------------------------------------------------------
1 | src.app.flask\_memory package
2 | =============================
3 |
4 | Subpackages
5 | -----------
6 |
7 | .. toctree::
8 | :maxdepth: 4
9 |
10 | src.app.flask_memory.blueprints
11 | src.app.flask_memory.controllers
12 | src.app.flask_memory.interfaces
13 | src.app.flask_memory.presenters
14 |
15 | Submodules
16 | ----------
17 |
18 | src.app.flask\_memory.create\_flask\_memory\_app module
19 | -------------------------------------------------------
20 |
21 | .. automodule:: src.app.flask_memory.create_flask_memory_app
22 | :members:
23 | :undoc-members:
24 | :show-inheritance:
25 |
26 | src.app.flask\_memory.create\_flask\_memory\_app\_test module
27 | -------------------------------------------------------------
28 |
29 | .. automodule:: src.app.flask_memory.create_flask_memory_app_test
30 | :members:
31 | :undoc-members:
32 | :show-inheritance:
33 |
34 | Module contents
35 | ---------------
36 |
37 | .. automodule:: src.app.flask_memory
38 | :members:
39 | :undoc-members:
40 | :show-inheritance:
41 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/src.app.flask_postgresql.blueprints.rst.txt:
--------------------------------------------------------------------------------
1 | src.app.flask\_postgresql.blueprints package
2 | ============================================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.app.flask\_postgresql.blueprints.create\_profession\_blueprint module
8 | -------------------------------------------------------------------------
9 |
10 | .. automodule:: src.app.flask_postgresql.blueprints.create_profession_blueprint
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | Module contents
16 | ---------------
17 |
18 | .. automodule:: src.app.flask_postgresql.blueprints
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/src.app.flask_postgresql.controllers.rst.txt:
--------------------------------------------------------------------------------
1 | src.app.flask\_postgresql.controllers package
2 | =============================================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.app.flask\_postgresql.controllers.create\_profession\_controller module
8 | ---------------------------------------------------------------------------
9 |
10 | .. automodule:: src.app.flask_postgresql.controllers.create_profession_controller
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | src.app.flask\_postgresql.controllers.create\_profession\_controller\_test module
16 | ---------------------------------------------------------------------------------
17 |
18 | .. automodule:: src.app.flask_postgresql.controllers.create_profession_controller_test
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
23 | Module contents
24 | ---------------
25 |
26 | .. automodule:: src.app.flask_postgresql.controllers
27 | :members:
28 | :undoc-members:
29 | :show-inheritance:
30 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/src.app.flask_postgresql.interfaces.rst.txt:
--------------------------------------------------------------------------------
1 | src.app.flask\_postgresql.interfaces package
2 | ============================================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.app.flask\_postgresql.interfaces.flask\_postgresql\_controller\_interface module
8 | ------------------------------------------------------------------------------------
9 |
10 | .. automodule:: src.app.flask_postgresql.interfaces.flask_postgresql_controller_interface
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | Module contents
16 | ---------------
17 |
18 | .. automodule:: src.app.flask_postgresql.interfaces
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/src.app.flask_postgresql.presenters.rst.txt:
--------------------------------------------------------------------------------
1 | src.app.flask\_postgresql.presenters package
2 | ============================================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.app.flask\_postgresql.presenters.create\_profession\_presenter module
8 | -------------------------------------------------------------------------
9 |
10 | .. automodule:: src.app.flask_postgresql.presenters.create_profession_presenter
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | src.app.flask\_postgresql.presenters.create\_profession\_presenter\_test module
16 | -------------------------------------------------------------------------------
17 |
18 | .. automodule:: src.app.flask_postgresql.presenters.create_profession_presenter_test
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
23 | Module contents
24 | ---------------
25 |
26 | .. automodule:: src.app.flask_postgresql.presenters
27 | :members:
28 | :undoc-members:
29 | :show-inheritance:
30 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/src.app.flask_postgresql.rst.txt:
--------------------------------------------------------------------------------
1 | src.app.flask\_postgresql package
2 | =================================
3 |
4 | Subpackages
5 | -----------
6 |
7 | .. toctree::
8 | :maxdepth: 4
9 |
10 | src.app.flask_postgresql.blueprints
11 | src.app.flask_postgresql.controllers
12 | src.app.flask_postgresql.interfaces
13 | src.app.flask_postgresql.presenters
14 |
15 | Submodules
16 | ----------
17 |
18 | src.app.flask\_postgresql.create\_flask\_postgresql\_app module
19 | ---------------------------------------------------------------
20 |
21 | .. automodule:: src.app.flask_postgresql.create_flask_postgresql_app
22 | :members:
23 | :undoc-members:
24 | :show-inheritance:
25 |
26 | src.app.flask\_postgresql.create\_flask\_postgresql\_app\_test module
27 | ---------------------------------------------------------------------
28 |
29 | .. automodule:: src.app.flask_postgresql.create_flask_postgresql_app_test
30 | :members:
31 | :undoc-members:
32 | :show-inheritance:
33 |
34 | Module contents
35 | ---------------
36 |
37 | .. automodule:: src.app.flask_postgresql
38 | :members:
39 | :undoc-members:
40 | :show-inheritance:
41 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/src.app.rst.txt:
--------------------------------------------------------------------------------
1 | src.app package
2 | ===============
3 |
4 | Subpackages
5 | -----------
6 |
7 | .. toctree::
8 | :maxdepth: 4
9 |
10 | src.app.cli_memory
11 | src.app.flask_memory
12 | src.app.flask_postgresql
13 |
14 | Module contents
15 | ---------------
16 |
17 | .. automodule:: src.app
18 | :members:
19 | :undoc-members:
20 | :show-inheritance:
21 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/src.domain.entities.rst.txt:
--------------------------------------------------------------------------------
1 | src.domain.entities package
2 | ===========================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.domain.entities.profession module
8 | -------------------------------------
9 |
10 | .. automodule:: src.domain.entities.profession
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | src.domain.entities.profession\_test module
16 | -------------------------------------------
17 |
18 | .. automodule:: src.domain.entities.profession_test
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
23 | Module contents
24 | ---------------
25 |
26 | .. automodule:: src.domain.entities
27 | :members:
28 | :undoc-members:
29 | :show-inheritance:
30 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/src.domain.rst.txt:
--------------------------------------------------------------------------------
1 | src.domain package
2 | ==================
3 |
4 | Subpackages
5 | -----------
6 |
7 | .. toctree::
8 | :maxdepth: 4
9 |
10 | src.domain.entities
11 |
12 | Submodules
13 | ----------
14 |
15 | src.domain.value\_objects module
16 | --------------------------------
17 |
18 | .. automodule:: src.domain.value_objects
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
23 | Module contents
24 | ---------------
25 |
26 | .. automodule:: src.domain
27 | :members:
28 | :undoc-members:
29 | :show-inheritance:
30 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/src.infra.db_models.rst.txt:
--------------------------------------------------------------------------------
1 | src.infra.db\_models package
2 | ============================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.infra.db\_models.db\_base module
8 | ------------------------------------
9 |
10 | .. automodule:: src.infra.db_models.db_base
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | src.infra.db\_models.profession\_db\_model module
16 | -------------------------------------------------
17 |
18 | .. automodule:: src.infra.db_models.profession_db_model
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
23 | Module contents
24 | ---------------
25 |
26 | .. automodule:: src.infra.db_models
27 | :members:
28 | :undoc-members:
29 | :show-inheritance:
30 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/src.infra.repositories.rst.txt:
--------------------------------------------------------------------------------
1 | src.infra.repositories package
2 | ==============================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.infra.repositories.profession\_in\_memory\_repository module
8 | ----------------------------------------------------------------
9 |
10 | .. automodule:: src.infra.repositories.profession_in_memory_repository
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | src.infra.repositories.profession\_in\_memory\_repository\_test module
16 | ----------------------------------------------------------------------
17 |
18 | .. automodule:: src.infra.repositories.profession_in_memory_repository_test
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
23 | src.infra.repositories.profession\_postgresql\_repository module
24 | ----------------------------------------------------------------
25 |
26 | .. automodule:: src.infra.repositories.profession_postgresql_repository
27 | :members:
28 | :undoc-members:
29 | :show-inheritance:
30 |
31 | src.infra.repositories.profession\_postgresql\_repository\_test module
32 | ----------------------------------------------------------------------
33 |
34 | .. automodule:: src.infra.repositories.profession_postgresql_repository_test
35 | :members:
36 | :undoc-members:
37 | :show-inheritance:
38 |
39 | Module contents
40 | ---------------
41 |
42 | .. automodule:: src.infra.repositories
43 | :members:
44 | :undoc-members:
45 | :show-inheritance:
46 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/src.infra.rst.txt:
--------------------------------------------------------------------------------
1 | src.infra package
2 | =================
3 |
4 | Subpackages
5 | -----------
6 |
7 | .. toctree::
8 | :maxdepth: 4
9 |
10 | src.infra.db_models
11 | src.infra.repositories
12 |
13 | Module contents
14 | ---------------
15 |
16 | .. automodule:: src.infra
17 | :members:
18 | :undoc-members:
19 | :show-inheritance:
20 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/src.interactor.dtos.rst.txt:
--------------------------------------------------------------------------------
1 | src.interactor.dtos package
2 | ===========================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.interactor.dtos.create\_profession\_dtos module
8 | ---------------------------------------------------
9 |
10 | .. automodule:: src.interactor.dtos.create_profession_dtos
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | src.interactor.dtos.create\_profession\_dtos\_test module
16 | ---------------------------------------------------------
17 |
18 | .. automodule:: src.interactor.dtos.create_profession_dtos_test
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
23 | Module contents
24 | ---------------
25 |
26 | .. automodule:: src.interactor.dtos
27 | :members:
28 | :undoc-members:
29 | :show-inheritance:
30 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/src.interactor.errors.rst.txt:
--------------------------------------------------------------------------------
1 | src.interactor.errors package
2 | =============================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.interactor.errors.error\_classes module
8 | -------------------------------------------
9 |
10 | .. automodule:: src.interactor.errors.error_classes
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | src.interactor.errors.error\_classes\_test module
16 | -------------------------------------------------
17 |
18 | .. automodule:: src.interactor.errors.error_classes_test
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
23 | Module contents
24 | ---------------
25 |
26 | .. automodule:: src.interactor.errors
27 | :members:
28 | :undoc-members:
29 | :show-inheritance:
30 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/src.interactor.interfaces.logger.rst.txt:
--------------------------------------------------------------------------------
1 | src.interactor.interfaces.logger package
2 | ========================================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.interactor.interfaces.logger.logger module
8 | ----------------------------------------------
9 |
10 | .. automodule:: src.interactor.interfaces.logger.logger
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | Module contents
16 | ---------------
17 |
18 | .. automodule:: src.interactor.interfaces.logger
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/src.interactor.interfaces.presenters.rst.txt:
--------------------------------------------------------------------------------
1 | src.interactor.interfaces.presenters package
2 | ============================================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.interactor.interfaces.presenters.create\_profession\_presenter module
8 | -------------------------------------------------------------------------
9 |
10 | .. automodule:: src.interactor.interfaces.presenters.create_profession_presenter
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | Module contents
16 | ---------------
17 |
18 | .. automodule:: src.interactor.interfaces.presenters
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/src.interactor.interfaces.repositories.rst.txt:
--------------------------------------------------------------------------------
1 | src.interactor.interfaces.repositories package
2 | ==============================================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.interactor.interfaces.repositories.profession\_repository module
8 | --------------------------------------------------------------------
9 |
10 | .. automodule:: src.interactor.interfaces.repositories.profession_repository
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | Module contents
16 | ---------------
17 |
18 | .. automodule:: src.interactor.interfaces.repositories
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/src.interactor.interfaces.rst.txt:
--------------------------------------------------------------------------------
1 | src.interactor.interfaces package
2 | =================================
3 |
4 | Subpackages
5 | -----------
6 |
7 | .. toctree::
8 | :maxdepth: 4
9 |
10 | src.interactor.interfaces.logger
11 | src.interactor.interfaces.presenters
12 | src.interactor.interfaces.repositories
13 |
14 | Module contents
15 | ---------------
16 |
17 | .. automodule:: src.interactor.interfaces
18 | :members:
19 | :undoc-members:
20 | :show-inheritance:
21 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/src.interactor.rst.txt:
--------------------------------------------------------------------------------
1 | src.interactor package
2 | ======================
3 |
4 | Subpackages
5 | -----------
6 |
7 | .. toctree::
8 | :maxdepth: 4
9 |
10 | src.interactor.dtos
11 | src.interactor.errors
12 | src.interactor.interfaces
13 | src.interactor.use_cases
14 | src.interactor.validations
15 |
16 | Module contents
17 | ---------------
18 |
19 | .. automodule:: src.interactor
20 | :members:
21 | :undoc-members:
22 | :show-inheritance:
23 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/src.interactor.use_cases.rst.txt:
--------------------------------------------------------------------------------
1 | src.interactor.use\_cases package
2 | =================================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.interactor.use\_cases.create\_profession module
8 | ---------------------------------------------------
9 |
10 | .. automodule:: src.interactor.use_cases.create_profession
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | src.interactor.use\_cases.create\_profession\_test module
16 | ---------------------------------------------------------
17 |
18 | .. automodule:: src.interactor.use_cases.create_profession_test
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
23 | Module contents
24 | ---------------
25 |
26 | .. automodule:: src.interactor.use_cases
27 | :members:
28 | :undoc-members:
29 | :show-inheritance:
30 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/src.interactor.validations.rst.txt:
--------------------------------------------------------------------------------
1 | src.interactor.validations package
2 | ==================================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.interactor.validations.base\_input\_validator module
8 | --------------------------------------------------------
9 |
10 | .. automodule:: src.interactor.validations.base_input_validator
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | src.interactor.validations.base\_input\_validator\_test module
16 | --------------------------------------------------------------
17 |
18 | .. automodule:: src.interactor.validations.base_input_validator_test
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
23 | src.interactor.validations.create\_profession\_validator module
24 | ---------------------------------------------------------------
25 |
26 | .. automodule:: src.interactor.validations.create_profession_validator
27 | :members:
28 | :undoc-members:
29 | :show-inheritance:
30 |
31 | src.interactor.validations.create\_profession\_validator\_test module
32 | ---------------------------------------------------------------------
33 |
34 | .. automodule:: src.interactor.validations.create_profession_validator_test
35 | :members:
36 | :undoc-members:
37 | :show-inheritance:
38 |
39 | Module contents
40 | ---------------
41 |
42 | .. automodule:: src.interactor.validations
43 | :members:
44 | :undoc-members:
45 | :show-inheritance:
46 |
--------------------------------------------------------------------------------
/docs/build/html/_sources/src.rst.txt:
--------------------------------------------------------------------------------
1 | src package
2 | ===========
3 |
4 | Subpackages
5 | -----------
6 |
7 | .. toctree::
8 | :maxdepth: 4
9 |
10 | src.app
11 | src.domain
12 | src.infra
13 | src.interactor
14 |
15 | Submodules
16 | ----------
17 |
18 | src.conftest module
19 | -------------------
20 |
21 | .. automodule:: src.conftest
22 | :members:
23 | :undoc-members:
24 | :show-inheritance:
25 |
26 | Module contents
27 | ---------------
28 |
29 | .. automodule:: src
30 | :members:
31 | :undoc-members:
32 | :show-inheritance:
33 |
--------------------------------------------------------------------------------
/docs/build/html/_static/css/badge_only.css:
--------------------------------------------------------------------------------
1 | .clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}
--------------------------------------------------------------------------------
/docs/build/html/_static/css/fonts/Roboto-Slab-Bold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/html/_static/css/fonts/Roboto-Slab-Bold.woff
--------------------------------------------------------------------------------
/docs/build/html/_static/css/fonts/Roboto-Slab-Bold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/html/_static/css/fonts/Roboto-Slab-Bold.woff2
--------------------------------------------------------------------------------
/docs/build/html/_static/css/fonts/Roboto-Slab-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/html/_static/css/fonts/Roboto-Slab-Regular.woff
--------------------------------------------------------------------------------
/docs/build/html/_static/css/fonts/Roboto-Slab-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/html/_static/css/fonts/Roboto-Slab-Regular.woff2
--------------------------------------------------------------------------------
/docs/build/html/_static/css/fonts/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/html/_static/css/fonts/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/docs/build/html/_static/css/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/html/_static/css/fonts/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/docs/build/html/_static/css/fonts/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/html/_static/css/fonts/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/docs/build/html/_static/css/fonts/fontawesome-webfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/html/_static/css/fonts/fontawesome-webfont.woff2
--------------------------------------------------------------------------------
/docs/build/html/_static/css/fonts/lato-bold-italic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/html/_static/css/fonts/lato-bold-italic.woff
--------------------------------------------------------------------------------
/docs/build/html/_static/css/fonts/lato-bold-italic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/html/_static/css/fonts/lato-bold-italic.woff2
--------------------------------------------------------------------------------
/docs/build/html/_static/css/fonts/lato-bold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/html/_static/css/fonts/lato-bold.woff
--------------------------------------------------------------------------------
/docs/build/html/_static/css/fonts/lato-bold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/html/_static/css/fonts/lato-bold.woff2
--------------------------------------------------------------------------------
/docs/build/html/_static/css/fonts/lato-normal-italic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/html/_static/css/fonts/lato-normal-italic.woff
--------------------------------------------------------------------------------
/docs/build/html/_static/css/fonts/lato-normal-italic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/html/_static/css/fonts/lato-normal-italic.woff2
--------------------------------------------------------------------------------
/docs/build/html/_static/css/fonts/lato-normal.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/html/_static/css/fonts/lato-normal.woff
--------------------------------------------------------------------------------
/docs/build/html/_static/css/fonts/lato-normal.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/html/_static/css/fonts/lato-normal.woff2
--------------------------------------------------------------------------------
/docs/build/html/_static/documentation_options.js:
--------------------------------------------------------------------------------
1 | var DOCUMENTATION_OPTIONS = {
2 | URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
3 | VERSION: '1.0.0',
4 | LANGUAGE: 'en',
5 | COLLAPSE_INDEX: false,
6 | BUILDER: 'html',
7 | FILE_SUFFIX: '.html',
8 | LINK_SUFFIX: '.html',
9 | HAS_SOURCE: true,
10 | SOURCELINK_SUFFIX: '.txt',
11 | NAVIGATION_WITH_KEYS: false,
12 | SHOW_SEARCH_SUMMARY: true,
13 | ENABLE_SEARCH_SHORTCUTS: true,
14 | };
--------------------------------------------------------------------------------
/docs/build/html/_static/file.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/html/_static/file.png
--------------------------------------------------------------------------------
/docs/build/html/_static/js/badge_only.js:
--------------------------------------------------------------------------------
1 | !function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=4)}({4:function(e,t,r){}});
--------------------------------------------------------------------------------
/docs/build/html/_static/js/html5shiv-printshiv.min.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @preserve HTML5 Shiv 3.7.3-pre | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
3 | */
4 | !function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=y.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=y.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),y.elements=c+" "+a,j(b)}function f(a){var b=x[a[v]];return b||(b={},w++,a[v]=w,x[w]=b),b}function g(a,c,d){if(c||(c=b),q)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():u.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||t.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),q)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return y.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(y,b.frag)}function j(a){a||(a=b);var d=f(a);return!y.shivCSS||p||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),q||i(a,d),a}function k(a){for(var b,c=a.getElementsByTagName("*"),e=c.length,f=RegExp("^(?:"+d().join("|")+")$","i"),g=[];e--;)b=c[e],f.test(b.nodeName)&&g.push(b.applyElement(l(b)));return g}function l(a){for(var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(A+":"+a.nodeName);d--;)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function m(a){for(var b,c=a.split("{"),e=c.length,f=RegExp("(^|[\\s,>+~])("+d().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),g="$1"+A+"\\:$2";e--;)b=c[e]=c[e].split("}"),b[b.length-1]=b[b.length-1].replace(f,g),c[e]=b.join("}");return c.join("{")}function n(a){for(var b=a.length;b--;)a[b].removeNode()}function o(a){function b(){clearTimeout(g._removeSheetTimer),d&&d.removeNode(!0),d=null}var d,e,g=f(a),h=a.namespaces,i=a.parentWindow;return!B||a.printShived?a:("undefined"==typeof h[A]&&h.add(A),i.attachEvent("onbeforeprint",function(){b();for(var f,g,h,i=a.styleSheets,j=[],l=i.length,n=Array(l);l--;)n[l]=i[l];for(;h=n.pop();)if(!h.disabled&&z.test(h.media)){try{f=h.imports,g=f.length}catch(o){g=0}for(l=0;g>l;l++)n.push(f[l]);try{j.push(h.cssText)}catch(o){}}j=m(j.reverse().join("")),e=k(a),d=c(a,j)}),i.attachEvent("onafterprint",function(){n(e),clearTimeout(g._removeSheetTimer),g._removeSheetTimer=setTimeout(b,500)}),a.printShived=!0,a)}var p,q,r="3.7.3",s=a.html5||{},t=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,u=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",w=0,x={};!function(){try{var a=b.createElement("a");a.innerHTML="",p="hidden"in a,q=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){p=!0,q=!0}}();var y={elements:s.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:r,shivCSS:s.shivCSS!==!1,supportsUnknownElements:q,shivMethods:s.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=y,j(b);var z=/^$|\b(?:all|print)\b/,A="html5shiv",B=!q&&function(){var c=b.documentElement;return!("undefined"==typeof b.namespaces||"undefined"==typeof b.parentWindow||"undefined"==typeof c.applyElement||"undefined"==typeof c.removeNode||"undefined"==typeof a.attachEvent)}();y.type+=" print",y.shivPrint=o,o(b),"object"==typeof module&&module.exports&&(module.exports=y)}("undefined"!=typeof window?window:this,document);
--------------------------------------------------------------------------------
/docs/build/html/_static/js/html5shiv.min.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
3 | */
4 | !function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3-pre",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document);
--------------------------------------------------------------------------------
/docs/build/html/_static/js/theme.js:
--------------------------------------------------------------------------------
1 | !function(n){var e={};function t(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return n[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=n,t.c=e,t.d=function(n,e,i){t.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:i})},t.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},t.t=function(n,e){if(1&e&&(n=t(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var i=Object.create(null);if(t.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var o in n)t.d(i,o,function(e){return n[e]}.bind(null,o));return i},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},t.p="",t(t.s=0)}([function(n,e,t){t(1),n.exports=t(3)},function(n,e,t){(function(){var e="undefined"!=typeof window?window.jQuery:t(2);n.exports.ThemeNav={navBar:null,win:null,winScroll:!1,winResize:!1,linkScroll:!1,winPosition:0,winHeight:null,docHeight:null,isRunning:!1,enable:function(n){var t=this;void 0===n&&(n=!0),t.isRunning||(t.isRunning=!0,e((function(e){t.init(e),t.reset(),t.win.on("hashchange",t.reset),n&&t.win.on("scroll",(function(){t.linkScroll||t.winScroll||(t.winScroll=!0,requestAnimationFrame((function(){t.onScroll()})))})),t.win.on("resize",(function(){t.winResize||(t.winResize=!0,requestAnimationFrame((function(){t.onResize()})))})),t.onResize()})))},enableSticky:function(){this.enable(!0)},init:function(n){n(document);var e=this;this.navBar=n("div.wy-side-scroll:first"),this.win=n(window),n(document).on("click","[data-toggle='wy-nav-top']",(function(){n("[data-toggle='wy-nav-shift']").toggleClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift")})).on("click",".wy-menu-vertical .current ul li a",(function(){var t=n(this);n("[data-toggle='wy-nav-shift']").removeClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift"),e.toggleCurrent(t),e.hashChange()})).on("click","[data-toggle='rst-current-version']",(function(){n("[data-toggle='rst-versions']").toggleClass("shift-up")})),n("table.docutils:not(.field-list,.footnote,.citation)").wrap("
"),n("table.docutils.footnote").wrap(""),n("table.docutils.citation").wrap(""),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n(''),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}if(t.length>0){$(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded","false"),t.addClass("current").attr("aria-expanded","true"),t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded","true");for(let n=1;n<=10;n++)t.closest("li.toctree-l"+n).addClass("current").attr("aria-expanded","true");t[0].scrollIntoView()}}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current").attr("aria-expanded","false"),e.siblings().find("li.current").removeClass("current").attr("aria-expanded","false");var t=e.find("> ul li");t.length&&(t.removeClass("current").attr("aria-expanded","false"),e.toggleClass("current").attr("aria-expanded",(function(n,e){return"true"==e?"false":"true"})))}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t
2 |
3 |
4 |
5 |
6 |
7 | flask_memory_process_handler module — Python Clean Architecture example 1.0.0 documentation
8 |
9 |
10 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
51 |
52 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | - flask_memory_process_handler module
63 | -
64 | View page source
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 | flask_memory_process_handler module
74 | Flask In-Memory Process Handler
75 |
76 |
77 |
78 |
79 |
80 |
94 |
95 |
96 |
97 |
98 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/docs/build/html/flask_postgresql_process_handler.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | flask_postgresql_process_handler module — Python Clean Architecture example 1.0.0 documentation
8 |
9 |
10 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
51 |
52 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | - flask_postgresql_process_handler module
63 | -
64 | View page source
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 | flask_postgresql_process_handler module
74 | Flask PostgreSQL Process Handler
75 |
76 |
77 |
78 |
79 |
80 |
94 |
95 |
96 |
97 |
98 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/docs/build/html/objects.inv:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/docs/build/html/objects.inv
--------------------------------------------------------------------------------
/docs/build/html/search.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Search — Python Clean Architecture example 1.0.0 documentation
7 |
8 |
9 |
10 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
53 |
54 |
58 |
59 |
60 |
61 |
62 |
63 |
64 | - Search
65 | -
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
102 |
103 |
104 |
105 |
106 |
111 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
--------------------------------------------------------------------------------
/docs/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | pushd %~dp0
4 |
5 | REM Command file for Sphinx documentation
6 |
7 | if "%SPHINXBUILD%" == "" (
8 | set SPHINXBUILD=sphinx-build
9 | )
10 | set SOURCEDIR=source
11 | set BUILDDIR=build
12 |
13 | %SPHINXBUILD% >NUL 2>NUL
14 | if errorlevel 9009 (
15 | echo.
16 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
17 | echo.installed, then set the SPHINXBUILD environment variable to point
18 | echo.to the full path of the 'sphinx-build' executable. Alternatively you
19 | echo.may add the Sphinx directory to PATH.
20 | echo.
21 | echo.If you don't have Sphinx installed, grab it from
22 | echo.https://www.sphinx-doc.org/
23 | exit /b 1
24 | )
25 |
26 | if "%1" == "" goto help
27 |
28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
29 | goto end
30 |
31 | :help
32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
33 |
34 | :end
35 | popd
36 |
--------------------------------------------------------------------------------
/docs/source/cli_memory_process_handler.rst:
--------------------------------------------------------------------------------
1 | cli\_memory\_process\_handler module
2 | ====================================
3 |
4 | .. automodule:: cli_memory_process_handler
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/conf.py:
--------------------------------------------------------------------------------
1 | # pylint: skip-file
2 | # type: ignore
3 |
4 | # Configuration file for the Sphinx documentation builder.
5 | #
6 | # For the full list of built-in configuration values, see the documentation:
7 | # https://www.sphinx-doc.org/en/master/usage/configuration.html
8 |
9 | # -- Project information -----------------------------------------------------
10 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
11 |
12 | import os
13 | import sys
14 | # Use this line if you chose to separate source and build directories
15 | sys.path.insert(0, os.path.abspath('../..'))
16 | # Use this line if you chose to NOT separate source and build directories
17 | # sys.path.insert(0, os.path.abspath('..'))
18 |
19 |
20 | project = 'Python Clean Architecture example'
21 | copyright = '2023, Claudio Shigueo Watanabe'
22 | author = 'Claudio Shigueo Watanabe'
23 | release = '1.0.0'
24 |
25 | # -- General configuration ---------------------------------------------------
26 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
27 |
28 | extensions = ['sphinx.ext.autodoc']
29 |
30 | templates_path = ['_templates']
31 | exclude_patterns = []
32 |
33 |
34 |
35 | # -- Options for HTML output -------------------------------------------------
36 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
37 |
38 | html_theme = 'sphinx_rtd_theme'
39 | html_static_path = ['_static']
40 |
--------------------------------------------------------------------------------
/docs/source/configs.rst:
--------------------------------------------------------------------------------
1 | configs package
2 | ===============
3 |
4 | Submodules
5 | ----------
6 |
7 | configs.config module
8 | ---------------------
9 |
10 | .. automodule:: configs.config
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | Module contents
16 | ---------------
17 |
18 | .. automodule:: configs
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
--------------------------------------------------------------------------------
/docs/source/flask_memory_process_handler.rst:
--------------------------------------------------------------------------------
1 | flask\_memory\_process\_handler module
2 | ======================================
3 |
4 | .. automodule:: flask_memory_process_handler
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/flask_postgresql_process_handler.rst:
--------------------------------------------------------------------------------
1 | flask\_postgresql\_process\_handler module
2 | ==========================================
3 |
4 | .. automodule:: flask_postgresql_process_handler
5 | :members:
6 | :undoc-members:
7 | :show-inheritance:
8 |
--------------------------------------------------------------------------------
/docs/source/index.rst:
--------------------------------------------------------------------------------
1 | .. Python Clean Architecture example documentation master file, created by
2 | sphinx-quickstart on Thu Jun 8 19:17:15 2023.
3 | You can adapt this file completely to your liking, but it should at least
4 | contain the root `toctree` directive.
5 |
6 | Welcome to Python Clean Architecture example's documentation!
7 | =============================================================
8 |
9 | .. toctree::
10 | :maxdepth: 7
11 | :caption: Contents:
12 |
13 | modules
14 |
15 | Indices and tables
16 | ==================
17 |
18 | * :ref:`genindex`
19 | * :ref:`modindex`
20 | * :ref:`search`
21 |
--------------------------------------------------------------------------------
/docs/source/modules.rst:
--------------------------------------------------------------------------------
1 | python-clean-architecture-example
2 | =================================
3 |
4 | .. toctree::
5 | :maxdepth: 4
6 |
7 | cli_memory_process_handler
8 | configs
9 | flask_memory_process_handler
10 | flask_postgresql_process_handler
11 | src
12 |
--------------------------------------------------------------------------------
/docs/source/src.app.cli_memory.controllers.rst:
--------------------------------------------------------------------------------
1 | src.app.cli\_memory.controllers package
2 | =======================================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.app.cli\_memory.controllers.create\_profession\_controller module
8 | ---------------------------------------------------------------------
9 |
10 | .. automodule:: src.app.cli_memory.controllers.create_profession_controller
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | src.app.cli\_memory.controllers.create\_profession\_controller\_test module
16 | ---------------------------------------------------------------------------
17 |
18 | .. automodule:: src.app.cli_memory.controllers.create_profession_controller_test
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
23 | src.app.cli\_memory.controllers.exit\_controller module
24 | -------------------------------------------------------
25 |
26 | .. automodule:: src.app.cli_memory.controllers.exit_controller
27 | :members:
28 | :undoc-members:
29 | :show-inheritance:
30 |
31 | Module contents
32 | ---------------
33 |
34 | .. automodule:: src.app.cli_memory.controllers
35 | :members:
36 | :undoc-members:
37 | :show-inheritance:
38 |
--------------------------------------------------------------------------------
/docs/source/src.app.cli_memory.presenters.rst:
--------------------------------------------------------------------------------
1 | src.app.cli\_memory.presenters package
2 | ======================================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.app.cli\_memory.presenters.create\_profession\_presenter module
8 | -------------------------------------------------------------------
9 |
10 | .. automodule:: src.app.cli_memory.presenters.create_profession_presenter
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | src.app.cli\_memory.presenters.create\_profession\_presenter\_test module
16 | -------------------------------------------------------------------------
17 |
18 | .. automodule:: src.app.cli_memory.presenters.create_profession_presenter_test
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
23 | Module contents
24 | ---------------
25 |
26 | .. automodule:: src.app.cli_memory.presenters
27 | :members:
28 | :undoc-members:
29 | :show-inheritance:
30 |
--------------------------------------------------------------------------------
/docs/source/src.app.cli_memory.rst:
--------------------------------------------------------------------------------
1 | src.app.cli\_memory package
2 | ===========================
3 |
4 | Subpackages
5 | -----------
6 |
7 | .. toctree::
8 | :maxdepth: 4
9 |
10 | src.app.cli_memory.controllers
11 | src.app.cli_memory.presenters
12 | src.app.cli_memory.views
13 |
14 | Module contents
15 | ---------------
16 |
17 | .. automodule:: src.app.cli_memory
18 | :members:
19 | :undoc-members:
20 | :show-inheritance:
21 |
--------------------------------------------------------------------------------
/docs/source/src.app.cli_memory.views.rst:
--------------------------------------------------------------------------------
1 | src.app.cli\_memory.views package
2 | =================================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.app.cli\_memory.views.create\_profession\_view module
8 | ---------------------------------------------------------
9 |
10 | .. automodule:: src.app.cli_memory.views.create_profession_view
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | src.app.cli\_memory.views.create\_profession\_view\_test module
16 | ---------------------------------------------------------------
17 |
18 | .. automodule:: src.app.cli_memory.views.create_profession_view_test
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
23 | Module contents
24 | ---------------
25 |
26 | .. automodule:: src.app.cli_memory.views
27 | :members:
28 | :undoc-members:
29 | :show-inheritance:
30 |
--------------------------------------------------------------------------------
/docs/source/src.app.flask_memory.blueprints.rst:
--------------------------------------------------------------------------------
1 | src.app.flask\_memory.blueprints package
2 | ========================================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.app.flask\_memory.blueprints.create\_profession\_blueprint module
8 | ---------------------------------------------------------------------
9 |
10 | .. automodule:: src.app.flask_memory.blueprints.create_profession_blueprint
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | Module contents
16 | ---------------
17 |
18 | .. automodule:: src.app.flask_memory.blueprints
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
--------------------------------------------------------------------------------
/docs/source/src.app.flask_memory.controllers.rst:
--------------------------------------------------------------------------------
1 | src.app.flask\_memory.controllers package
2 | =========================================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.app.flask\_memory.controllers.create\_profession\_controller module
8 | -----------------------------------------------------------------------
9 |
10 | .. automodule:: src.app.flask_memory.controllers.create_profession_controller
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | src.app.flask\_memory.controllers.create\_profession\_controller\_test module
16 | -----------------------------------------------------------------------------
17 |
18 | .. automodule:: src.app.flask_memory.controllers.create_profession_controller_test
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
23 | Module contents
24 | ---------------
25 |
26 | .. automodule:: src.app.flask_memory.controllers
27 | :members:
28 | :undoc-members:
29 | :show-inheritance:
30 |
--------------------------------------------------------------------------------
/docs/source/src.app.flask_memory.interfaces.rst:
--------------------------------------------------------------------------------
1 | src.app.flask\_memory.interfaces package
2 | ========================================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.app.flask\_memory.interfaces.flask\_memory\_controller\_interface module
8 | ----------------------------------------------------------------------------
9 |
10 | .. automodule:: src.app.flask_memory.interfaces.flask_memory_controller_interface
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | Module contents
16 | ---------------
17 |
18 | .. automodule:: src.app.flask_memory.interfaces
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
--------------------------------------------------------------------------------
/docs/source/src.app.flask_memory.presenters.rst:
--------------------------------------------------------------------------------
1 | src.app.flask\_memory.presenters package
2 | ========================================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.app.flask\_memory.presenters.create\_profession\_presenter module
8 | ---------------------------------------------------------------------
9 |
10 | .. automodule:: src.app.flask_memory.presenters.create_profession_presenter
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | src.app.flask\_memory.presenters.create\_profession\_presenter\_test module
16 | ---------------------------------------------------------------------------
17 |
18 | .. automodule:: src.app.flask_memory.presenters.create_profession_presenter_test
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
23 | Module contents
24 | ---------------
25 |
26 | .. automodule:: src.app.flask_memory.presenters
27 | :members:
28 | :undoc-members:
29 | :show-inheritance:
30 |
--------------------------------------------------------------------------------
/docs/source/src.app.flask_memory.rst:
--------------------------------------------------------------------------------
1 | src.app.flask\_memory package
2 | =============================
3 |
4 | Subpackages
5 | -----------
6 |
7 | .. toctree::
8 | :maxdepth: 4
9 |
10 | src.app.flask_memory.blueprints
11 | src.app.flask_memory.controllers
12 | src.app.flask_memory.interfaces
13 | src.app.flask_memory.presenters
14 |
15 | Submodules
16 | ----------
17 |
18 | src.app.flask\_memory.create\_flask\_memory\_app module
19 | -------------------------------------------------------
20 |
21 | .. automodule:: src.app.flask_memory.create_flask_memory_app
22 | :members:
23 | :undoc-members:
24 | :show-inheritance:
25 |
26 | src.app.flask\_memory.create\_flask\_memory\_app\_test module
27 | -------------------------------------------------------------
28 |
29 | .. automodule:: src.app.flask_memory.create_flask_memory_app_test
30 | :members:
31 | :undoc-members:
32 | :show-inheritance:
33 |
34 | Module contents
35 | ---------------
36 |
37 | .. automodule:: src.app.flask_memory
38 | :members:
39 | :undoc-members:
40 | :show-inheritance:
41 |
--------------------------------------------------------------------------------
/docs/source/src.app.flask_postgresql.blueprints.rst:
--------------------------------------------------------------------------------
1 | src.app.flask\_postgresql.blueprints package
2 | ============================================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.app.flask\_postgresql.blueprints.create\_profession\_blueprint module
8 | -------------------------------------------------------------------------
9 |
10 | .. automodule:: src.app.flask_postgresql.blueprints.create_profession_blueprint
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | Module contents
16 | ---------------
17 |
18 | .. automodule:: src.app.flask_postgresql.blueprints
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
--------------------------------------------------------------------------------
/docs/source/src.app.flask_postgresql.controllers.rst:
--------------------------------------------------------------------------------
1 | src.app.flask\_postgresql.controllers package
2 | =============================================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.app.flask\_postgresql.controllers.create\_profession\_controller module
8 | ---------------------------------------------------------------------------
9 |
10 | .. automodule:: src.app.flask_postgresql.controllers.create_profession_controller
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | src.app.flask\_postgresql.controllers.create\_profession\_controller\_test module
16 | ---------------------------------------------------------------------------------
17 |
18 | .. automodule:: src.app.flask_postgresql.controllers.create_profession_controller_test
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
23 | Module contents
24 | ---------------
25 |
26 | .. automodule:: src.app.flask_postgresql.controllers
27 | :members:
28 | :undoc-members:
29 | :show-inheritance:
30 |
--------------------------------------------------------------------------------
/docs/source/src.app.flask_postgresql.interfaces.rst:
--------------------------------------------------------------------------------
1 | src.app.flask\_postgresql.interfaces package
2 | ============================================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.app.flask\_postgresql.interfaces.flask\_postgresql\_controller\_interface module
8 | ------------------------------------------------------------------------------------
9 |
10 | .. automodule:: src.app.flask_postgresql.interfaces.flask_postgresql_controller_interface
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | Module contents
16 | ---------------
17 |
18 | .. automodule:: src.app.flask_postgresql.interfaces
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
--------------------------------------------------------------------------------
/docs/source/src.app.flask_postgresql.presenters.rst:
--------------------------------------------------------------------------------
1 | src.app.flask\_postgresql.presenters package
2 | ============================================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.app.flask\_postgresql.presenters.create\_profession\_presenter module
8 | -------------------------------------------------------------------------
9 |
10 | .. automodule:: src.app.flask_postgresql.presenters.create_profession_presenter
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | src.app.flask\_postgresql.presenters.create\_profession\_presenter\_test module
16 | -------------------------------------------------------------------------------
17 |
18 | .. automodule:: src.app.flask_postgresql.presenters.create_profession_presenter_test
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
23 | Module contents
24 | ---------------
25 |
26 | .. automodule:: src.app.flask_postgresql.presenters
27 | :members:
28 | :undoc-members:
29 | :show-inheritance:
30 |
--------------------------------------------------------------------------------
/docs/source/src.app.flask_postgresql.rst:
--------------------------------------------------------------------------------
1 | src.app.flask\_postgresql package
2 | =================================
3 |
4 | Subpackages
5 | -----------
6 |
7 | .. toctree::
8 | :maxdepth: 4
9 |
10 | src.app.flask_postgresql.blueprints
11 | src.app.flask_postgresql.controllers
12 | src.app.flask_postgresql.interfaces
13 | src.app.flask_postgresql.presenters
14 |
15 | Submodules
16 | ----------
17 |
18 | src.app.flask\_postgresql.create\_flask\_postgresql\_app module
19 | ---------------------------------------------------------------
20 |
21 | .. automodule:: src.app.flask_postgresql.create_flask_postgresql_app
22 | :members:
23 | :undoc-members:
24 | :show-inheritance:
25 |
26 | src.app.flask\_postgresql.create\_flask\_postgresql\_app\_test module
27 | ---------------------------------------------------------------------
28 |
29 | .. automodule:: src.app.flask_postgresql.create_flask_postgresql_app_test
30 | :members:
31 | :undoc-members:
32 | :show-inheritance:
33 |
34 | Module contents
35 | ---------------
36 |
37 | .. automodule:: src.app.flask_postgresql
38 | :members:
39 | :undoc-members:
40 | :show-inheritance:
41 |
--------------------------------------------------------------------------------
/docs/source/src.app.rst:
--------------------------------------------------------------------------------
1 | src.app package
2 | ===============
3 |
4 | Subpackages
5 | -----------
6 |
7 | .. toctree::
8 | :maxdepth: 4
9 |
10 | src.app.cli_memory
11 | src.app.flask_memory
12 | src.app.flask_postgresql
13 |
14 | Module contents
15 | ---------------
16 |
17 | .. automodule:: src.app
18 | :members:
19 | :undoc-members:
20 | :show-inheritance:
21 |
--------------------------------------------------------------------------------
/docs/source/src.domain.entities.rst:
--------------------------------------------------------------------------------
1 | src.domain.entities package
2 | ===========================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.domain.entities.profession module
8 | -------------------------------------
9 |
10 | .. automodule:: src.domain.entities.profession
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | src.domain.entities.profession\_test module
16 | -------------------------------------------
17 |
18 | .. automodule:: src.domain.entities.profession_test
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
23 | Module contents
24 | ---------------
25 |
26 | .. automodule:: src.domain.entities
27 | :members:
28 | :undoc-members:
29 | :show-inheritance:
30 |
--------------------------------------------------------------------------------
/docs/source/src.domain.rst:
--------------------------------------------------------------------------------
1 | src.domain package
2 | ==================
3 |
4 | Subpackages
5 | -----------
6 |
7 | .. toctree::
8 | :maxdepth: 4
9 |
10 | src.domain.entities
11 |
12 | Submodules
13 | ----------
14 |
15 | src.domain.value\_objects module
16 | --------------------------------
17 |
18 | .. automodule:: src.domain.value_objects
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
23 | Module contents
24 | ---------------
25 |
26 | .. automodule:: src.domain
27 | :members:
28 | :undoc-members:
29 | :show-inheritance:
30 |
--------------------------------------------------------------------------------
/docs/source/src.infra.db_models.rst:
--------------------------------------------------------------------------------
1 | src.infra.db\_models package
2 | ============================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.infra.db\_models.db\_base module
8 | ------------------------------------
9 |
10 | .. automodule:: src.infra.db_models.db_base
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | src.infra.db\_models.profession\_db\_model module
16 | -------------------------------------------------
17 |
18 | .. automodule:: src.infra.db_models.profession_db_model
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
23 | Module contents
24 | ---------------
25 |
26 | .. automodule:: src.infra.db_models
27 | :members:
28 | :undoc-members:
29 | :show-inheritance:
30 |
--------------------------------------------------------------------------------
/docs/source/src.infra.repositories.rst:
--------------------------------------------------------------------------------
1 | src.infra.repositories package
2 | ==============================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.infra.repositories.profession\_in\_memory\_repository module
8 | ----------------------------------------------------------------
9 |
10 | .. automodule:: src.infra.repositories.profession_in_memory_repository
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | src.infra.repositories.profession\_in\_memory\_repository\_test module
16 | ----------------------------------------------------------------------
17 |
18 | .. automodule:: src.infra.repositories.profession_in_memory_repository_test
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
23 | src.infra.repositories.profession\_postgresql\_repository module
24 | ----------------------------------------------------------------
25 |
26 | .. automodule:: src.infra.repositories.profession_postgresql_repository
27 | :members:
28 | :undoc-members:
29 | :show-inheritance:
30 |
31 | src.infra.repositories.profession\_postgresql\_repository\_test module
32 | ----------------------------------------------------------------------
33 |
34 | .. automodule:: src.infra.repositories.profession_postgresql_repository_test
35 | :members:
36 | :undoc-members:
37 | :show-inheritance:
38 |
39 | Module contents
40 | ---------------
41 |
42 | .. automodule:: src.infra.repositories
43 | :members:
44 | :undoc-members:
45 | :show-inheritance:
46 |
--------------------------------------------------------------------------------
/docs/source/src.infra.rst:
--------------------------------------------------------------------------------
1 | src.infra package
2 | =================
3 |
4 | Subpackages
5 | -----------
6 |
7 | .. toctree::
8 | :maxdepth: 4
9 |
10 | src.infra.db_models
11 | src.infra.repositories
12 |
13 | Module contents
14 | ---------------
15 |
16 | .. automodule:: src.infra
17 | :members:
18 | :undoc-members:
19 | :show-inheritance:
20 |
--------------------------------------------------------------------------------
/docs/source/src.interactor.dtos.rst:
--------------------------------------------------------------------------------
1 | src.interactor.dtos package
2 | ===========================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.interactor.dtos.create\_profession\_dtos module
8 | ---------------------------------------------------
9 |
10 | .. automodule:: src.interactor.dtos.create_profession_dtos
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | src.interactor.dtos.create\_profession\_dtos\_test module
16 | ---------------------------------------------------------
17 |
18 | .. automodule:: src.interactor.dtos.create_profession_dtos_test
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
23 | Module contents
24 | ---------------
25 |
26 | .. automodule:: src.interactor.dtos
27 | :members:
28 | :undoc-members:
29 | :show-inheritance:
30 |
--------------------------------------------------------------------------------
/docs/source/src.interactor.errors.rst:
--------------------------------------------------------------------------------
1 | src.interactor.errors package
2 | =============================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.interactor.errors.error\_classes module
8 | -------------------------------------------
9 |
10 | .. automodule:: src.interactor.errors.error_classes
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | src.interactor.errors.error\_classes\_test module
16 | -------------------------------------------------
17 |
18 | .. automodule:: src.interactor.errors.error_classes_test
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
23 | Module contents
24 | ---------------
25 |
26 | .. automodule:: src.interactor.errors
27 | :members:
28 | :undoc-members:
29 | :show-inheritance:
30 |
--------------------------------------------------------------------------------
/docs/source/src.interactor.interfaces.logger.rst:
--------------------------------------------------------------------------------
1 | src.interactor.interfaces.logger package
2 | ========================================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.interactor.interfaces.logger.logger module
8 | ----------------------------------------------
9 |
10 | .. automodule:: src.interactor.interfaces.logger.logger
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | Module contents
16 | ---------------
17 |
18 | .. automodule:: src.interactor.interfaces.logger
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
--------------------------------------------------------------------------------
/docs/source/src.interactor.interfaces.presenters.rst:
--------------------------------------------------------------------------------
1 | src.interactor.interfaces.presenters package
2 | ============================================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.interactor.interfaces.presenters.create\_profession\_presenter module
8 | -------------------------------------------------------------------------
9 |
10 | .. automodule:: src.interactor.interfaces.presenters.create_profession_presenter
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | Module contents
16 | ---------------
17 |
18 | .. automodule:: src.interactor.interfaces.presenters
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
--------------------------------------------------------------------------------
/docs/source/src.interactor.interfaces.repositories.rst:
--------------------------------------------------------------------------------
1 | src.interactor.interfaces.repositories package
2 | ==============================================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.interactor.interfaces.repositories.profession\_repository module
8 | --------------------------------------------------------------------
9 |
10 | .. automodule:: src.interactor.interfaces.repositories.profession_repository
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | Module contents
16 | ---------------
17 |
18 | .. automodule:: src.interactor.interfaces.repositories
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
--------------------------------------------------------------------------------
/docs/source/src.interactor.interfaces.rst:
--------------------------------------------------------------------------------
1 | src.interactor.interfaces package
2 | =================================
3 |
4 | Subpackages
5 | -----------
6 |
7 | .. toctree::
8 | :maxdepth: 4
9 |
10 | src.interactor.interfaces.logger
11 | src.interactor.interfaces.presenters
12 | src.interactor.interfaces.repositories
13 |
14 | Module contents
15 | ---------------
16 |
17 | .. automodule:: src.interactor.interfaces
18 | :members:
19 | :undoc-members:
20 | :show-inheritance:
21 |
--------------------------------------------------------------------------------
/docs/source/src.interactor.rst:
--------------------------------------------------------------------------------
1 | src.interactor package
2 | ======================
3 |
4 | Subpackages
5 | -----------
6 |
7 | .. toctree::
8 | :maxdepth: 4
9 |
10 | src.interactor.dtos
11 | src.interactor.errors
12 | src.interactor.interfaces
13 | src.interactor.use_cases
14 | src.interactor.validations
15 |
16 | Module contents
17 | ---------------
18 |
19 | .. automodule:: src.interactor
20 | :members:
21 | :undoc-members:
22 | :show-inheritance:
23 |
--------------------------------------------------------------------------------
/docs/source/src.interactor.use_cases.rst:
--------------------------------------------------------------------------------
1 | src.interactor.use\_cases package
2 | =================================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.interactor.use\_cases.create\_profession module
8 | ---------------------------------------------------
9 |
10 | .. automodule:: src.interactor.use_cases.create_profession
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | src.interactor.use\_cases.create\_profession\_test module
16 | ---------------------------------------------------------
17 |
18 | .. automodule:: src.interactor.use_cases.create_profession_test
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
23 | Module contents
24 | ---------------
25 |
26 | .. automodule:: src.interactor.use_cases
27 | :members:
28 | :undoc-members:
29 | :show-inheritance:
30 |
--------------------------------------------------------------------------------
/docs/source/src.interactor.validations.rst:
--------------------------------------------------------------------------------
1 | src.interactor.validations package
2 | ==================================
3 |
4 | Submodules
5 | ----------
6 |
7 | src.interactor.validations.base\_input\_validator module
8 | --------------------------------------------------------
9 |
10 | .. automodule:: src.interactor.validations.base_input_validator
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | src.interactor.validations.base\_input\_validator\_test module
16 | --------------------------------------------------------------
17 |
18 | .. automodule:: src.interactor.validations.base_input_validator_test
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
23 | src.interactor.validations.create\_profession\_validator module
24 | ---------------------------------------------------------------
25 |
26 | .. automodule:: src.interactor.validations.create_profession_validator
27 | :members:
28 | :undoc-members:
29 | :show-inheritance:
30 |
31 | src.interactor.validations.create\_profession\_validator\_test module
32 | ---------------------------------------------------------------------
33 |
34 | .. automodule:: src.interactor.validations.create_profession_validator_test
35 | :members:
36 | :undoc-members:
37 | :show-inheritance:
38 |
39 | Module contents
40 | ---------------
41 |
42 | .. automodule:: src.interactor.validations
43 | :members:
44 | :undoc-members:
45 | :show-inheritance:
46 |
--------------------------------------------------------------------------------
/docs/source/src.rst:
--------------------------------------------------------------------------------
1 | src package
2 | ===========
3 |
4 | Subpackages
5 | -----------
6 |
7 | .. toctree::
8 | :maxdepth: 4
9 |
10 | src.app
11 | src.domain
12 | src.infra
13 | src.interactor
14 |
15 | Submodules
16 | ----------
17 |
18 | src.conftest module
19 | -------------------
20 |
21 | .. automodule:: src.conftest
22 | :members:
23 | :undoc-members:
24 | :show-inheritance:
25 |
26 | Module contents
27 | ---------------
28 |
29 | .. automodule:: src
30 | :members:
31 | :undoc-members:
32 | :show-inheritance:
33 |
--------------------------------------------------------------------------------
/flask_memory_process_handler.py:
--------------------------------------------------------------------------------
1 | """ Flask In-Memory Process Handler
2 | """
3 |
4 |
5 | from src.app.flask_memory.create_flask_memory_app \
6 | import create_flask_memory_app
7 | from src.infra.loggers.logger_default import LoggerDefault
8 |
9 |
10 | logger = LoggerDefault()
11 |
12 |
13 | if __name__ == "__main__":
14 | flask_memory_app = create_flask_memory_app(logger)
15 | flask_memory_app.run(debug=True)
16 |
--------------------------------------------------------------------------------
/flask_postgresql_process_handler.py:
--------------------------------------------------------------------------------
1 | """ Flask PostgreSQL Process Handler
2 | """
3 |
4 |
5 | from src.app.flask_postgresql.create_flask_postgresql_app \
6 | import create_flask_postgresql_app
7 | from src.infra.loggers.logger_default import LoggerDefault
8 |
9 |
10 | logger = LoggerDefault()
11 |
12 |
13 | if __name__ == "__main__":
14 | flask_memory_app = create_flask_postgresql_app(logger)
15 | flask_memory_app.run(debug=True)
16 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | alabaster==0.7.13
2 | alembic==1.11.1
3 | astroid==2.15.3
4 | Babel==2.12.1
5 | blinker==1.6.2
6 | Cerberus==1.3.4
7 | certifi==2023.5.7
8 | cfgv==3.3.1
9 | charset-normalizer==3.1.0
10 | click==8.1.3
11 | colorama==0.4.6
12 | coverage==7.2.3
13 | dill==0.3.6
14 | distlib==0.3.6
15 | docutils==0.18.1
16 | exceptiongroup==1.1.1
17 | filelock==3.12.0
18 | Flask==2.3.2
19 | greenlet==2.0.2
20 | identify==2.5.22
21 | idna==3.4
22 | imagesize==1.4.1
23 | importlib-metadata==6.6.0
24 | iniconfig==2.0.0
25 | install==1.3.5
26 | isort==5.12.0
27 | itsdangerous==2.1.2
28 | Jinja2==3.1.2
29 | lazy-object-proxy==1.9.0
30 | lxml-stubs==0.4.0
31 | Mako==1.2.4
32 | MarkupSafe==2.1.2
33 | mccabe==0.7.0
34 | mypy==1.3.0
35 | mypy-extensions==1.0.0
36 | nodeenv==1.7.0
37 | packaging==23.1
38 | platformdirs==3.2.0
39 | pluggy==1.0.0
40 | pre-commit==3.2.2
41 | psycopg2==2.9.6
42 | Pygments==2.15.1
43 | pylint==2.17.2
44 | pylint-pytest==1.1.2
45 | pytest==7.3.1
46 | pytest-cov==4.0.0
47 | pytest-cover==3.0.0
48 | pytest-coverage==0.0
49 | pytest-flask==1.2.0
50 | pytest-mock==3.10.0
51 | python-dotenv==1.0.0
52 | PyYAML==6.0
53 | requests==2.31.0
54 | six==1.16.0
55 | snowballstemmer==2.2.0
56 | Sphinx==6.2.1
57 | sphinx-rtd-theme==1.2.2
58 | sphinxcontrib-applehelp==1.0.4
59 | sphinxcontrib-devhelp==1.0.2
60 | sphinxcontrib-htmlhelp==2.0.1
61 | sphinxcontrib-jquery==4.1
62 | sphinxcontrib-jsmath==1.0.1
63 | sphinxcontrib-qthelp==1.0.3
64 | sphinxcontrib-serializinghtml==1.1.5
65 | SQLAlchemy==2.0.15
66 | toml==0.10.2
67 | tomli==2.0.1
68 | tomlkit==0.11.7
69 | types-docutils==0.20.0.1
70 | typing_extensions==4.5.0
71 | urllib3==2.0.3
72 | virtualenv==20.22.0
73 | Werkzeug==2.3.4
74 | wrapt==1.15.0
75 | zipp==3.15.0
76 |
--------------------------------------------------------------------------------
/src/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/src/__init__.py
--------------------------------------------------------------------------------
/src/app/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/src/app/__init__.py
--------------------------------------------------------------------------------
/src/app/cli_memory/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/src/app/cli_memory/__init__.py
--------------------------------------------------------------------------------
/src/app/cli_memory/controllers/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/src/app/cli_memory/controllers/__init__.py
--------------------------------------------------------------------------------
/src/app/cli_memory/controllers/create_profession_controller.py:
--------------------------------------------------------------------------------
1 | """Create Profession Controller Module"""
2 |
3 |
4 | from src.interactor.use_cases.create_profession import CreateProfessionUseCase
5 | from src.infra.repositories.profession_in_memory_repository \
6 | import ProfessionInMemoryRepository
7 | from src.interactor.dtos.create_profession_dtos import CreateProfessionInputDto
8 | from src.app.cli_memory.interfaces.cli_memory_controller_interface \
9 | import CliMemoryControllerInterface
10 | from src.interactor.interfaces.logger.logger import LoggerInterface
11 | from ..presenters.create_profession_presenter import CreateProfessionPresenter
12 | from ..views.create_profession_view import CreateProfessionView
13 |
14 |
15 | class CreateProfessionController(CliMemoryControllerInterface):
16 | """ Create Profession Controller Class
17 | """
18 | def __init__(self, logger: LoggerInterface):
19 | self.logger = logger
20 |
21 | def _get_profession_info(self) -> CreateProfessionInputDto:
22 | name = input("Enter the profession name:")
23 | description = input("Enter the profession description:")
24 | return CreateProfessionInputDto(name, description)
25 |
26 | def execute(self):
27 | """ Execute the create profession controller
28 | """
29 | repository = ProfessionInMemoryRepository()
30 | presenter = CreateProfessionPresenter()
31 | input_dto = self._get_profession_info()
32 | use_case = CreateProfessionUseCase(presenter, repository, self.logger)
33 | result = use_case.execute(input_dto)
34 | view = CreateProfessionView()
35 | view.show(result)
36 |
--------------------------------------------------------------------------------
/src/app/cli_memory/controllers/create_profession_controller_test.py:
--------------------------------------------------------------------------------
1 | # pylint: disable=missing-module-docstring
2 | # pylint: disable=missing-class-docstring
3 | # pylint: disable=missing-function-docstring
4 |
5 |
6 | from src.app.cli_memory.controllers.create_profession_controller \
7 | import CreateProfessionController
8 | from src.interactor.dtos.create_profession_dtos import CreateProfessionInputDto
9 | from src.interactor.interfaces.logger.logger import LoggerInterface
10 |
11 |
12 | def test_create_profession(monkeypatch, mocker, fixture_profession_developer):
13 | name = fixture_profession_developer["name"]
14 | description = fixture_profession_developer["description"]
15 | fake_user_inputs = iter([name, description])
16 | monkeypatch.setattr('builtins.input', lambda _: next(fake_user_inputs))
17 |
18 | mock_repository = mocker.patch(
19 | 'src.app.cli_memory.controllers.create_profession_controller.\
20 | ProfessionInMemoryRepository')
21 | mock_presenter = mocker.patch(
22 | 'src.app.cli_memory.controllers.create_profession_controller.\
23 | CreateProfessionPresenter')
24 | mock_use_case = mocker.patch(
25 | 'src.app.cli_memory.controllers.create_profession_controller.\
26 | CreateProfessionUseCase')
27 | mock_use_case_instance = mock_use_case.return_value
28 | mock_view = mocker.patch(
29 | 'src.app.cli_memory.controllers.create_profession_controller.\
30 | CreateProfessionView')
31 | logger_mock = mocker.patch.object(
32 | LoggerInterface,
33 | "log_info"
34 | )
35 | result_use_case = {
36 | "profession_id": fixture_profession_developer["profession_id"],
37 | "name": fixture_profession_developer["name"],
38 | "description": fixture_profession_developer["description"]
39 | }
40 | mock_use_case_instance.execute.return_value = result_use_case
41 | mock_view_instance = mock_view.return_value
42 |
43 | controller = CreateProfessionController(logger_mock)
44 | controller.execute()
45 |
46 | mock_repository.assert_called_once_with()
47 | mock_presenter.assert_called_once_with()
48 | mock_use_case.assert_called_once_with(
49 | mock_presenter.return_value,
50 | mock_repository.return_value,
51 | logger_mock
52 | )
53 | input_dto = CreateProfessionInputDto(name, description)
54 | mock_use_case_instance.execute.assert_called_once_with(input_dto)
55 | mock_view_instance.show.assert_called_once_with(result_use_case)
56 |
--------------------------------------------------------------------------------
/src/app/cli_memory/controllers/exit_controller.py:
--------------------------------------------------------------------------------
1 | """ This module contains the ExitController class
2 | """
3 |
4 |
5 | import sys
6 | from src.app.cli_memory.interfaces.cli_memory_controller_interface \
7 | import CliMemoryControllerInterface
8 |
9 |
10 | class ExitController(CliMemoryControllerInterface):
11 | """ This class is a controller for exiting the program
12 | """
13 | def execute(self):
14 | """ This method executes the controller, exiting the program
15 | """
16 | print("Exiting the program")
17 | sys.exit()
18 |
--------------------------------------------------------------------------------
/src/app/cli_memory/interfaces/cli_memory_controller_interface.py:
--------------------------------------------------------------------------------
1 | """ This module contains the CliMemoryControllerInterface class
2 | """
3 |
4 |
5 | from abc import ABC, abstractmethod
6 |
7 |
8 | class CliMemoryControllerInterface(ABC):
9 | """ This class is the interface for the CliMemoryController class
10 | """
11 | @abstractmethod
12 | def execute(self):
13 | """ Executes the controller
14 | """
15 |
--------------------------------------------------------------------------------
/src/app/cli_memory/presenters/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/src/app/cli_memory/presenters/__init__.py
--------------------------------------------------------------------------------
/src/app/cli_memory/presenters/create_profession_presenter.py:
--------------------------------------------------------------------------------
1 | """ Module for the CreateProfessionPresenter
2 | """
3 |
4 |
5 | from typing import Dict
6 | from src.interactor.dtos.create_profession_dtos \
7 | import CreateProfessionOutputDto
8 | from src.interactor.interfaces.presenters.create_profession_presenter \
9 | import CreateProfessionPresenterInterface
10 |
11 |
12 | class CreateProfessionPresenter(CreateProfessionPresenterInterface):
13 | """ Class for the CreateProfessionPresenter
14 | """
15 | def present(self, output_dto: CreateProfessionOutputDto) -> Dict:
16 | """ Present the CreateProfession
17 | :param output_dto: CreateProfessionOutputDto
18 | :return: Dict
19 | """
20 | return {
21 | "profession_id": output_dto.profession.profession_id,
22 | "name": output_dto.profession.name,
23 | "description": output_dto.profession.description
24 | }
25 |
--------------------------------------------------------------------------------
/src/app/cli_memory/presenters/create_profession_presenter_test.py:
--------------------------------------------------------------------------------
1 | # pylint: disable=missing-module-docstring
2 | # pylint: disable=missing-class-docstring
3 | # pylint: disable=missing-function-docstring
4 |
5 |
6 | from src.interactor.dtos.create_profession_dtos \
7 | import CreateProfessionOutputDto
8 | from src.domain.entities.profession import Profession
9 | from .create_profession_presenter import CreateProfessionPresenter
10 |
11 |
12 | def test_create_profession_presenter(fixture_profession_developer):
13 | profession = Profession(
14 | profession_id=fixture_profession_developer["profession_id"],
15 | name=fixture_profession_developer["name"],
16 | description=fixture_profession_developer["description"]
17 | )
18 | output_dto = CreateProfessionOutputDto(profession)
19 | presenter = CreateProfessionPresenter()
20 | assert presenter.present(output_dto) == {
21 | "profession_id": fixture_profession_developer["profession_id"],
22 | "name": fixture_profession_developer["name"],
23 | "description": fixture_profession_developer["description"]
24 | }
25 |
--------------------------------------------------------------------------------
/src/app/cli_memory/views/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/src/app/cli_memory/views/__init__.py
--------------------------------------------------------------------------------
/src/app/cli_memory/views/create_profession_view.py:
--------------------------------------------------------------------------------
1 | """ Create profession view Module """
2 |
3 |
4 | from typing import Dict
5 |
6 |
7 | class CreateProfessionView:
8 | """ Create profession view Class """
9 | def show(self, data: Dict) -> None:
10 | """ Show profession view
11 | :param data: data to show
12 | :return: None
13 | """
14 | print(data)
15 |
--------------------------------------------------------------------------------
/src/app/cli_memory/views/create_profession_view_test.py:
--------------------------------------------------------------------------------
1 | # pylint: disable=missing-module-docstring
2 | # pylint: disable=missing-class-docstring
3 | # pylint: disable=missing-function-docstring
4 |
5 |
6 | from .create_profession_view import CreateProfessionView
7 |
8 |
9 | def test_create_profession_presenter(capsys, fixture_profession_developer):
10 | profession_dict = {
11 | "profession_id": fixture_profession_developer["profession_id"],
12 | "name": fixture_profession_developer["name"],
13 | "description": fixture_profession_developer["description"]
14 | }
15 | view = CreateProfessionView()
16 | view.show(profession_dict)
17 | captured = capsys.readouterr()
18 | assert captured.out == str(profession_dict) + "\n"
19 |
--------------------------------------------------------------------------------
/src/app/flask_memory/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/src/app/flask_memory/__init__.py
--------------------------------------------------------------------------------
/src/app/flask_memory/blueprints/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/src/app/flask_memory/blueprints/__init__.py
--------------------------------------------------------------------------------
/src/app/flask_memory/blueprints/create_profession_blueprint.py:
--------------------------------------------------------------------------------
1 | """ Flask Blueprint Create Profession
2 | """
3 |
4 |
5 | from flask import Blueprint, request, current_app
6 | from src.app.flask_memory.controllers.create_profession_controller import \
7 | CreateProfessionController
8 |
9 |
10 | blueprint_create_profession = Blueprint('create_profession', __name__)
11 |
12 |
13 | @blueprint_create_profession.route('/profession/', methods=["POST"])
14 | def create_profession_blueprint():
15 | """ Create Profession Blueprint
16 | """
17 | logger = current_app.config['logger']
18 | input_json = request.get_json(force=True)
19 | controller = CreateProfessionController(logger)
20 | controller.get_profession_info(input_json)
21 | result = controller.execute()
22 | return result
23 |
--------------------------------------------------------------------------------
/src/app/flask_memory/controllers/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/src/app/flask_memory/controllers/__init__.py
--------------------------------------------------------------------------------
/src/app/flask_memory/controllers/create_profession_controller.py:
--------------------------------------------------------------------------------
1 | """Create Profession Controller Module"""
2 |
3 |
4 | from typing import Dict
5 | from src.interactor.use_cases.create_profession import CreateProfessionUseCase
6 | from src.infra.repositories.profession_in_memory_repository \
7 | import ProfessionInMemoryRepository
8 | from src.interactor.dtos.create_profession_dtos import CreateProfessionInputDto
9 | from src.app.flask_memory.interfaces.flask_memory_controller_interface \
10 | import FlaskMemoryControllerInterface
11 | from src.interactor.interfaces.logger.logger import LoggerInterface
12 | from src.app.flask_memory.presenters.create_profession_presenter import \
13 | CreateProfessionPresenter
14 |
15 |
16 | class CreateProfessionController(FlaskMemoryControllerInterface):
17 | """ Create Profession Controller Class
18 | """
19 | def __init__(self, logger: LoggerInterface):
20 | self.logger = logger
21 | self.input_dto: CreateProfessionInputDto
22 |
23 | def get_profession_info(self, json_input) -> None:
24 | """ Get Profession Info
25 | :param json_input: Input data
26 | :raises: ValueError if profession name or description are missing.
27 | """
28 | if "name" in json_input:
29 | name = json_input["name"]
30 | else:
31 | raise ValueError("Missing Profession Name")
32 | if "description" in json_input:
33 | description = json_input["description"]
34 | else:
35 | raise ValueError("Missing Profession Description")
36 | self.input_dto = CreateProfessionInputDto(name, description)
37 |
38 | def execute(self) -> Dict:
39 | """ Execute the create profession controller
40 | :returns: Profession created
41 | """
42 | repository = ProfessionInMemoryRepository()
43 | presenter = CreateProfessionPresenter()
44 | use_case = CreateProfessionUseCase(presenter, repository, self.logger)
45 | result = use_case.execute(self.input_dto)
46 | return result
47 |
--------------------------------------------------------------------------------
/src/app/flask_memory/controllers/create_profession_controller_test.py:
--------------------------------------------------------------------------------
1 | # pylint: disable=missing-module-docstring
2 | # pylint: disable=missing-class-docstring
3 | # pylint: disable=missing-function-docstring
4 |
5 |
6 | import pytest
7 | from src.app.flask_memory.controllers.create_profession_controller \
8 | import CreateProfessionController
9 | from src.interactor.dtos.create_profession_dtos import CreateProfessionInputDto
10 | from src.interactor.interfaces.logger.logger import LoggerInterface
11 |
12 |
13 | def test_create_profession(monkeypatch, mocker, fixture_profession_developer):
14 | name = fixture_profession_developer["name"]
15 | description = fixture_profession_developer["description"]
16 | fake_user_inputs = {
17 | "name": name,
18 | "description": description
19 | }
20 | monkeypatch.setattr('builtins.input', lambda _: next(fake_user_inputs))
21 |
22 | mock_repository = mocker.patch(
23 | 'src.app.flask_memory.controllers.create_profession_controller.\
24 | ProfessionInMemoryRepository')
25 | mock_presenter = mocker.patch(
26 | 'src.app.flask_memory.controllers.create_profession_controller.\
27 | CreateProfessionPresenter')
28 | mock_use_case = mocker.patch(
29 | 'src.app.flask_memory.controllers.create_profession_controller.\
30 | CreateProfessionUseCase')
31 | mock_use_case_instance = mock_use_case.return_value
32 | logger_mock = mocker.patch.object(
33 | LoggerInterface,
34 | "log_info"
35 | )
36 | result_use_case = {
37 | "profession_id": fixture_profession_developer["profession_id"],
38 | "name": fixture_profession_developer["name"],
39 | "description": fixture_profession_developer["description"]
40 | }
41 | mock_use_case_instance.execute.return_value = result_use_case
42 |
43 | controller = CreateProfessionController(logger_mock)
44 | controller.get_profession_info(fake_user_inputs)
45 | result = controller.execute()
46 |
47 | mock_repository.assert_called_once_with()
48 | mock_presenter.assert_called_once_with()
49 | mock_use_case.assert_called_once_with(
50 | mock_presenter.return_value,
51 | mock_repository.return_value,
52 | logger_mock
53 | )
54 | input_dto = CreateProfessionInputDto(name, description)
55 | mock_use_case_instance.execute.assert_called_once_with(input_dto)
56 | assert result["name"] == name
57 | assert result["description"] == description
58 |
59 | # Test for missing inputs (name)
60 | fake_user_inputs = {
61 | "nam": name,
62 | "description": description
63 | }
64 | with pytest.raises(ValueError) as exception_info:
65 | controller.get_profession_info(fake_user_inputs)
66 | assert str(exception_info.value) == "Missing Profession Name"
67 |
68 | # Test for missing inputs (description)
69 | fake_user_inputs = {
70 | "name": name,
71 | "descriptio": description
72 | }
73 | with pytest.raises(ValueError) as exception_info:
74 | controller.get_profession_info(fake_user_inputs)
75 | assert str(exception_info.value) == "Missing Profession Description"
76 |
--------------------------------------------------------------------------------
/src/app/flask_memory/create_flask_memory_app.py:
--------------------------------------------------------------------------------
1 | """ Main Flask In-Memory app
2 | """
3 |
4 |
5 | from flask import Flask
6 | from werkzeug.exceptions import HTTPException
7 | from src.app.flask_memory.blueprints.create_profession_blueprint \
8 | import blueprint_create_profession
9 | from src.interactor.interfaces.logger.logger import LoggerInterface
10 | from src.interactor.errors.error_classes \
11 | import FieldValueNotPermittedException
12 |
13 |
14 | def format_error_response(
15 | error: Exception,
16 | error_code: int,
17 | logger: LoggerInterface
18 | ):
19 | """ Format Error Response """
20 | logger.log_exception(f"500 - Internal Server Error: {str(error)}")
21 |
22 | response = {
23 | 'status_code': error_code,
24 | 'error': error.__class__.__name__,
25 | 'message': str(error)
26 | }
27 | return response, error_code
28 |
29 |
30 | def create_flask_memory_app(logger: LoggerInterface):
31 | """ Create Main Flask In-Memory app
32 | """
33 | app = Flask(__name__)
34 | app.config['logger'] = logger
35 | app.register_blueprint(blueprint_create_profession, url_prefix='/v1')
36 |
37 | @app.errorhandler(HTTPException)
38 | def handle_http_error(error: HTTPException):
39 | """ Handle HTTP Error Response """
40 | logger.log_exception(str(error.__class__.__name__))
41 | logger.log_exception(str(error.description))
42 | response = {
43 | 'error': error.__class__.__name__,
44 | 'message': error.description,
45 | }
46 | return response, error.code
47 |
48 | @app.errorhandler(ValueError)
49 | def handle_value_error(error: ValueError):
50 | """ Handle Value Error Response """
51 | return format_error_response(error, 400, logger)
52 |
53 | @app.errorhandler(FieldValueNotPermittedException)
54 | def handle_field_not_permitted_error(error: ValueError):
55 | """ Handle Value Error Response """
56 | return format_error_response(error, 400, logger)
57 |
58 | @app.errorhandler(Exception)
59 | def handle_general_exception(error):
60 | """ Handle Other Errors Response """
61 | return format_error_response(error, 500, logger)
62 |
63 | return app
64 |
--------------------------------------------------------------------------------
/src/app/flask_memory/create_flask_memory_app_test.py:
--------------------------------------------------------------------------------
1 | # pylint: disable=missing-module-docstring
2 | # pylint: disable=missing-class-docstring
3 | # pylint: disable=missing-function-docstring
4 |
5 |
6 | import pytest
7 | from src.infra.loggers.logger_default import LoggerDefault
8 | from src.app.flask_memory.controllers.create_profession_controller import \
9 | CreateProfessionController
10 | from .create_flask_memory_app import create_flask_memory_app
11 |
12 |
13 | logger = LoggerDefault()
14 |
15 |
16 | @pytest.fixture(name="app_flask_memory_app")
17 | def fixture_app_flask_memory_app():
18 | """ Fixture for flask app with blueprint
19 | """
20 | app = create_flask_memory_app(logger)
21 | app.config.update({
22 | "TESTING": True,
23 | })
24 |
25 | yield app
26 |
27 |
28 | @pytest.fixture(name="client_flask_memory_app")
29 | def fixture_client_flask_memory_app(app_flask_memory_app):
30 | """ Fixture to test app_flask_with_blueprint
31 | """
32 | return app_flask_memory_app.test_client()
33 |
34 |
35 | def test_request_profession(
36 | client_flask_memory_app,
37 | fixture_profession_developer
38 | ):
39 | """ Test request example
40 | """
41 | input_data = {
42 | "name": fixture_profession_developer["name"],
43 | "description": fixture_profession_developer["description"]
44 | }
45 | response = client_flask_memory_app.post("/v1/profession/", json=input_data)
46 | assert b"Developer" in response.data
47 | assert b"Developer is a person that write software code" in response.data
48 |
49 |
50 | def test_request_profession_missing_name_error(
51 | client_flask_memory_app,
52 | fixture_profession_developer
53 | ):
54 | """ Test request example
55 | """
56 | input_data = {
57 | "nam": fixture_profession_developer["name"],
58 | "description": fixture_profession_developer["description"]
59 | }
60 | response = client_flask_memory_app.post("/v1/profession/", json=input_data)
61 | assert b"Missing Profession Name" in response.data
62 |
63 |
64 | def test_request_profession_invalid_name_error(
65 | client_flask_memory_app,
66 | fixture_profession_developer
67 | ):
68 | """ Test request invalid name
69 | """
70 | input_data = {
71 | "name": "Profession",
72 | "description": fixture_profession_developer["description"]
73 | }
74 | response = client_flask_memory_app.post("/v1/profession/", json=input_data)
75 | assert b"Name: Profession is not permitted" in response.data
76 |
77 |
78 | def test_request_profession_wrong_url_error(
79 | client_flask_memory_app,
80 | fixture_profession_developer
81 | ):
82 | """ Test request HTTPException error
83 | """
84 | input_data = {
85 | "name": fixture_profession_developer["name"],
86 | "description": fixture_profession_developer["description"]
87 | }
88 | response = client_flask_memory_app.post("/v1/professio/", json=input_data)
89 | assert b"The requested URL was not found on the server" in response.data
90 |
91 |
92 | def test_request_profession_500_status_code(
93 | client_flask_memory_app,
94 | fixture_profession_developer,
95 | mocker
96 | ):
97 | """ Test handling of exception that should return a 500 status code
98 | """
99 | blueprint_mock = mocker.patch.object(
100 | CreateProfessionController,
101 | "get_profession_info"
102 | )
103 | blueprint_mock.side_effect = Exception('Unexpected error!')
104 | input_data = {
105 | "name": fixture_profession_developer["name"],
106 | "description": fixture_profession_developer["description"]
107 | }
108 | response = client_flask_memory_app.post("/v1/profession/", json=input_data)
109 | assert b'"status_code":500' in response.data
110 |
--------------------------------------------------------------------------------
/src/app/flask_memory/interfaces/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/src/app/flask_memory/interfaces/__init__.py
--------------------------------------------------------------------------------
/src/app/flask_memory/interfaces/flask_memory_controller_interface.py:
--------------------------------------------------------------------------------
1 | """ This module contains the FlaskMemoryControllerInterface class
2 | """
3 |
4 |
5 | from typing import Dict
6 | from abc import ABC, abstractmethod
7 |
8 |
9 | class FlaskMemoryControllerInterface(ABC):
10 | """ This class is the interface for the Flask Memory Controller class
11 | """
12 |
13 | def get_profession_info(self, json_input) -> None:
14 | """ Get Profession Info
15 | :param json_input: Input data
16 | :raises: ValueError if profession name or description are missing.
17 | """
18 |
19 | @abstractmethod
20 | def execute(self) -> Dict:
21 | """ Executes the controller
22 | :returns: Profession created
23 | """
24 |
--------------------------------------------------------------------------------
/src/app/flask_memory/presenters/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/src/app/flask_memory/presenters/__init__.py
--------------------------------------------------------------------------------
/src/app/flask_memory/presenters/create_profession_presenter.py:
--------------------------------------------------------------------------------
1 | """ Module for the CreateProfessionPresenter
2 | """
3 |
4 |
5 | from typing import Dict
6 | from src.interactor.dtos.create_profession_dtos \
7 | import CreateProfessionOutputDto
8 | from src.interactor.interfaces.presenters.create_profession_presenter \
9 | import CreateProfessionPresenterInterface
10 |
11 |
12 | class CreateProfessionPresenter(CreateProfessionPresenterInterface):
13 | """ Class for the CreateProfessionPresenter
14 | """
15 | def present(self, output_dto: CreateProfessionOutputDto) -> Dict:
16 | """ Present the CreateProfession
17 | :param output_dto: CreateProfessionOutputDto
18 | :return: Dict
19 | """
20 | return {
21 | "profession_id": output_dto.profession.profession_id,
22 | "name": output_dto.profession.name,
23 | "description": output_dto.profession.description
24 | }
25 |
--------------------------------------------------------------------------------
/src/app/flask_memory/presenters/create_profession_presenter_test.py:
--------------------------------------------------------------------------------
1 | # pylint: disable=missing-module-docstring
2 | # pylint: disable=missing-class-docstring
3 | # pylint: disable=missing-function-docstring
4 |
5 |
6 | from src.interactor.dtos.create_profession_dtos \
7 | import CreateProfessionOutputDto
8 | from src.domain.entities.profession import Profession
9 | from .create_profession_presenter import CreateProfessionPresenter
10 |
11 |
12 | def test_create_profession_presenter(fixture_profession_developer):
13 | profession = Profession(
14 | profession_id=fixture_profession_developer["profession_id"],
15 | name=fixture_profession_developer["name"],
16 | description=fixture_profession_developer["description"]
17 | )
18 | output_dto = CreateProfessionOutputDto(profession)
19 | presenter = CreateProfessionPresenter()
20 | assert presenter.present(output_dto) == {
21 | "profession_id": fixture_profession_developer["profession_id"],
22 | "name": fixture_profession_developer["name"],
23 | "description": fixture_profession_developer["description"]
24 | }
25 |
--------------------------------------------------------------------------------
/src/app/flask_postgresql/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/src/app/flask_postgresql/__init__.py
--------------------------------------------------------------------------------
/src/app/flask_postgresql/blueprints/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/src/app/flask_postgresql/blueprints/__init__.py
--------------------------------------------------------------------------------
/src/app/flask_postgresql/blueprints/create_profession_blueprint.py:
--------------------------------------------------------------------------------
1 | """ Flask PostgreSQL Blueprint Create Profession
2 | """
3 |
4 |
5 | from flask import jsonify
6 | from flask import Blueprint, request, current_app
7 | from src.app.flask_postgresql.controllers.create_profession_controller import \
8 | CreateProfessionController
9 |
10 |
11 | blueprint_create_profession = Blueprint('create_profession', __name__)
12 |
13 |
14 | @blueprint_create_profession.route('/profession/', methods=["POST"])
15 | def create_profession_blueprint():
16 | """ Create Profession Blueprint
17 | """
18 | logger = current_app.config['logger']
19 | input_json = request.get_json(force=True)
20 | controller = CreateProfessionController(logger)
21 | controller.get_profession_info(input_json)
22 | result = controller.execute()
23 | return jsonify(result), 201
24 |
--------------------------------------------------------------------------------
/src/app/flask_postgresql/controllers/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/src/app/flask_postgresql/controllers/__init__.py
--------------------------------------------------------------------------------
/src/app/flask_postgresql/controllers/create_profession_controller.py:
--------------------------------------------------------------------------------
1 | """Create Profession Controller Module"""
2 |
3 |
4 | from typing import Dict
5 | from src.interactor.use_cases.create_profession import CreateProfessionUseCase
6 | from src.infra.repositories.profession_postgresql_repository \
7 | import ProfessionPostgresqlRepository
8 | from src.interactor.dtos.create_profession_dtos import CreateProfessionInputDto
9 | from src.app.flask_postgresql.interfaces.flask_postgresql_controller_interface\
10 | import FlaskPostgresqlControllerInterface
11 | from src.interactor.interfaces.logger.logger import LoggerInterface
12 | from src.app.flask_postgresql.presenters.create_profession_presenter import \
13 | CreateProfessionPresenter
14 |
15 |
16 | class CreateProfessionController(FlaskPostgresqlControllerInterface):
17 | """ Create Profession Controller Class
18 | """
19 | def __init__(self, logger: LoggerInterface):
20 | self.logger = logger
21 | self.input_dto: CreateProfessionInputDto
22 |
23 | def get_profession_info(self, json_input) -> None:
24 | """ Get Profession Info
25 | :param json_input: Input data
26 | :raises: ValueError if profession name or description are missing.
27 | """
28 | if "name" in json_input:
29 | name = json_input["name"]
30 | else:
31 | raise ValueError("Missing Profession Name")
32 | if "description" in json_input:
33 | description = json_input["description"]
34 | else:
35 | raise ValueError("Missing Profession Description")
36 | self.input_dto = CreateProfessionInputDto(name, description)
37 |
38 | def execute(self) -> Dict:
39 | """ Execute the create profession controller
40 | :returns: Profession created
41 | """
42 | repository = ProfessionPostgresqlRepository()
43 | presenter = CreateProfessionPresenter()
44 | use_case = CreateProfessionUseCase(presenter, repository, self.logger)
45 | result = use_case.execute(self.input_dto)
46 | return result
47 |
--------------------------------------------------------------------------------
/src/app/flask_postgresql/controllers/create_profession_controller_test.py:
--------------------------------------------------------------------------------
1 | # pylint: disable=missing-module-docstring
2 | # pylint: disable=missing-class-docstring
3 | # pylint: disable=missing-function-docstring
4 |
5 |
6 | import pytest
7 | from unittest import mock
8 | from src.interactor.dtos.create_profession_dtos import CreateProfessionInputDto
9 | from src.interactor.interfaces.logger.logger import LoggerInterface
10 |
11 | with mock.patch(
12 | "sqlalchemy.create_engine"
13 | ) as mock_create_engine:
14 | from src.app.flask_postgresql.controllers.create_profession_controller \
15 | import CreateProfessionController
16 |
17 |
18 | def test_create_profession(monkeypatch, mocker, fixture_profession_developer):
19 | name = fixture_profession_developer["name"]
20 | description = fixture_profession_developer["description"]
21 | fake_user_inputs = {
22 | "name": name,
23 | "description": description
24 | }
25 | monkeypatch.setattr('builtins.input', lambda _: next(fake_user_inputs))
26 |
27 | mock_repository = mocker.patch(
28 | 'src.app.flask_postgresql.controllers.create_profession_controller.\
29 | ProfessionPostgresqlRepository')
30 | mock_presenter = mocker.patch(
31 | 'src.app.flask_postgresql.controllers.create_profession_controller.\
32 | CreateProfessionPresenter')
33 | mock_use_case = mocker.patch(
34 | 'src.app.flask_postgresql.controllers.create_profession_controller.\
35 | CreateProfessionUseCase')
36 | mock_use_case_instance = mock_use_case.return_value
37 | logger_mock = mocker.patch.object(
38 | LoggerInterface,
39 | "log_info"
40 | )
41 | result_use_case = {
42 | "profession_id": fixture_profession_developer["profession_id"],
43 | "name": fixture_profession_developer["name"],
44 | "description": fixture_profession_developer["description"]
45 | }
46 | mock_use_case_instance.execute.return_value = result_use_case
47 |
48 | controller = CreateProfessionController(logger_mock)
49 | controller.get_profession_info(fake_user_inputs)
50 | result = controller.execute()
51 |
52 | mock_repository.assert_called_once_with()
53 | mock_presenter.assert_called_once_with()
54 | mock_use_case.assert_called_once_with(
55 | mock_presenter.return_value,
56 | mock_repository.return_value,
57 | logger_mock
58 | )
59 | input_dto = CreateProfessionInputDto(name, description)
60 | mock_use_case_instance.execute.assert_called_once_with(input_dto)
61 | assert result["name"] == name
62 | assert result["description"] == description
63 |
64 | # Test for missing inputs (name)
65 | fake_user_inputs = {
66 | "nam": name,
67 | "description": description
68 | }
69 | with pytest.raises(ValueError) as exception_info:
70 | controller.get_profession_info(fake_user_inputs)
71 | assert str(exception_info.value) == "Missing Profession Name"
72 |
73 | # Test for missing inputs (description)
74 | fake_user_inputs = {
75 | "name": name,
76 | "descriptio": description
77 | }
78 | with pytest.raises(ValueError) as exception_info:
79 | controller.get_profession_info(fake_user_inputs)
80 | assert str(exception_info.value) == "Missing Profession Description"
81 |
--------------------------------------------------------------------------------
/src/app/flask_postgresql/create_flask_postgresql_app.py:
--------------------------------------------------------------------------------
1 | """ Main Flask PostgreSQL app
2 | """
3 |
4 |
5 | from flask import Flask, g
6 | from werkzeug.exceptions import HTTPException
7 | from src.app.flask_postgresql.blueprints.create_profession_blueprint \
8 | import blueprint_create_profession
9 | from src.interactor.interfaces.logger.logger import LoggerInterface
10 | from src.interactor.errors.error_classes \
11 | import FieldValueNotPermittedException
12 | from src.infra.db_models.db_base import Session
13 | from src.interactor.errors.error_classes import UniqueViolationError
14 |
15 |
16 | def format_error_response(
17 | error: Exception,
18 | error_code: int,
19 | logger: LoggerInterface
20 | ):
21 | """ Format Error Response """
22 | logger.log_exception(f"500 - Internal Server Error: {str(error)}")
23 |
24 | response = {
25 | 'status_code': error_code,
26 | 'error': error.__class__.__name__,
27 | 'message': str(error)
28 | }
29 | return response, error_code
30 |
31 |
32 | def create_flask_postgresql_app(logger: LoggerInterface):
33 | """ Create Main Flask PostgreSQL app
34 | """
35 | app = Flask(__name__)
36 | app.config['logger'] = logger
37 | app.register_blueprint(blueprint_create_profession, url_prefix='/v1')
38 |
39 | @app.errorhandler(HTTPException)
40 | def handle_http_error(error: HTTPException):
41 | """ Handle HTTP Error Response """
42 | logger.log_exception(str(error.__class__.__name__))
43 | logger.log_exception(str(error.description))
44 | response = {
45 | 'error': error.__class__.__name__,
46 | 'message': error.description,
47 | }
48 | return response, error.code
49 |
50 | @app.errorhandler(ValueError)
51 | def handle_value_error(error: ValueError):
52 | """ Handle Value Error Response """
53 | return format_error_response(error, 400, logger)
54 |
55 | @app.errorhandler(FieldValueNotPermittedException)
56 | def handle_field_not_permitted_error(
57 | error: FieldValueNotPermittedException
58 | ):
59 | """ Handle Value Error Response """
60 | return format_error_response(error, 400, logger)
61 |
62 | @app.errorhandler(UniqueViolationError)
63 | def handle_unique_violation_error(error: UniqueViolationError):
64 | """ Handle Unique Violation Error Response """
65 | return format_error_response(error, 409, logger)
66 |
67 | @app.errorhandler(Exception)
68 | def handle_general_exception(error):
69 | """ Handle Other Errors Response """
70 | return format_error_response(error, 500, logger)
71 |
72 | @app.before_request
73 | def before_request():
74 | """ Before Request """
75 | g.db = Session()
76 |
77 | @app.teardown_request
78 | def teardown_request(_unused=False):
79 | """ After Request """
80 | dbc = getattr(g, 'db', None)
81 | if dbc is not None:
82 | dbc.close()
83 |
84 | return app
85 |
--------------------------------------------------------------------------------
/src/app/flask_postgresql/interfaces/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/src/app/flask_postgresql/interfaces/__init__.py
--------------------------------------------------------------------------------
/src/app/flask_postgresql/interfaces/flask_postgresql_controller_interface.py:
--------------------------------------------------------------------------------
1 | """ This module contains the FlaskPostgresqlControllerInterface class
2 | """
3 |
4 |
5 | from typing import Dict
6 | from abc import ABC, abstractmethod
7 |
8 |
9 | class FlaskPostgresqlControllerInterface(ABC):
10 | """ This class is the interface for the Flask Postgresql Controller class
11 | """
12 |
13 | def get_profession_info(self, json_input) -> None:
14 | """ Get Profession Info
15 | :param json_input: Input data
16 | :raises: ValueError if profession name or description are missing.
17 | """
18 |
19 | @abstractmethod
20 | def execute(self) -> Dict:
21 | """ Executes the controller
22 | :returns: Profession created
23 | """
24 |
--------------------------------------------------------------------------------
/src/app/flask_postgresql/presenters/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/src/app/flask_postgresql/presenters/__init__.py
--------------------------------------------------------------------------------
/src/app/flask_postgresql/presenters/create_profession_presenter.py:
--------------------------------------------------------------------------------
1 | """ Module for the CreateProfessionPresenter
2 | """
3 |
4 |
5 | from typing import Dict
6 | from src.interactor.dtos.create_profession_dtos \
7 | import CreateProfessionOutputDto
8 | from src.interactor.interfaces.presenters.create_profession_presenter \
9 | import CreateProfessionPresenterInterface
10 |
11 |
12 | class CreateProfessionPresenter(CreateProfessionPresenterInterface):
13 | """ Class for the CreateProfessionPresenter
14 | """
15 | def present(self, output_dto: CreateProfessionOutputDto) -> Dict:
16 | """ Present the CreateProfession
17 | :param output_dto: CreateProfessionOutputDto
18 | :return: Dict
19 | """
20 | return {
21 | "profession_id": output_dto.profession.profession_id,
22 | "name": output_dto.profession.name,
23 | "description": output_dto.profession.description
24 | }
25 |
--------------------------------------------------------------------------------
/src/app/flask_postgresql/presenters/create_profession_presenter_test.py:
--------------------------------------------------------------------------------
1 | # pylint: disable=missing-module-docstring
2 | # pylint: disable=missing-class-docstring
3 | # pylint: disable=missing-function-docstring
4 |
5 |
6 | from src.interactor.dtos.create_profession_dtos \
7 | import CreateProfessionOutputDto
8 | from src.domain.entities.profession import Profession
9 | from .create_profession_presenter import CreateProfessionPresenter
10 |
11 |
12 | def test_create_profession_presenter(fixture_profession_developer):
13 | profession = Profession(
14 | profession_id=fixture_profession_developer["profession_id"],
15 | name=fixture_profession_developer["name"],
16 | description=fixture_profession_developer["description"]
17 | )
18 | output_dto = CreateProfessionOutputDto(profession)
19 | presenter = CreateProfessionPresenter()
20 | assert presenter.present(output_dto) == {
21 | "profession_id": fixture_profession_developer["profession_id"],
22 | "name": fixture_profession_developer["name"],
23 | "description": fixture_profession_developer["description"]
24 | }
25 |
--------------------------------------------------------------------------------
/src/conftest.py:
--------------------------------------------------------------------------------
1 | # pylint: disable=missing-module-docstring
2 | # pylint: disable=missing-class-docstring
3 | # pylint: disable=missing-function-docstring
4 |
5 |
6 | import uuid
7 | import pytest
8 |
9 |
10 | @pytest.fixture
11 | def fixture_profession_developer():
12 | """ Fixture with Profession example """
13 | return {
14 | "profession_id": uuid.uuid4(),
15 | "name": "Developer - Test",
16 | "description": "Developer is a person that write software code. This \
17 | professional needs to know at least one programming language."
18 | }
19 |
--------------------------------------------------------------------------------
/src/domain/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/src/domain/__init__.py
--------------------------------------------------------------------------------
/src/domain/entities/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/src/domain/entities/__init__.py
--------------------------------------------------------------------------------
/src/domain/entities/profession.py:
--------------------------------------------------------------------------------
1 | """ This module has definition of the Profession entity
2 | """
3 |
4 |
5 | from dataclasses import dataclass, asdict
6 | from src.domain.value_objects import ProfessionId
7 |
8 |
9 | @dataclass
10 | class Profession:
11 | """ Definition of the Profession entity
12 | """
13 | profession_id: ProfessionId
14 | name: str
15 | description: str
16 |
17 | @classmethod
18 | def from_dict(cls, data):
19 | """ Convert data from a dictionary
20 | """
21 | return cls(**data)
22 |
23 | def to_dict(self):
24 | """ Convert data into dictionary
25 | """
26 | return asdict(self)
27 |
--------------------------------------------------------------------------------
/src/domain/entities/profession_test.py:
--------------------------------------------------------------------------------
1 | # pylint: disable=missing-module-docstring
2 | # pylint: disable=missing-class-docstring
3 | # pylint: disable=missing-function-docstring
4 |
5 |
6 | from .profession import Profession
7 |
8 |
9 | def test_profession_creation(fixture_profession_developer):
10 | profession = Profession(
11 | profession_id=fixture_profession_developer["profession_id"],
12 | name=fixture_profession_developer["name"],
13 | description=fixture_profession_developer["description"]
14 | )
15 | assert profession.name == fixture_profession_developer["name"]
16 | assert (profession.description
17 | == fixture_profession_developer["description"])
18 |
19 |
20 | def test_profession_from_dict(fixture_profession_developer):
21 | profession = Profession.from_dict(fixture_profession_developer)
22 | assert profession.name == fixture_profession_developer["name"]
23 | assert (profession.description
24 | == fixture_profession_developer["description"])
25 |
26 |
27 | def test_profession_to_dict(fixture_profession_developer):
28 | profession = Profession.from_dict(fixture_profession_developer)
29 | assert profession.to_dict() == fixture_profession_developer
30 |
31 |
32 | def test_profession_comparison(fixture_profession_developer):
33 | profession_1 = Profession.from_dict(fixture_profession_developer)
34 | profession_2 = Profession.from_dict(fixture_profession_developer)
35 | assert profession_1 == profession_2
36 |
--------------------------------------------------------------------------------
/src/domain/value_objects.py:
--------------------------------------------------------------------------------
1 | """ Module for Value Objects
2 | """
3 |
4 |
5 | import uuid
6 |
7 |
8 | ProfessionId = uuid.UUID
9 |
--------------------------------------------------------------------------------
/src/infra/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/src/infra/__init__.py
--------------------------------------------------------------------------------
/src/infra/db_models/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/src/infra/db_models/__init__.py
--------------------------------------------------------------------------------
/src/infra/db_models/db_base.py:
--------------------------------------------------------------------------------
1 | """ Base class for all models
2 | """
3 |
4 |
5 | from sqlalchemy.orm import DeclarativeBase, sessionmaker, scoped_session
6 | from sqlalchemy import create_engine
7 | from configs import config
8 |
9 |
10 | class Base(DeclarativeBase):
11 | """ Base class for all models
12 | """
13 |
14 |
15 | engine = create_engine(config.DB_URI)
16 | Session = scoped_session(sessionmaker(bind=engine))
17 |
--------------------------------------------------------------------------------
/src/infra/db_models/profession_db_model.py:
--------------------------------------------------------------------------------
1 | """ Defines the professions database model.
2 | """
3 |
4 |
5 | import uuid
6 | from sqlalchemy import String
7 | from sqlalchemy.orm import Mapped, mapped_column
8 | from sqlalchemy.dialects.postgresql import UUID
9 | from src.infra.db_models.db_base import Base
10 |
11 |
12 | class ProfessionsDBModel(Base):
13 | """ Defines the professions database model.
14 | """
15 |
16 | __tablename__ = "professions"
17 |
18 | profession_id: Mapped[uuid.UUID] = \
19 | mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
20 | name: Mapped[str] = mapped_column(String(80), nullable=False, unique=True)
21 | description: Mapped[str] = mapped_column(String(200), nullable=False)
22 |
--------------------------------------------------------------------------------
/src/infra/loggers/logger_default.py:
--------------------------------------------------------------------------------
1 | """ Module for LoggerDefault class."""
2 |
3 |
4 | import logging
5 | from src.interactor.interfaces.logger.logger import LoggerInterface
6 |
7 |
8 | class LoggerDefault(LoggerInterface):
9 | """ LoggerDefault class.
10 | """
11 |
12 | def __init__(self):
13 | logging.basicConfig(
14 | filename='app.log',
15 | filemode='a',
16 | datefmt='%Y-%m-%d %H:%M:%S',
17 | format='%(asctime)-s - %(levelname)s - %(message)s',
18 | level=logging.INFO
19 | )
20 |
21 | def log_debug(self, message: str) -> None:
22 | """ Log debug message.
23 | :param message: Message to log.
24 | """
25 | logging.debug(message)
26 |
27 | def log_info(self, message: str) -> None:
28 | """ Log info message.
29 | :param message: Message to log.
30 | """
31 | logging.info(message)
32 |
33 | def log_warning(self, message: str) -> None:
34 | """ Log warning message.
35 | :param message: Message to log.
36 | """
37 | logging.warning(message)
38 |
39 | def log_error(self, message: str) -> None:
40 | """ Log error message.
41 | :param message: Message to log.
42 | """
43 | logging.error(message)
44 |
45 | def log_critical(self, message: str) -> None:
46 | """ Log critical message.
47 | :param message: Message to log.
48 | """
49 | logging.critical(message)
50 |
51 | def log_exception(self, message: str) -> None:
52 | """ Log exception message with exception info.
53 | :param message: Message to log.
54 | """
55 | logging.exception(message)
56 |
--------------------------------------------------------------------------------
/src/infra/loggers/logger_default_test.py:
--------------------------------------------------------------------------------
1 | # pylint: disable=missing-module-docstring
2 | # pylint: disable=missing-class-docstring
3 | # pylint: disable=missing-function-docstring
4 |
5 |
6 | import logging
7 | from src.infra.loggers.logger_default import LoggerDefault
8 |
9 |
10 | def test_logger_default(mocker):
11 | mocker.patch.object(logging, 'debug')
12 | logger = LoggerDefault()
13 | logger.log_debug('testdebug')
14 | logging.debug.assert_called_once_with('testdebug') # pylint: disable=E1101
15 |
16 | mocker.patch.object(logging, 'info')
17 | logger = LoggerDefault()
18 | logger.log_info('testinfo')
19 | logging.info.assert_called_once_with('testinfo') # pylint: disable=E1101
20 |
21 | mocker.patch.object(logging, 'warning')
22 | logger = LoggerDefault()
23 | logger.log_warning('tstwarn')
24 | logging.warning.assert_called_once_with('tstwarn') # pylint: disable=E1101
25 |
26 | mocker.patch.object(logging, 'error')
27 | logger = LoggerDefault()
28 | logger.log_error('testerror')
29 | logging.error.assert_called_once_with('testerror') # pylint: disable=E1101
30 |
31 | mocker.patch.object(logging, 'critical')
32 | logger = LoggerDefault()
33 | logger.log_critical('tcrit')
34 | logging.critical.assert_called_once_with('tcrit') # pylint: disable=E1101
35 |
36 | mocker.patch.object(logging, 'exception')
37 | logger = LoggerDefault()
38 | logger.log_exception('texce')
39 | logging.exception.assert_called_once_with('texce') # pylint: disable=E1101
40 |
--------------------------------------------------------------------------------
/src/infra/repositories/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/src/infra/repositories/__init__.py
--------------------------------------------------------------------------------
/src/infra/repositories/profession_in_memory_repository.py:
--------------------------------------------------------------------------------
1 | """ Module for ProfessionInMemoryRepository
2 | """
3 |
4 |
5 | from typing import Dict
6 | import copy
7 | import uuid
8 | from src.domain.entities.profession import Profession
9 | from src.interactor.interfaces.repositories.profession_repository \
10 | import ProfessionRepositoryInterface
11 | from src.domain.value_objects import ProfessionId
12 |
13 |
14 | class ProfessionInMemoryRepository(ProfessionRepositoryInterface):
15 | """ InMemory Repository for Profession
16 | """
17 | def __init__(self) -> None:
18 | self._data: Dict[ProfessionId, Profession] = {}
19 |
20 | def get(self, profession_id: ProfessionId) -> Profession:
21 | """ Get Profession by id
22 |
23 | :param profession_id: ProfessionId
24 | :return: Profession
25 | """
26 | return copy.deepcopy(self._data[profession_id])
27 |
28 | def create(self, name: str, description: str) -> Profession:
29 | profession = Profession(
30 | profession_id=uuid.uuid4(),
31 | name=name,
32 | description=description
33 | )
34 | self._data[profession.profession_id] = copy.deepcopy(profession)
35 | return copy.deepcopy(self._data[profession.profession_id])
36 |
37 | def update(self, profession: Profession) -> Profession:
38 | self._data[profession.profession_id] = copy.deepcopy(profession)
39 | return copy.deepcopy(self._data[profession.profession_id])
40 |
--------------------------------------------------------------------------------
/src/infra/repositories/profession_in_memory_repository_test.py:
--------------------------------------------------------------------------------
1 | # pylint: disable=missing-module-docstring
2 | # pylint: disable=missing-class-docstring
3 | # pylint: disable=missing-function-docstring
4 |
5 |
6 | from src.domain.entities.profession import Profession
7 | from .profession_in_memory_repository import ProfessionInMemoryRepository
8 |
9 |
10 | def test_profession_in_memory_repository(fixture_profession_developer):
11 | repository = ProfessionInMemoryRepository()
12 | profession = repository.create(
13 | fixture_profession_developer["name"],
14 | fixture_profession_developer["description"]
15 | )
16 | response = repository.get(profession.profession_id)
17 | assert response.name == fixture_profession_developer["name"]
18 | assert response.description == fixture_profession_developer["description"]
19 | new_profession = Profession(
20 | profession.profession_id,
21 | "new name",
22 | "new description"
23 | )
24 | response_update = repository.update(new_profession)
25 | assert response_update.name == "new name"
26 | assert response_update.description == "new description"
27 |
--------------------------------------------------------------------------------
/src/infra/repositories/profession_postgresql_repository.py:
--------------------------------------------------------------------------------
1 | """ Module for ProfessionPostgresqlRepository
2 | """
3 |
4 | from typing import Optional
5 | import uuid
6 | from sqlalchemy.exc import IntegrityError
7 | from src.domain.entities.profession import Profession
8 | from src.interactor.interfaces.repositories.profession_repository \
9 | import ProfessionRepositoryInterface
10 | from src.domain.value_objects import ProfessionId
11 | from src.infra.db_models.db_base import Session
12 | from src.infra.db_models.profession_db_model import ProfessionsDBModel
13 | from src.interactor.errors.error_classes import UniqueViolationError
14 |
15 |
16 | class ProfessionPostgresqlRepository(ProfessionRepositoryInterface):
17 | """ Postgresql Repository for Profession
18 | """
19 | def __init__(self) -> None:
20 | self.__session = Session
21 |
22 | def __db_to_entity(
23 | self, db_row: ProfessionsDBModel
24 | ) -> Optional[Profession]:
25 | return Profession(
26 | profession_id=db_row.profession_id,
27 | name=db_row.name,
28 | description=db_row.description
29 | )
30 |
31 | def create(self, name: str, description: str) -> Optional[Profession]:
32 | """ Create Profession
33 | :param name: str
34 | :param description: str
35 | :return: Optional[Profession]
36 | """
37 | profession_id = uuid.uuid4()
38 | profession_db_model = ProfessionsDBModel(
39 | profession_id=profession_id,
40 | name=name,
41 | description=description
42 | )
43 |
44 | try:
45 | self.__session.add(profession_db_model)
46 | self.__session.commit()
47 | self.__session.refresh(profession_db_model)
48 | except IntegrityError as exception:
49 | if "violates unique constraint" in str(exception.orig):
50 | raise UniqueViolationError(
51 | "Profession with the same name already exists"
52 | ) from exception
53 | raise
54 |
55 | if profession_db_model is not None:
56 | return self.__db_to_entity(profession_db_model)
57 | return None
58 |
59 | def get(self, profession_id: ProfessionId) -> Optional[Profession]:
60 | """ Get Profession by id
61 | :param profession_id: ProfessionId
62 | :return: Optional[Profession]
63 | """
64 | result = self.__session.query(ProfessionsDBModel).get(profession_id)
65 | if result is not None:
66 | return self.__db_to_entity(result)
67 | return None
68 |
69 | def update(self, profession: Profession) -> Optional[Profession]:
70 | """ Update Profession
71 | :param profession: Profession
72 | :return: Optional[Profession]
73 | """
74 | profession_db_model = ProfessionsDBModel(
75 | profession_id=profession.profession_id,
76 | name=profession.name,
77 | description=profession.description
78 | )
79 | result = self.__session.query(
80 | ProfessionsDBModel
81 | ).filter_by(
82 | profession_id=profession.profession_id
83 | ).update(
84 | {
85 | "name": profession.name,
86 | "description": profession.description
87 | }
88 | )
89 | if result == 0:
90 | return None
91 | self.__session.commit()
92 | return self.__db_to_entity(profession_db_model)
93 |
--------------------------------------------------------------------------------
/src/interactor/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/src/interactor/__init__.py
--------------------------------------------------------------------------------
/src/interactor/dtos/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/src/interactor/dtos/__init__.py
--------------------------------------------------------------------------------
/src/interactor/dtos/create_profession_dtos.py:
--------------------------------------------------------------------------------
1 | """ Module for CreateProfession Dtos
2 | """
3 |
4 |
5 | from dataclasses import dataclass, asdict
6 | from src.domain.entities.profession import Profession
7 |
8 |
9 | @dataclass
10 | class CreateProfessionInputDto:
11 | """ Input Dto for create profession """
12 | name: str
13 | description: str
14 |
15 | def to_dict(self):
16 | """ Convert data into dictionary
17 | """
18 | return asdict(self)
19 |
20 |
21 | @dataclass
22 | class CreateProfessionOutputDto:
23 | """ Output Dto for create profession """
24 | profession: Profession
25 |
--------------------------------------------------------------------------------
/src/interactor/dtos/create_profession_dtos_test.py:
--------------------------------------------------------------------------------
1 | # pylint: disable=missing-module-docstring
2 | # pylint: disable=missing-class-docstring
3 | # pylint: disable=missing-function-docstring
4 |
5 |
6 | from .create_profession_dtos import CreateProfessionInputDto
7 |
8 |
9 | def test_create_profession_input_dto_valid(fixture_profession_developer):
10 | input_dto = CreateProfessionInputDto(
11 | name=fixture_profession_developer["name"],
12 | description=fixture_profession_developer["description"]
13 | )
14 | assert input_dto.name == fixture_profession_developer["name"]
15 | assert input_dto.description == fixture_profession_developer["description"]
16 | assert input_dto.to_dict() == {
17 | "name": fixture_profession_developer["name"],
18 | "description": fixture_profession_developer["description"]
19 | }
20 |
--------------------------------------------------------------------------------
/src/interactor/errors/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/src/interactor/errors/__init__.py
--------------------------------------------------------------------------------
/src/interactor/errors/error_classes.py:
--------------------------------------------------------------------------------
1 | """ This module contains exceptions for the Use Cases layer
2 | """
3 |
4 |
5 | class FieldValueNotPermittedException(Exception):
6 | """ Exception raised when a field is empty """
7 | def __init__(self, field_name: str, field_value: str) -> None:
8 | self.field_name = field_name
9 | self.field_value = field_value
10 |
11 | def __str__(self) -> str:
12 | return f"{self.field_name.capitalize()}: {self.field_value} is not \
13 | permitted"
14 |
15 |
16 | class ItemNotCreatedException(Exception):
17 | """ Exception raised when an item is not created """
18 | def __init__(self, item_name: str, item_type: str) -> None:
19 | self.item_name = item_name
20 | self.item_type = item_type
21 |
22 | def __str__(self) -> str:
23 | return f"{self.item_type.capitalize()} '{self.item_name}' was not \
24 | created correctly"
25 |
26 |
27 | class UniqueViolationError(Exception):
28 | """ Exception raised when a unique constraint is violated """
29 |
--------------------------------------------------------------------------------
/src/interactor/errors/error_classes_test.py:
--------------------------------------------------------------------------------
1 | # pylint: disable=missing-module-docstring
2 | # pylint: disable=missing-class-docstring
3 | # pylint: disable=missing-function-docstring
4 |
5 |
6 | import pytest
7 | from src.interactor.errors.error_classes \
8 | import FieldValueNotPermittedException
9 | from src.interactor.errors.error_classes import ItemNotCreatedException
10 |
11 |
12 | def test_empty_field_exception():
13 | with pytest.raises(FieldValueNotPermittedException) as exception_info:
14 | raise FieldValueNotPermittedException("name", "Profession")
15 | assert str(exception_info.value) == "Name: Profession is not permitted"
16 |
17 |
18 | def test_item_not_created_exception():
19 | with pytest.raises(ItemNotCreatedException) as exception_info:
20 | raise ItemNotCreatedException("profession name", "profession")
21 | assert str(exception_info.value) == \
22 | "Profession 'profession name' was not created correctly"
23 |
--------------------------------------------------------------------------------
/src/interactor/interfaces/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/src/interactor/interfaces/__init__.py
--------------------------------------------------------------------------------
/src/interactor/interfaces/logger/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/src/interactor/interfaces/logger/__init__.py
--------------------------------------------------------------------------------
/src/interactor/interfaces/logger/logger.py:
--------------------------------------------------------------------------------
1 | """ Module provides a logger interface.
2 | """
3 |
4 |
5 | from abc import ABC, abstractmethod
6 |
7 |
8 | class LoggerInterface(ABC):
9 | """ LoggerInterface class provides an interface for logging.
10 | """
11 |
12 | @abstractmethod
13 | def log_debug(self, message: str) -> None:
14 | """ Log debug message.
15 | :param message: Message to log.
16 | """
17 |
18 | @abstractmethod
19 | def log_info(self, message: str) -> None:
20 | """ Log info message.
21 | :param message: Message to log.
22 | """
23 |
24 | @abstractmethod
25 | def log_warning(self, message: str) -> None:
26 | """ Log warning message.
27 | :param message: Message to log.
28 | """
29 |
30 | @abstractmethod
31 | def log_error(self, message: str) -> None:
32 | """ Log error message.
33 | :param message: Message to log.
34 | """
35 |
36 | @abstractmethod
37 | def log_critical(self, message: str) -> None:
38 | """ Log critical message.
39 | :param message: Message to log.
40 | """
41 |
42 | @abstractmethod
43 | def log_exception(self, message: str) -> None:
44 | """ Log exception message with exception info.
45 | :param message: Message to log.
46 | """
47 |
--------------------------------------------------------------------------------
/src/interactor/interfaces/presenters/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/src/interactor/interfaces/presenters/__init__.py
--------------------------------------------------------------------------------
/src/interactor/interfaces/presenters/create_profession_presenter.py:
--------------------------------------------------------------------------------
1 | """ Module for the CreateProfessionPresenterInterface
2 | """
3 |
4 |
5 | from typing import Dict
6 | from abc import ABC, abstractmethod
7 | from src.interactor.dtos.create_profession_dtos \
8 | import CreateProfessionOutputDto
9 |
10 |
11 | class CreateProfessionPresenterInterface(ABC):
12 | """ Class for the Interface of the ProfessionPresenter
13 | """
14 | @abstractmethod
15 | def present(self, output_dto: CreateProfessionOutputDto) -> Dict:
16 | """ Present the Profession
17 | """
18 |
--------------------------------------------------------------------------------
/src/interactor/interfaces/repositories/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/src/interactor/interfaces/repositories/__init__.py
--------------------------------------------------------------------------------
/src/interactor/interfaces/repositories/profession_repository.py:
--------------------------------------------------------------------------------
1 | """ This module contains the interface for the ProfessionRepository
2 | """
3 |
4 |
5 | from abc import ABC, abstractmethod
6 | from typing import Optional
7 | from src.domain.value_objects import ProfessionId
8 | from src.domain.entities.profession import Profession
9 |
10 |
11 | class ProfessionRepositoryInterface(ABC):
12 | """ This class is the interface for the ProfessionRepository
13 | """
14 |
15 | @abstractmethod
16 | def get(self, profession_id: ProfessionId) -> Optional[Profession]:
17 | """ Get a Profession by id
18 |
19 | :param profession_id: ProfessionId
20 | :return: Profession
21 | """
22 |
23 | @abstractmethod
24 | def create(self, name: str, description: str) -> Optional[Profession]:
25 | """ Create a Profession
26 |
27 | :param name: Profession Name
28 | :param description: Profession Description
29 | :return: ProfessionId
30 | """
31 |
32 | @abstractmethod
33 | def update(self, profession: Profession) -> Optional[Profession]:
34 | """ Save a Profession
35 |
36 | :param Profession: Profession
37 | :return: Profession
38 | """
39 |
--------------------------------------------------------------------------------
/src/interactor/use_cases/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/src/interactor/use_cases/__init__.py
--------------------------------------------------------------------------------
/src/interactor/use_cases/create_profession.py:
--------------------------------------------------------------------------------
1 | """ This module is responsible for creating a new profession.
2 | """
3 |
4 |
5 | from typing import Dict
6 | from src.interactor.dtos.create_profession_dtos \
7 | import CreateProfessionInputDto, CreateProfessionOutputDto
8 | from src.interactor.interfaces.presenters.create_profession_presenter \
9 | import CreateProfessionPresenterInterface
10 | from src.interactor.interfaces.repositories.profession_repository \
11 | import ProfessionRepositoryInterface
12 | from src.interactor.validations.create_profession_validator \
13 | import CreateProfessionInputDtoValidator
14 | from src.interactor.interfaces.logger.logger import LoggerInterface
15 | from src.interactor.errors.error_classes import ItemNotCreatedException
16 |
17 |
18 | class CreateProfessionUseCase():
19 | """ This class is responsible for creating a new profession.
20 | """
21 |
22 | def __init__(
23 | self,
24 | presenter: CreateProfessionPresenterInterface,
25 | repository: ProfessionRepositoryInterface,
26 | logger: LoggerInterface
27 | ):
28 | self.presenter = presenter
29 | self.repository = repository
30 | self.logger = logger
31 |
32 | def execute(
33 | self,
34 | input_dto: CreateProfessionInputDto
35 | ) -> Dict:
36 | """ This method is responsible for creating a new profession.
37 | :param input_dto: The input data transfer object.
38 | :type input_dto: CreateProfessionInputDto
39 | :return: Dict
40 | """
41 |
42 | validator = CreateProfessionInputDtoValidator(input_dto.to_dict())
43 | validator.validate()
44 | profession = self.repository.create(
45 | input_dto.name,
46 | input_dto.description
47 | )
48 | if profession is None:
49 | self.logger.log_exception("Profession creation failed")
50 | raise ItemNotCreatedException(input_dto.name, "Profession")
51 | output_dto = CreateProfessionOutputDto(profession)
52 | presenter_response = self.presenter.present(output_dto)
53 | self.logger.log_info("Profession created successfully")
54 | return presenter_response
55 |
--------------------------------------------------------------------------------
/src/interactor/use_cases/create_profession_test.py:
--------------------------------------------------------------------------------
1 | # pylint: disable=missing-module-docstring
2 | # pylint: disable=missing-class-docstring
3 | # pylint: disable=missing-function-docstring
4 |
5 |
6 | import pytest
7 | from src.interactor.use_cases import create_profession
8 | from src.domain.entities.profession import Profession
9 | from src.interactor.dtos.create_profession_dtos \
10 | import CreateProfessionInputDto, CreateProfessionOutputDto
11 | from src.interactor.interfaces.presenters.create_profession_presenter \
12 | import CreateProfessionPresenterInterface
13 | from src.interactor.interfaces.repositories.profession_repository \
14 | import ProfessionRepositoryInterface
15 | from src.interactor.interfaces.logger.logger import LoggerInterface
16 | from src.interactor.errors.error_classes import ItemNotCreatedException
17 |
18 |
19 | def test_create_profession(mocker, fixture_profession_developer):
20 | profession = Profession(
21 | profession_id=fixture_profession_developer["profession_id"],
22 | name=fixture_profession_developer["name"],
23 | description=fixture_profession_developer["description"]
24 | )
25 | presenter_mock = mocker.patch.object(
26 | CreateProfessionPresenterInterface,
27 | "present"
28 | )
29 | repository_mock = mocker.patch.object(
30 | ProfessionRepositoryInterface,
31 | "create"
32 | )
33 |
34 | input_dto_validator_mock = mocker.patch(
35 | "src.interactor.use_cases.create_profession.\
36 | CreateProfessionInputDtoValidator"
37 | )
38 | logger_mock = mocker.patch.object(
39 | LoggerInterface,
40 | "log_info"
41 | )
42 | repository_mock.create.return_value = profession
43 | presenter_mock.present.return_value = "Test output"
44 | use_case = create_profession.CreateProfessionUseCase(
45 | presenter_mock,
46 | repository_mock,
47 | logger_mock
48 | )
49 | input_dto = CreateProfessionInputDto(
50 | name=fixture_profession_developer["name"],
51 | description=fixture_profession_developer["description"]
52 | )
53 | result = use_case.execute(input_dto)
54 | repository_mock.create.assert_called_once()
55 | input_dto_validator_mock.assert_called_once_with(input_dto.to_dict())
56 | input_dto_validator_instance = input_dto_validator_mock.return_value
57 | input_dto_validator_instance.validate.assert_called_once_with()
58 | logger_mock.log_info.assert_called_once_with(
59 | "Profession created successfully")
60 | output_dto = CreateProfessionOutputDto(profession)
61 | presenter_mock.present.assert_called_once_with(output_dto)
62 | assert result == "Test output"
63 |
64 | # Testing None return value from repository
65 | repository_mock.create.return_value = None
66 | profession_name = fixture_profession_developer["name"]
67 | with pytest.raises(ItemNotCreatedException) as exception_info:
68 | use_case.execute(input_dto)
69 | assert str(exception_info.value) == \
70 | f"Profession '{profession_name}' was not created correctly"
71 |
72 |
73 | def test_create_profession_empty_field(mocker, fixture_profession_developer):
74 | presenter_mock = mocker.patch.object(
75 | CreateProfessionPresenterInterface,
76 | "present"
77 | )
78 | repository_mock = mocker.patch.object(
79 | ProfessionRepositoryInterface,
80 | "create"
81 | )
82 | logger_mock = mocker.patch.object(
83 | LoggerInterface,
84 | "log_info"
85 | )
86 | use_case = create_profession.CreateProfessionUseCase(
87 | presenter_mock,
88 | repository_mock,
89 | logger_mock
90 | )
91 | input_dto = CreateProfessionInputDto(
92 | name="",
93 | description=fixture_profession_developer["description"]
94 | )
95 | with pytest.raises(ValueError) as exception_info:
96 | use_case.execute(input_dto)
97 | assert str(exception_info.value) == "Name: empty values not allowed"
98 |
99 | repository_mock.create.assert_not_called()
100 | presenter_mock.present.assert_not_called()
101 |
--------------------------------------------------------------------------------
/src/interactor/validations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/claudiosw/python-clean-architecture-example/2050a235efe2d62a282fb6a11e8400ce1b65629f/src/interactor/validations/__init__.py
--------------------------------------------------------------------------------
/src/interactor/validations/base_input_validator.py:
--------------------------------------------------------------------------------
1 | """ This module provides the base class BaseInputValidator for input validation
2 | """
3 |
4 |
5 | from typing import Dict
6 | from cerberus import Validator # type: ignore
7 |
8 |
9 | class BaseInputValidator:
10 | """ This class provides the base class for input validation
11 | """
12 | def __init__(self, data: Dict[str, str]):
13 | self.data = data
14 | self.errors: Dict = {}
15 |
16 | def verify(self, schema: Dict) -> None:
17 | """ Validates the input data against the provided schema
18 | :param schema: The schema to validate against
19 | :return: None
20 | :raises ValueError: If the input data is invalid.
21 | """
22 | validator = Validator(schema)
23 | if not validator.validate(self.data):
24 | self.errors = validator.errors
25 | self._raise_validation_error()
26 |
27 | def _raise_validation_error(self):
28 | error_messages = []
29 | for field, messages in self.errors.items():
30 | for message in messages:
31 | error_messages.append(f"{field.capitalize()}: {message}")
32 | raise ValueError("\n".join(error_messages))
33 |
--------------------------------------------------------------------------------
/src/interactor/validations/base_input_validator_test.py:
--------------------------------------------------------------------------------
1 | # pylint: disable=missing-module-docstring
2 | # pylint: disable=missing-class-docstring
3 | # pylint: disable=missing-function-docstring
4 |
5 |
6 | from typing import Dict
7 | import pytest
8 | from src.interactor.validations.base_input_validator import BaseInputValidator
9 |
10 |
11 | class BaseValidator(BaseInputValidator):
12 | def __init__(self, data: Dict):
13 | super().__init__(data)
14 | self.schema = {
15 | "name": {
16 | "type": "string",
17 | "minlength": 3,
18 | "maxlength": 10,
19 | "required": True,
20 | "empty": False
21 | },
22 | "description": {
23 | "type": "string",
24 | "minlength": 3,
25 | "maxlength": 10,
26 | "required": False,
27 | "empty": True
28 | }
29 | }
30 |
31 | def validate(self):
32 | super().verify(self.schema)
33 |
34 |
35 | def test_base_validator_with_valid_data():
36 | data = {'name': 'test'}
37 | validator = BaseValidator(data)
38 | validator.validate()
39 |
40 |
41 | def test_base_validator_with_small_data():
42 | data = {'name': 'a', 'description': 'a'}
43 | validator = BaseValidator(data)
44 | with pytest.raises(ValueError) as exception_info:
45 | validator.validate()
46 | assert str(exception_info.value) == "Description: min length is 3\n\
47 | Name: min length is 3"
48 |
49 |
50 | def test_base_validator_with_long_data():
51 | data = {'name': 'this is a long name'}
52 | validator = BaseValidator(data)
53 | with pytest.raises(ValueError) as exception_info:
54 | validator.validate()
55 | assert str(exception_info.value) == "Name: max length is 10"
56 |
57 |
58 | def test_base_validator_with_empty_data():
59 | data = {'name': ''}
60 | validator = BaseValidator(data)
61 | with pytest.raises(ValueError) as exception_info:
62 | validator.validate()
63 | assert str(exception_info.value) == "Name: empty values not allowed"
64 |
65 |
66 | def test_base_validator_without_required_data():
67 | data = {}
68 | validator = BaseValidator(data)
69 | with pytest.raises(ValueError) as exception_info:
70 | validator.validate()
71 | assert str(exception_info.value) == "Name: required field"
72 |
--------------------------------------------------------------------------------
/src/interactor/validations/create_profession_validator.py:
--------------------------------------------------------------------------------
1 | """ Defines the validator for the create profession input data.
2 | """
3 |
4 |
5 | from typing import Dict
6 | from src.interactor.validations.base_input_validator import BaseInputValidator
7 | from src.interactor.errors.error_classes import FieldValueNotPermittedException
8 |
9 |
10 | class CreateProfessionInputDtoValidator(BaseInputValidator):
11 | """ Validates the create profession input data.
12 | :param input_data: The input data to be validated.
13 | """
14 |
15 | def __init__(self, input_data: Dict) -> None:
16 | super().__init__(input_data)
17 | self.input_data = input_data
18 | self.__schema = {
19 | "name": {
20 | "type": "string",
21 | "minlength": 3,
22 | "maxlength": 80,
23 | "required": True,
24 | "empty": False
25 | },
26 | "description": {
27 | "type": "string",
28 | "minlength": 5,
29 | "maxlength": 200,
30 | "required": True,
31 | "empty": False
32 | }
33 | }
34 |
35 | def validate(self) -> None:
36 | """ Validates the input data
37 | """
38 | # Verify the input data using BaseInputValidator method
39 | super().verify(self.__schema)
40 | # This is an example of a custom validation
41 | if self.input_data["name"] == "Profession":
42 | raise FieldValueNotPermittedException("name", "Profession")
43 |
--------------------------------------------------------------------------------
/src/interactor/validations/create_profession_validator_test.py:
--------------------------------------------------------------------------------
1 | # pylint: disable=missing-module-docstring
2 | # pylint: disable=missing-class-docstring
3 | # pylint: disable=missing-function-docstring
4 |
5 |
6 | import pytest
7 | from src.interactor.validations.create_profession_validator \
8 | import CreateProfessionInputDtoValidator
9 | from src.interactor.errors.error_classes import FieldValueNotPermittedException
10 |
11 |
12 | def test_create_profession_validator_valid_data(
13 | mocker,
14 | fixture_profession_developer
15 | ):
16 | mocker.patch("src.interactor.validations.base_input_validator.\
17 | BaseInputValidator.verify")
18 | input_data = {
19 | "name": fixture_profession_developer["name"],
20 | "description": fixture_profession_developer["description"]
21 | }
22 | schema = {
23 | "name": {
24 | "type": "string",
25 | "minlength": 3,
26 | "maxlength": 80,
27 | "required": True,
28 | "empty": False
29 | },
30 | "description": {
31 | "type": "string",
32 | "minlength": 5,
33 | "maxlength": 200,
34 | "required": True,
35 | "empty": False
36 | }
37 | }
38 | validator = CreateProfessionInputDtoValidator(input_data)
39 | validator.validate()
40 | validator.verify.assert_called_once_with(schema) # pylint: disable=E1101
41 |
42 |
43 | def test_create_profession_validator_empty_input(fixture_profession_developer):
44 | # We are doing just a simple test as the complete test is done in
45 | # base_input_validator_test.py
46 | input_data = {
47 | "name": fixture_profession_developer["name"],
48 | "description": "",
49 | }
50 | validator = CreateProfessionInputDtoValidator(input_data)
51 | with pytest.raises(ValueError) as exception_info:
52 | validator.validate()
53 | assert str(exception_info.value) == "Description: empty values not allowed"
54 |
55 |
56 | def test_create_profession_custom_validation(fixture_profession_developer):
57 | input_data = {
58 | "name": "Profession",
59 | "description": fixture_profession_developer["description"],
60 | }
61 | validator = CreateProfessionInputDtoValidator(input_data)
62 | with pytest.raises(FieldValueNotPermittedException) as exception_info:
63 | validator.validate()
64 | assert str(exception_info.value) == "Name: Profession is not permitted"
65 |
--------------------------------------------------------------------------------