From 016313c8af4cda1a2a5f03cda99c28ee1624de7f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Dec 2023 12:46:25 +0000 Subject: [PATCH 01/13] build(deps): bump rich from 13.3.2 to 13.4.1 (#16) Bumps [rich](https://github.com/Textualize/rich) from 13.3.2 to 13.4.1.
Release notes

Sourced from rich's releases.

Hot fix for typing extension issue

[13.4.1] - 2023-06-31

Fixed

Added tables to Markdown

[13.4.0] - 2023-06-31

Added

table

v13.3.5

[13.3.5] - 2023-04-27

Fixed

Bugfix for is_terminal

[13.3.4] - 2023-04-12

Fixed

Clear meta and links

Just a new method on the Style class. A helper for Textual, you probable aren't going to need it.

[13.3.3] - 2023-02-27

Added

Changelog

Sourced from rich's changelog.

[13.4.1] - 2023-06-31

Fixed

[13.4.0] - 2023-06-31

Added

[13.3.5] - 2023-04-27

Fixed

[13.3.4] - 2023-04-12

Fixed

[13.3.3] - 2023-02-27

Added

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=rich&package-manager=pip&previous-version=13.3.2&new-version=13.4.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index bb40699..f967661 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1248,13 +1248,13 @@ tests = ["coverage (>=6.0.0)", "flake8", "mypy", "pytest (>=7.0.0)", "pytest-asy [[package]] name = "rich" -version = "13.3.2" +version = "13.4.1" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" optional = false python-versions = ">=3.7.0" files = [ - {file = "rich-13.3.2-py3-none-any.whl", hash = "sha256:a104f37270bf677148d8acb07d33be1569eeee87e2d1beb286a4e9113caf6f2f"}, - {file = "rich-13.3.2.tar.gz", hash = "sha256:91954fe80cfb7985727a467ca98a7618e5dd15178cc2da10f553b36a93859001"}, + {file = "rich-13.4.1-py3-none-any.whl", hash = "sha256:d204aadb50b936bf6b1a695385429d192bc1fdaf3e8b907e8e26f4c4e4b5bf75"}, + {file = "rich-13.4.1.tar.gz", hash = "sha256:76f6b65ea7e5c5d924ba80e322231d7cb5b5981aa60bfc1e694f1bc097fe6fe1"}, ] [package.dependencies] @@ -1297,7 +1297,8 @@ files = [ {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win32.whl", hash = "sha256:763d65baa3b952479c4e972669f679fe490eee058d5aa85da483ebae2009d231"}, {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:d000f258cf42fec2b1bbf2863c61d7b8918d31ffee905da62dede869254d3b8a"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:045e0626baf1c52e5527bd5db361bc83180faaba2ff586e763d3d5982a876a9e"}, - {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_12_6_arm64.whl", hash = "sha256:721bc4ba4525f53f6a611ec0967bdcee61b31df5a56801281027a3a6d1c2daf5"}, + {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:1a6391a7cabb7641c32517539ca42cf84b87b667bad38b78d4d42dd23e957c81"}, + {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:9c7617df90c1365638916b98cdd9be833d31d337dbcd722485597b43c4a215bf"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:41d0f1fa4c6830176eef5b276af04c89320ea616655d01327d5ce65e50575c94"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-win32.whl", hash = "sha256:f6d3d39611ac2e4f62c3128a9eed45f19a6608670c5a2f4f07f24e8de3441d38"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-win_amd64.whl", hash = "sha256:da538167284de58a52109a9b89b8f6a53ff8437dd6dc26d33b57bf6699153122"}, From 7e5aa02949c29e18d78ed9c18d2b55f62c94ae6a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Dec 2023 12:51:01 +0000 Subject: [PATCH 02/13] build(deps-dev): bump pre-commit from 3.2.0 to 3.3.2 (#15) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [pre-commit](https://github.com/pre-commit/pre-commit) from 3.2.0 to 3.3.2.
Release notes

Sourced from pre-commit's releases.

pre-commit v3.3.2

Fixes

pre-commit v3.3.1

Fixes

pre-commit v3.3.0

Features

pre-commit v3.2.2

Fixes

pre-commit v3.2.1

Fixes

Changelog

Sourced from pre-commit's changelog.

3.3.2 - 2023-05-17

Fixes

3.3.1 - 2023-05-02

Fixes

3.3.0 - 2023-05-01

Features

3.2.2 - 2023-04-03

Fixes

3.2.1 - 2023-03-25

Fixes

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=pre-commit&package-manager=pip&previous-version=3.2.0&new-version=3.3.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index f967661..025974b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -895,13 +895,13 @@ files = [ [[package]] name = "pre-commit" -version = "3.2.0" +version = "3.3.2" description = "A framework for managing and maintaining multi-language pre-commit hooks." optional = false python-versions = ">=3.8" files = [ - {file = "pre_commit-3.2.0-py2.py3-none-any.whl", hash = "sha256:f712d3688102e13c8e66b7d7dbd8934a6dda157e58635d89f7d6fecdca39ce8a"}, - {file = "pre_commit-3.2.0.tar.gz", hash = "sha256:818f0d998059934d0f81bb3667e3ccdc32da6ed7ccaac33e43dc231561ddaaa9"}, + {file = "pre_commit-3.3.2-py2.py3-none-any.whl", hash = "sha256:8056bc52181efadf4aac792b1f4f255dfd2fb5a350ded7335d251a68561e8cb6"}, + {file = "pre_commit-3.3.2.tar.gz", hash = "sha256:66e37bec2d882de1f17f88075047ef8962581f83c234ac08da21a0c58953d1f0"}, ] [package.dependencies] From f003a15a8ccb56eb5867821b64a7f593f24c2e94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Szafra=C5=84ski?= Date: Wed, 13 Dec 2023 14:26:58 +0100 Subject: [PATCH 03/13] feat: Native builds (#18) --- .github/workflows/test.yml | 25 ++++++++----------------- .pre-commit-config.yaml | 2 +- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6be7021..2496b52 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -14,7 +14,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.8"] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] name: Python ${{ matrix.python-version }} @@ -22,26 +22,17 @@ jobs: - name: Checkout uses: actions/checkout@v3 - - name: Set up Node.js - uses: actions/setup-node@v3 - with: - node-version: 16 - - - name: Install @devcontainers/cli - run: npm install --location=global @devcontainers/cli@0.27.1 + - name: Install poetry + run: pip install poetry - - name: Start Dev Container - env: - DOCKER_BUILDKIT: 1 - run: | - git config --global init.defaultBranch main - PYTHON_VERSION=${{ matrix.python-version }} devcontainer up --workspace-folder . + - name: Install dependencies + run: poetry install - - name: Lint package - run: devcontainer exec --workspace-folder . poe lint + - name: Lint project + run: poetry run poe lint - name: Test package - run: devcontainer exec --workspace-folder . poe test + run: poetry run poe test - name: Upload coverage uses: codecov/codecov-action@v3 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e2c7aae..d2f50dd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,7 +22,7 @@ repos: rev: 23.12.0 hooks: - id: black - language_version: python3.8 + language_version: python3 - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.1.7 hooks: From a7387737a3a8a9e498c52661ac984f3823037891 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Szafra=C5=84ski?= Date: Thu, 14 Dec 2023 10:30:52 +0100 Subject: [PATCH 04/13] Documentation init (#19) --- .readthedocs.yaml | 38 ++ documentation/docs/index.md | 8 + .../tutorials/getting-started/installation.md | 9 + documentation/mkdocs.yml | 7 + poetry.lock | 371 +++++++++++++++++- pyproject.toml | 2 + 6 files changed, 428 insertions(+), 7 deletions(-) create mode 100644 .readthedocs.yaml create mode 100644 documentation/docs/index.md create mode 100644 documentation/docs/tutorials/getting-started/installation.md create mode 100644 documentation/mkdocs.yml diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..27d53bf --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,38 @@ +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the OS, Python version and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.12" + # You can also specify other tool versions: + # nodejs: "19" + # rust: "1.64" + # golang: "1.19" + jobs: + post_create_environment: + # Install poetry + # https://python-poetry.org/docs/#installing-manually + - pip install poetry + # Tell poetry to not use a virtual environment + - poetry config virtualenvs.create false + post_install: + # Install dependencies with 'docs' dependency group + # https://python-poetry.org/docs/managing-dependencies/#dependency-groups + - poetry install --with docs + +# Build documentation in the "docs/" directory with Sphinx +mkdocs: + configuration: docs/mkdocs.yml + + +# Optional but recommended, declare the Python requirements required +# to build your documentation +# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html +# python: +# install: +# - requirements: docs/requirements.txt diff --git a/documentation/docs/index.md b/documentation/docs/index.md new file mode 100644 index 0000000..7e8ab1d --- /dev/null +++ b/documentation/docs/index.md @@ -0,0 +1,8 @@ +# Python-KSEF documentation + + +!!! warning "Warning" + + This Library is not yet production ready. It is in early alpha development right now. + +A python library for Polish KSEF (National e-invoice system, original: Krajowy System e-Faktur) system. diff --git a/documentation/docs/tutorials/getting-started/installation.md b/documentation/docs/tutorials/getting-started/installation.md new file mode 100644 index 0000000..4eaf7f0 --- /dev/null +++ b/documentation/docs/tutorials/getting-started/installation.md @@ -0,0 +1,9 @@ +# 1. Installation + +You can install the package using `pip`: + +```shell +pip install ksef +``` + +Other build tools such as `pipenv` or `poetry` are also supported. diff --git a/documentation/mkdocs.yml b/documentation/mkdocs.yml new file mode 100644 index 0000000..0cadc32 --- /dev/null +++ b/documentation/mkdocs.yml @@ -0,0 +1,7 @@ +site_name: My Docs +theme: + name: material +markdown_extensions: + - admonition + - pymdownx.details + - pymdownx.superfences diff --git a/poetry.lock b/poetry.lock index 025974b..7f6d10c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -73,6 +73,23 @@ docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib- tests = ["attrs[tests-no-zope]", "zope.interface"] tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", "mypy (>=0.971,<0.990)", "mypy (>=0.971,<0.990)", "pympler", "pympler", "pytest (>=4.3.0)", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-mypy-plugins", "pytest-xdist[psutil]", "pytest-xdist[psutil]"] +[[package]] +name = "babel" +version = "2.14.0" +description = "Internationalization utilities" +optional = false +python-versions = ">=3.7" +files = [ + {file = "Babel-2.14.0-py3-none-any.whl", hash = "sha256:efb1a25b7118e67ce3a259bed20545c29cb68be8ad2c784c83689981b7a57287"}, + {file = "Babel-2.14.0.tar.gz", hash = "sha256:6919867db036398ba21eb5c7a0f6b28ab8cbc3ae7a73a44ebe34ae74a4e7d363"}, +] + +[package.dependencies] +pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""} + +[package.extras] +dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] + [[package]] name = "binaryornot" version = "0.4.4" @@ -517,6 +534,23 @@ files = [ docs = ["furo (>=2022.12.7)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.22,!=1.23.4)"] testing = ["covdefaults (>=2.3)", "coverage (>=7.2.1)", "pytest (>=7.2.2)", "pytest-cov (>=4)", "pytest-timeout (>=2.1)"] +[[package]] +name = "ghp-import" +version = "2.1.0" +description = "Copy your docs directly to the gh-pages branch." +optional = false +python-versions = "*" +files = [ + {file = "ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343"}, + {file = "ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619"}, +] + +[package.dependencies] +python-dateutil = ">=2.8.1" + +[package.extras] +dev = ["flake8", "markdown", "twine", "wheel"] + [[package]] name = "gitdb" version = "4.0.10" @@ -570,6 +604,25 @@ files = [ {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, ] +[[package]] +name = "importlib-metadata" +version = "7.0.0" +description = "Read metadata from Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "importlib_metadata-7.0.0-py3-none-any.whl", hash = "sha256:d97503976bb81f40a193d41ee6570868479c69d5068651eb039c40d850c59d67"}, + {file = "importlib_metadata-7.0.0.tar.gz", hash = "sha256:7fc841f8b8332803464e5dc1c63a2e59121f46ca186c0e2e182e80bf8c1319f7"}, +] + +[package.dependencies] +zipp = ">=0.5" + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] +perf = ["ipython"] +testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] + [[package]] name = "iniconfig" version = "2.0.0" @@ -613,6 +666,24 @@ files = [ arrow = "*" jinja2 = "*" +[[package]] +name = "markdown" +version = "3.5.1" +description = "Python implementation of John Gruber's Markdown." +optional = false +python-versions = ">=3.8" +files = [ + {file = "Markdown-3.5.1-py3-none-any.whl", hash = "sha256:5874b47d4ee3f0b14d764324d2c94c03ea66bee56f2d929da9f2508d65e722dc"}, + {file = "Markdown-3.5.1.tar.gz", hash = "sha256:b65d7beb248dc22f2e8a31fb706d93798093c308dc1aba295aedeb9d41a813bd"}, +] + +[package.dependencies] +importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} + +[package.extras] +docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.5)", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-nature (>=0.6)", "mkdocs-section-index", "mkdocstrings[python]"] +testing = ["coverage", "pyyaml"] + [[package]] name = "markdown-it-py" version = "2.2.0" @@ -707,6 +778,88 @@ files = [ {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, ] +[[package]] +name = "mergedeep" +version = "1.3.4" +description = "A deep merge function for 🐍." +optional = false +python-versions = ">=3.6" +files = [ + {file = "mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307"}, + {file = "mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8"}, +] + +[[package]] +name = "mkdocs" +version = "1.5.3" +description = "Project documentation with Markdown." +optional = false +python-versions = ">=3.7" +files = [ + {file = "mkdocs-1.5.3-py3-none-any.whl", hash = "sha256:3b3a78e736b31158d64dbb2f8ba29bd46a379d0c6e324c2246c3bc3d2189cfc1"}, + {file = "mkdocs-1.5.3.tar.gz", hash = "sha256:eb7c99214dcb945313ba30426c2451b735992c73c2e10838f76d09e39ff4d0e2"}, +] + +[package.dependencies] +click = ">=7.0" +colorama = {version = ">=0.4", markers = "platform_system == \"Windows\""} +ghp-import = ">=1.0" +importlib-metadata = {version = ">=4.3", markers = "python_version < \"3.10\""} +jinja2 = ">=2.11.1" +markdown = ">=3.2.1" +markupsafe = ">=2.0.1" +mergedeep = ">=1.3.4" +packaging = ">=20.5" +pathspec = ">=0.11.1" +platformdirs = ">=2.2.0" +pyyaml = ">=5.1" +pyyaml-env-tag = ">=0.1" +watchdog = ">=2.0" + +[package.extras] +i18n = ["babel (>=2.9.0)"] +min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-import (==1.0)", "importlib-metadata (==4.3)", "jinja2 (==2.11.1)", "markdown (==3.2.1)", "markupsafe (==2.0.1)", "mergedeep (==1.3.4)", "packaging (==20.5)", "pathspec (==0.11.1)", "platformdirs (==2.2.0)", "pyyaml (==5.1)", "pyyaml-env-tag (==0.1)", "typing-extensions (==3.10)", "watchdog (==2.0)"] + +[[package]] +name = "mkdocs-material" +version = "9.5.2" +description = "Documentation that simply works" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mkdocs_material-9.5.2-py3-none-any.whl", hash = "sha256:6ed0fbf4682491766f0ec1acc955db6901c2fd424c7ab343964ef51b819741f5"}, + {file = "mkdocs_material-9.5.2.tar.gz", hash = "sha256:ca8b9cd2b3be53e858e5a1a45ac9668bd78d95d77a30288bb5ebc1a31db6184c"}, +] + +[package.dependencies] +babel = ">=2.10,<3.0" +colorama = ">=0.4,<1.0" +jinja2 = ">=3.0,<4.0" +markdown = ">=3.2,<4.0" +mkdocs = ">=1.5.3,<2.0" +mkdocs-material-extensions = ">=1.3,<2.0" +paginate = ">=0.5,<1.0" +pygments = ">=2.16,<3.0" +pymdown-extensions = ">=10.2,<11.0" +regex = ">=2022.4" +requests = ">=2.26,<3.0" + +[package.extras] +git = ["mkdocs-git-committers-plugin-2 (>=1.1,<2.0)", "mkdocs-git-revision-date-localized-plugin (>=1.2,<2.0)"] +imaging = ["cairosvg (>=2.6,<3.0)", "pillow (>=9.4,<10.0)"] +recommended = ["mkdocs-minify-plugin (>=0.7,<1.0)", "mkdocs-redirects (>=1.2,<2.0)", "mkdocs-rss-plugin (>=1.6,<2.0)"] + +[[package]] +name = "mkdocs-material-extensions" +version = "1.3.1" +description = "Extension pack for Python Markdown and MkDocs Material." +optional = false +python-versions = ">=3.8" +files = [ + {file = "mkdocs_material_extensions-1.3.1-py3-none-any.whl", hash = "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31"}, + {file = "mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443"}, +] + [[package]] name = "mypy" version = "1.1.1" @@ -792,6 +945,16 @@ files = [ [package.dependencies] pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" +[[package]] +name = "paginate" +version = "0.5.6" +description = "Divides large result sets into pages for easier browsing" +optional = false +python-versions = "*" +files = [ + {file = "paginate-0.5.6.tar.gz", hash = "sha256:5e6007b6a9398177a7e1648d04fdd9f8c9766a1a945bceac82f1929e8c78af2d"}, +] + [[package]] name = "pastel" version = "0.2.1" @@ -990,17 +1153,36 @@ email = ["email-validator (>=1.0.3)"] [[package]] name = "pygments" -version = "2.14.0" +version = "2.17.2" description = "Pygments is a syntax highlighting package written in Python." optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "Pygments-2.14.0-py3-none-any.whl", hash = "sha256:fa7bd7bd2771287c0de303af8bfdfc731f51bd2c6a47ab69d117138893b82717"}, - {file = "Pygments-2.14.0.tar.gz", hash = "sha256:b3ed06a9e8ac9a9aae5a6f5dbe78a8a58655d17b43b93c078f094ddc476ae297"}, + {file = "pygments-2.17.2-py3-none-any.whl", hash = "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c"}, + {file = "pygments-2.17.2.tar.gz", hash = "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"}, ] [package.extras] plugins = ["importlib-metadata"] +windows-terminal = ["colorama (>=0.4.6)"] + +[[package]] +name = "pymdown-extensions" +version = "10.5" +description = "Extension pack for Python Markdown." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pymdown_extensions-10.5-py3-none-any.whl", hash = "sha256:1f0ca8bb5beff091315f793ee17683bc1390731f6ac4c5eb01e27464b80fe879"}, + {file = "pymdown_extensions-10.5.tar.gz", hash = "sha256:1b60f1e462adbec5a1ed79dac91f666c9c0d241fa294de1989f29d20096cfd0b"}, +] + +[package.dependencies] +markdown = ">=3.5" +pyyaml = "*" + +[package.extras] +extra = ["pygments (>=2.12)"] [[package]] name = "pyparsing" @@ -1139,6 +1321,17 @@ text-unidecode = ">=1.3" [package.extras] unidecode = ["Unidecode (>=1.1.1)"] +[[package]] +name = "pytz" +version = "2023.3.post1" +description = "World timezone definitions, modern and historical" +optional = false +python-versions = "*" +files = [ + {file = "pytz-2023.3.post1-py2.py3-none-any.whl", hash = "sha256:ce42d816b81b68506614c11e8937d3aa9e41007ceb50bfdcb0749b921bf646c7"}, + {file = "pytz-2023.3.post1.tar.gz", hash = "sha256:7b4fddbeb94a1eba4b557da24f19fdf9db575192544270a9101d8509f9f43d7b"}, +] + [[package]] name = "pyyaml" version = "6.0" @@ -1188,6 +1381,20 @@ files = [ {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, ] +[[package]] +name = "pyyaml-env-tag" +version = "0.1" +description = "A custom YAML tag for referencing environment variables in YAML files. " +optional = false +python-versions = ">=3.6" +files = [ + {file = "pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069"}, + {file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"}, +] + +[package.dependencies] +pyyaml = "*" + [[package]] name = "questionary" version = "1.10.0" @@ -1205,6 +1412,103 @@ prompt_toolkit = ">=2.0,<4.0" [package.extras] docs = ["Sphinx (>=3.3,<4.0)", "sphinx-autobuild (>=2020.9.1,<2021.0.0)", "sphinx-autodoc-typehints (>=1.11.1,<2.0.0)", "sphinx-copybutton (>=0.3.1,<0.4.0)", "sphinx-rtd-theme (>=0.5.0,<0.6.0)"] +[[package]] +name = "regex" +version = "2023.10.3" +description = "Alternative regular expression module, to replace re." +optional = false +python-versions = ">=3.7" +files = [ + {file = "regex-2023.10.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4c34d4f73ea738223a094d8e0ffd6d2c1a1b4c175da34d6b0de3d8d69bee6bcc"}, + {file = "regex-2023.10.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a8f4e49fc3ce020f65411432183e6775f24e02dff617281094ba6ab079ef0915"}, + {file = "regex-2023.10.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4cd1bccf99d3ef1ab6ba835308ad85be040e6a11b0977ef7ea8c8005f01a3c29"}, + {file = "regex-2023.10.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:81dce2ddc9f6e8f543d94b05d56e70d03a0774d32f6cca53e978dc01e4fc75b8"}, + {file = "regex-2023.10.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c6b4d23c04831e3ab61717a707a5d763b300213db49ca680edf8bf13ab5d91b"}, + {file = "regex-2023.10.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c15ad0aee158a15e17e0495e1e18741573d04eb6da06d8b84af726cfc1ed02ee"}, + {file = "regex-2023.10.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6239d4e2e0b52c8bd38c51b760cd870069f0bdf99700a62cd509d7a031749a55"}, + {file = "regex-2023.10.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4a8bf76e3182797c6b1afa5b822d1d5802ff30284abe4599e1247be4fd6b03be"}, + {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d9c727bbcf0065cbb20f39d2b4f932f8fa1631c3e01fcedc979bd4f51fe051c5"}, + {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3ccf2716add72f80714b9a63899b67fa711b654be3fcdd34fa391d2d274ce767"}, + {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:107ac60d1bfdc3edb53be75e2a52aff7481b92817cfdddd9b4519ccf0e54a6ff"}, + {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:00ba3c9818e33f1fa974693fb55d24cdc8ebafcb2e4207680669d8f8d7cca79a"}, + {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f0a47efb1dbef13af9c9a54a94a0b814902e547b7f21acb29434504d18f36e3a"}, + {file = "regex-2023.10.3-cp310-cp310-win32.whl", hash = "sha256:36362386b813fa6c9146da6149a001b7bd063dabc4d49522a1f7aa65b725c7ec"}, + {file = "regex-2023.10.3-cp310-cp310-win_amd64.whl", hash = "sha256:c65a3b5330b54103e7d21cac3f6bf3900d46f6d50138d73343d9e5b2900b2353"}, + {file = "regex-2023.10.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:90a79bce019c442604662d17bf69df99090e24cdc6ad95b18b6725c2988a490e"}, + {file = "regex-2023.10.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c7964c2183c3e6cce3f497e3a9f49d182e969f2dc3aeeadfa18945ff7bdd7051"}, + {file = "regex-2023.10.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ef80829117a8061f974b2fda8ec799717242353bff55f8a29411794d635d964"}, + {file = "regex-2023.10.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5addc9d0209a9afca5fc070f93b726bf7003bd63a427f65ef797a931782e7edc"}, + {file = "regex-2023.10.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c148bec483cc4b421562b4bcedb8e28a3b84fcc8f0aa4418e10898f3c2c0eb9b"}, + {file = "regex-2023.10.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d1f21af4c1539051049796a0f50aa342f9a27cde57318f2fc41ed50b0dbc4ac"}, + {file = "regex-2023.10.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0b9ac09853b2a3e0d0082104036579809679e7715671cfbf89d83c1cb2a30f58"}, + {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ebedc192abbc7fd13c5ee800e83a6df252bec691eb2c4bedc9f8b2e2903f5e2a"}, + {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d8a993c0a0ffd5f2d3bda23d0cd75e7086736f8f8268de8a82fbc4bd0ac6791e"}, + {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:be6b7b8d42d3090b6c80793524fa66c57ad7ee3fe9722b258aec6d0672543fd0"}, + {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4023e2efc35a30e66e938de5aef42b520c20e7eda7bb5fb12c35e5d09a4c43f6"}, + {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0d47840dc05e0ba04fe2e26f15126de7c755496d5a8aae4a08bda4dd8d646c54"}, + {file = "regex-2023.10.3-cp311-cp311-win32.whl", hash = "sha256:9145f092b5d1977ec8c0ab46e7b3381b2fd069957b9862a43bd383e5c01d18c2"}, + {file = "regex-2023.10.3-cp311-cp311-win_amd64.whl", hash = "sha256:b6104f9a46bd8743e4f738afef69b153c4b8b592d35ae46db07fc28ae3d5fb7c"}, + {file = "regex-2023.10.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:bff507ae210371d4b1fe316d03433ac099f184d570a1a611e541923f78f05037"}, + {file = "regex-2023.10.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:be5e22bbb67924dea15039c3282fa4cc6cdfbe0cbbd1c0515f9223186fc2ec5f"}, + {file = "regex-2023.10.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a992f702c9be9c72fa46f01ca6e18d131906a7180950958f766c2aa294d4b41"}, + {file = "regex-2023.10.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7434a61b158be563c1362d9071358f8ab91b8d928728cd2882af060481244c9e"}, + {file = "regex-2023.10.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c2169b2dcabf4e608416f7f9468737583ce5f0a6e8677c4efbf795ce81109d7c"}, + {file = "regex-2023.10.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9e908ef5889cda4de038892b9accc36d33d72fb3e12c747e2799a0e806ec841"}, + {file = "regex-2023.10.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12bd4bc2c632742c7ce20db48e0d99afdc05e03f0b4c1af90542e05b809a03d9"}, + {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bc72c231f5449d86d6c7d9cc7cd819b6eb30134bb770b8cfdc0765e48ef9c420"}, + {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bce8814b076f0ce5766dc87d5a056b0e9437b8e0cd351b9a6c4e1134a7dfbda9"}, + {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:ba7cd6dc4d585ea544c1412019921570ebd8a597fabf475acc4528210d7c4a6f"}, + {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b0c7d2f698e83f15228ba41c135501cfe7d5740181d5903e250e47f617eb4292"}, + {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5a8f91c64f390ecee09ff793319f30a0f32492e99f5dc1c72bc361f23ccd0a9a"}, + {file = "regex-2023.10.3-cp312-cp312-win32.whl", hash = "sha256:ad08a69728ff3c79866d729b095872afe1e0557251da4abb2c5faff15a91d19a"}, + {file = "regex-2023.10.3-cp312-cp312-win_amd64.whl", hash = "sha256:39cdf8d141d6d44e8d5a12a8569d5a227f645c87df4f92179bd06e2e2705e76b"}, + {file = "regex-2023.10.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a3ee019a9befe84fa3e917a2dd378807e423d013377a884c1970a3c2792d293"}, + {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76066d7ff61ba6bf3cb5efe2428fc82aac91802844c022d849a1f0f53820502d"}, + {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfe50b61bab1b1ec260fa7cd91106fa9fece57e6beba05630afe27c71259c59b"}, + {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fd88f373cb71e6b59b7fa597e47e518282455c2734fd4306a05ca219a1991b0"}, + {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3ab05a182c7937fb374f7e946f04fb23a0c0699c0450e9fb02ef567412d2fa3"}, + {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dac37cf08fcf2094159922edc7a2784cfcc5c70f8354469f79ed085f0328ebdf"}, + {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e54ddd0bb8fb626aa1f9ba7b36629564544954fff9669b15da3610c22b9a0991"}, + {file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:3367007ad1951fde612bf65b0dffc8fd681a4ab98ac86957d16491400d661302"}, + {file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:16f8740eb6dbacc7113e3097b0a36065a02e37b47c936b551805d40340fb9971"}, + {file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:f4f2ca6df64cbdd27f27b34f35adb640b5d2d77264228554e68deda54456eb11"}, + {file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:39807cbcbe406efca2a233884e169d056c35aa7e9f343d4e78665246a332f597"}, + {file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7eece6fbd3eae4a92d7c748ae825cbc1ee41a89bb1c3db05b5578ed3cfcfd7cb"}, + {file = "regex-2023.10.3-cp37-cp37m-win32.whl", hash = "sha256:ce615c92d90df8373d9e13acddd154152645c0dc060871abf6bd43809673d20a"}, + {file = "regex-2023.10.3-cp37-cp37m-win_amd64.whl", hash = "sha256:0f649fa32fe734c4abdfd4edbb8381c74abf5f34bc0b3271ce687b23729299ed"}, + {file = "regex-2023.10.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9b98b7681a9437262947f41c7fac567c7e1f6eddd94b0483596d320092004533"}, + {file = "regex-2023.10.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:91dc1d531f80c862441d7b66c4505cd6ea9d312f01fb2f4654f40c6fdf5cc37a"}, + {file = "regex-2023.10.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82fcc1f1cc3ff1ab8a57ba619b149b907072e750815c5ba63e7aa2e1163384a4"}, + {file = "regex-2023.10.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7979b834ec7a33aafae34a90aad9f914c41fd6eaa8474e66953f3f6f7cbd4368"}, + {file = "regex-2023.10.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ef71561f82a89af6cfcbee47f0fabfdb6e63788a9258e913955d89fdd96902ab"}, + {file = "regex-2023.10.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd829712de97753367153ed84f2de752b86cd1f7a88b55a3a775eb52eafe8a94"}, + {file = "regex-2023.10.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00e871d83a45eee2f8688d7e6849609c2ca2a04a6d48fba3dff4deef35d14f07"}, + {file = "regex-2023.10.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:706e7b739fdd17cb89e1fbf712d9dc21311fc2333f6d435eac2d4ee81985098c"}, + {file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cc3f1c053b73f20c7ad88b0d1d23be7e7b3901229ce89f5000a8399746a6e039"}, + {file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6f85739e80d13644b981a88f529d79c5bdf646b460ba190bffcaf6d57b2a9863"}, + {file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:741ba2f511cc9626b7561a440f87d658aabb3d6b744a86a3c025f866b4d19e7f"}, + {file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:e77c90ab5997e85901da85131fd36acd0ed2221368199b65f0d11bca44549711"}, + {file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:979c24cbefaf2420c4e377ecd1f165ea08cc3d1fbb44bdc51bccbbf7c66a2cb4"}, + {file = "regex-2023.10.3-cp38-cp38-win32.whl", hash = "sha256:58837f9d221744d4c92d2cf7201c6acd19623b50c643b56992cbd2b745485d3d"}, + {file = "regex-2023.10.3-cp38-cp38-win_amd64.whl", hash = "sha256:c55853684fe08d4897c37dfc5faeff70607a5f1806c8be148f1695be4a63414b"}, + {file = "regex-2023.10.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2c54e23836650bdf2c18222c87f6f840d4943944146ca479858404fedeb9f9af"}, + {file = "regex-2023.10.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:69c0771ca5653c7d4b65203cbfc5e66db9375f1078689459fe196fe08b7b4930"}, + {file = "regex-2023.10.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ac965a998e1388e6ff2e9781f499ad1eaa41e962a40d11c7823c9952c77123e"}, + {file = "regex-2023.10.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c0e8fae5b27caa34177bdfa5a960c46ff2f78ee2d45c6db15ae3f64ecadde14"}, + {file = "regex-2023.10.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6c56c3d47da04f921b73ff9415fbaa939f684d47293f071aa9cbb13c94afc17d"}, + {file = "regex-2023.10.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ef1e014eed78ab650bef9a6a9cbe50b052c0aebe553fb2881e0453717573f52"}, + {file = "regex-2023.10.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d29338556a59423d9ff7b6eb0cb89ead2b0875e08fe522f3e068b955c3e7b59b"}, + {file = "regex-2023.10.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9c6d0ced3c06d0f183b73d3c5920727268d2201aa0fe6d55c60d68c792ff3588"}, + {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:994645a46c6a740ee8ce8df7911d4aee458d9b1bc5639bc968226763d07f00fa"}, + {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:66e2fe786ef28da2b28e222c89502b2af984858091675044d93cb50e6f46d7af"}, + {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:11175910f62b2b8c055f2b089e0fedd694fe2be3941b3e2633653bc51064c528"}, + {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:06e9abc0e4c9ab4779c74ad99c3fc10d3967d03114449acc2c2762ad4472b8ca"}, + {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:fb02e4257376ae25c6dd95a5aec377f9b18c09be6ebdefa7ad209b9137b73d48"}, + {file = "regex-2023.10.3-cp39-cp39-win32.whl", hash = "sha256:3b2c3502603fab52d7619b882c25a6850b766ebd1b18de3df23b2f939360e1bd"}, + {file = "regex-2023.10.3-cp39-cp39-win_amd64.whl", hash = "sha256:adbccd17dcaff65704c856bd29951c58a1bd4b2b0f8ad6b826dbd543fe740988"}, + {file = "regex-2023.10.3.tar.gz", hash = "sha256:3fef4f844d2290ee0ba57addcec17eec9e3df73f10a2748485dfd6a3a188cc0f"}, +] + [[package]] name = "requests" version = "2.28.2" @@ -1297,8 +1601,7 @@ files = [ {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win32.whl", hash = "sha256:763d65baa3b952479c4e972669f679fe490eee058d5aa85da483ebae2009d231"}, {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:d000f258cf42fec2b1bbf2863c61d7b8918d31ffee905da62dede869254d3b8a"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:045e0626baf1c52e5527bd5db361bc83180faaba2ff586e763d3d5982a876a9e"}, - {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:1a6391a7cabb7641c32517539ca42cf84b87b667bad38b78d4d42dd23e957c81"}, - {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:9c7617df90c1365638916b98cdd9be833d31d337dbcd722485597b43c4a215bf"}, + {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_12_6_arm64.whl", hash = "sha256:721bc4ba4525f53f6a611ec0967bdcee61b31df5a56801281027a3a6d1c2daf5"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:41d0f1fa4c6830176eef5b276af04c89320ea616655d01327d5ce65e50575c94"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-win32.whl", hash = "sha256:f6d3d39611ac2e4f62c3128a9eed45f19a6608670c5a2f4f07f24e8de3441d38"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-win_amd64.whl", hash = "sha256:da538167284de58a52109a9b89b8f6a53ff8437dd6dc26d33b57bf6699153122"}, @@ -1605,6 +1908,45 @@ platformdirs = ">=2.4,<4" docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=22.12)"] test = ["covdefaults (>=2.2.2)", "coverage (>=7.1)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23)", "pytest (>=7.2.1)", "pytest-env (>=0.8.1)", "pytest-freezegun (>=0.4.2)", "pytest-mock (>=3.10)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)"] +[[package]] +name = "watchdog" +version = "3.0.0" +description = "Filesystem events monitoring" +optional = false +python-versions = ">=3.7" +files = [ + {file = "watchdog-3.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:336adfc6f5cc4e037d52db31194f7581ff744b67382eb6021c868322e32eef41"}, + {file = "watchdog-3.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a70a8dcde91be523c35b2bf96196edc5730edb347e374c7de7cd20c43ed95397"}, + {file = "watchdog-3.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:adfdeab2da79ea2f76f87eb42a3ab1966a5313e5a69a0213a3cc06ef692b0e96"}, + {file = "watchdog-3.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2b57a1e730af3156d13b7fdddfc23dea6487fceca29fc75c5a868beed29177ae"}, + {file = "watchdog-3.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7ade88d0d778b1b222adebcc0927428f883db07017618a5e684fd03b83342bd9"}, + {file = "watchdog-3.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7e447d172af52ad204d19982739aa2346245cc5ba6f579d16dac4bfec226d2e7"}, + {file = "watchdog-3.0.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:9fac43a7466eb73e64a9940ac9ed6369baa39b3bf221ae23493a9ec4d0022674"}, + {file = "watchdog-3.0.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8ae9cda41fa114e28faf86cb137d751a17ffd0316d1c34ccf2235e8a84365c7f"}, + {file = "watchdog-3.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:25f70b4aa53bd743729c7475d7ec41093a580528b100e9a8c5b5efe8899592fc"}, + {file = "watchdog-3.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4f94069eb16657d2c6faada4624c39464f65c05606af50bb7902e036e3219be3"}, + {file = "watchdog-3.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7c5f84b5194c24dd573fa6472685b2a27cc5a17fe5f7b6fd40345378ca6812e3"}, + {file = "watchdog-3.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3aa7f6a12e831ddfe78cdd4f8996af9cf334fd6346531b16cec61c3b3c0d8da0"}, + {file = "watchdog-3.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:233b5817932685d39a7896b1090353fc8efc1ef99c9c054e46c8002561252fb8"}, + {file = "watchdog-3.0.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:13bbbb462ee42ec3c5723e1205be8ced776f05b100e4737518c67c8325cf6100"}, + {file = "watchdog-3.0.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:8f3ceecd20d71067c7fd4c9e832d4e22584318983cabc013dbf3f70ea95de346"}, + {file = "watchdog-3.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c9d8c8ec7efb887333cf71e328e39cffbf771d8f8f95d308ea4125bf5f90ba64"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:0e06ab8858a76e1219e68c7573dfeba9dd1c0219476c5a44d5333b01d7e1743a"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:d00e6be486affb5781468457b21a6cbe848c33ef43f9ea4a73b4882e5f188a44"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:c07253088265c363d1ddf4b3cdb808d59a0468ecd017770ed716991620b8f77a"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:5113334cf8cf0ac8cd45e1f8309a603291b614191c9add34d33075727a967709"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:51f90f73b4697bac9c9a78394c3acbbd331ccd3655c11be1a15ae6fe289a8c83"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:ba07e92756c97e3aca0912b5cbc4e5ad802f4557212788e72a72a47ff376950d"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:d429c2430c93b7903914e4db9a966c7f2b068dd2ebdd2fa9b9ce094c7d459f33"}, + {file = "watchdog-3.0.0-py3-none-win32.whl", hash = "sha256:3ed7c71a9dccfe838c2f0b6314ed0d9b22e77d268c67e015450a29036a81f60f"}, + {file = "watchdog-3.0.0-py3-none-win_amd64.whl", hash = "sha256:4c9956d27be0bb08fc5f30d9d0179a855436e655f046d288e2bcc11adfae893c"}, + {file = "watchdog-3.0.0-py3-none-win_ia64.whl", hash = "sha256:5d9f3a10e02d7371cd929b5d8f11e87d4bad890212ed3901f9b4d68767bee759"}, + {file = "watchdog-3.0.0.tar.gz", hash = "sha256:4d98a320595da7a7c5a18fc48cb633c2e73cda78f93cac2ef42d42bf609a33f9"}, +] + +[package.extras] +watchmedo = ["PyYAML (>=3.10)"] + [[package]] name = "wcwidth" version = "0.2.6" @@ -1630,7 +1972,22 @@ files = [ [package.extras] test = ["pytest (>=6.0.0)"] +[[package]] +name = "zipp" +version = "3.17.0" +description = "Backport of pathlib-compatible object wrapper for zip files" +optional = false +python-versions = ">=3.8" +files = [ + {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"}, + {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] + [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "a0782b4a8ca6eb10e263a09cc7fadc18c9f46304176fbfd013f5b936ae94934f" +content-hash = "db689ba3cec94930a86e04bb51071583f92218d29e61f5f0c81d720a3f6a1baa" diff --git a/pyproject.toml b/pyproject.toml index 7499645..646924f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,6 +46,8 @@ pytest-responses = "^0.5.1" [tool.poetry.group.dev.dependencies] # https://python-poetry.org/docs/master/managing-dependencies/ cruft = "^2.12.0" pdoc = "^13.0.0" +mkdocs = "^1.5.3" +mkdocs-material = "^9.5.2" [tool.black] # https://black.readthedocs.io/en/stable/usage_and_configuration/the_basics.html#configuration-via-a-file line-length = 100 From 752f077bc73588134feaf82be1a511104754fdc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Szafra=C5=84ski?= Date: Thu, 14 Dec 2023 10:32:52 +0100 Subject: [PATCH 05/13] chore: Remove failing pre-commit task --- .pre-commit-config.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d2f50dd..2f52408 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -54,7 +54,6 @@ repos: - id: mixed-line-ending - id: name-tests-test args: [--pytest-test-first] - - id: no-commit-to-branch - id: trailing-whitespace types: [python] - repo: https://github.com/commitizen-tools/commitizen From 04d7d19a74fab8643052f6cd333c8321a2bad69a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Szafra=C5=84ski?= Date: Thu, 14 Dec 2023 10:34:01 +0100 Subject: [PATCH 06/13] chore: Use a docs poetry group --- poetry.lock | 2 +- pyproject.toml | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index 7f6d10c..2f7bf13 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1990,4 +1990,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "db689ba3cec94930a86e04bb51071583f92218d29e61f5f0c81d720a3f6a1baa" +content-hash = "325ad0d9dee133b6f4e45bd0874f1891a9f1eb541065caad9dc8089155526a5d" diff --git a/pyproject.toml b/pyproject.toml index 646924f..7d46979 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,6 +46,9 @@ pytest-responses = "^0.5.1" [tool.poetry.group.dev.dependencies] # https://python-poetry.org/docs/master/managing-dependencies/ cruft = "^2.12.0" pdoc = "^13.0.0" + + +[tool.poetry.group.docs.dependencies] mkdocs = "^1.5.3" mkdocs-material = "^9.5.2" From 4c7d4708a219af3ff30469daf91cb200f357e4ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Szafra=C5=84ski?= Date: Thu, 14 Dec 2023 10:37:40 +0100 Subject: [PATCH 07/13] chore: Use a docs poetry group --- .readthedocs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 27d53bf..cd8b8ae 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -8,7 +8,7 @@ version: 2 build: os: ubuntu-22.04 tools: - python: "3.12" + python: "3.8" # You can also specify other tool versions: # nodejs: "19" # rust: "1.64" From feb24a39d35fa177e36b8d6edf70e44a9e853c4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Szafra=C5=84ski?= Date: Thu, 14 Dec 2023 10:41:31 +0100 Subject: [PATCH 08/13] chore: Use a docs poetry group --- .readthedocs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index cd8b8ae..a9bbf5b 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -27,7 +27,7 @@ build: # Build documentation in the "docs/" directory with Sphinx mkdocs: - configuration: docs/mkdocs.yml + configuration: documentation/mkdocs.yml # Optional but recommended, declare the Python requirements required From c2416d9c5031d9f9f98207e9d8fe565eab129608 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Szafra=C5=84ski?= Date: Mon, 22 Jan 2024 12:40:14 +0100 Subject: [PATCH 09/13] feat: Base for invoice listing --- src/ksef/auth/base.py | 5 ++++ src/ksef/auth/token.py | 18 ++++++++++++- src/ksef/client.py | 8 ++++++ src/ksef/exceptions.py | 55 ++++++++++++++++++++++++++++++++++++++++ src/ksef/utils.py | 36 ++++++++++++++++++++++++++ tests/auth/test_token.py | 2 +- tests/test_utils.py | 16 ++++++++++++ 7 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 src/ksef/exceptions.py create mode 100644 src/ksef/utils.py create mode 100644 tests/test_utils.py diff --git a/src/ksef/auth/base.py b/src/ksef/auth/base.py index 11ff1f8..c514934 100644 --- a/src/ksef/auth/base.py +++ b/src/ksef/auth/base.py @@ -14,3 +14,8 @@ def modify_request(self, request: Request) -> Request: :param request: Request to be enriched """ ... + + @abstractmethod + def authorize(self, nip: str) -> None: + """Perform the authorization process.""" + ... diff --git a/src/ksef/auth/token.py b/src/ksef/auth/token.py index 0d26c93..365c3bd 100644 --- a/src/ksef/auth/token.py +++ b/src/ksef/auth/token.py @@ -21,11 +21,14 @@ ) from ksef.models.responses.authorization_challenge import AuthorizationChallenge from ksef.models.responses.authorization_token import AuthorizationToken +from ksef.utils import response_to_exception class TokenAuthorization(Authorization): """Simple token-based authorization.""" + authorization_token: AuthorizationToken + def __init__( self, token: str, public_key: str, base_url: str = BASE_URL, timeout: int = TIMEOUT ): @@ -40,11 +43,18 @@ def modify_request(self, request: Request) -> Request: :param request: Request to be enriched """ request.prepare() - request.headers["Authorization"] = self.token # TODO: This is just a stub implementaion + request.headers["SessionToken"] = self.token headers = self.build_headers() request.headers.update(headers) return request + def authorize(self, nip: str) -> None: + """Authorize the token authorization by obtaining a session token.""" + challenge = self.get_authorization_challenge(nip=nip) + authorization_token = self.init_token(authorization_challenge=challenge, nip=nip) + self.authorization_token = authorization_token + self.token = authorization_token.session_token.token + def build_url(self, url: str) -> str: """Construct a full URL.""" return urljoin(base=self.base_url, url=url) @@ -74,6 +84,9 @@ def get_authorization_challenge(self, nip: str) -> AuthorizationChallenge: timeout=TIMEOUT, ) challenge = response.json() + error = response_to_exception(response) + if error is not None: + raise error return AuthorizationChallenge( timestamp=challenge["timestamp"], challenge=challenge["challenge"] ) @@ -118,4 +131,7 @@ def init_token( data=document_xml, timeout=self.timeout, ) + error = response_to_exception(response) + if error is not None: + raise error return AuthorizationToken.from_dict(response.json()) diff --git a/src/ksef/client.py b/src/ksef/client.py index 4742c67..7b8f476 100644 --- a/src/ksef/client.py +++ b/src/ksef/client.py @@ -35,6 +35,14 @@ def search_invoices(self, page_size: int = 100, page_offset: int = 0) -> Dict[st request = Request( method="POST", url=self.build_url(url=URL_QUERY_INVOICES, params=params), + json={ + "queryCriteria": { + "subjectType": "subject1", + "type": "range", + "invoicingDateFrom": "2023-11-14T13:21:09.000Z", + "invoicingDateTo": "2023-12-12T13:21:09.000Z", + } + }, ) request = self.authorization.modify_request(request) prepared_request = request.prepare() diff --git a/src/ksef/exceptions.py b/src/ksef/exceptions.py new file mode 100644 index 0000000..3fd90b1 --- /dev/null +++ b/src/ksef/exceptions.py @@ -0,0 +1,55 @@ +"""KSEF-specific exceptions.""" +from requests import Response + + +class KsefError(Exception): + """Base exception class for all KSEF-related exceptions.""" + + @property + def prefix(self) -> str: + """ + Pretty auto-generated error message prefix. + + Used for transforming the exception to a human-readable error message. + """ + from ksef.utils import camelcase_to_words + + prefix = self.__class__.__name__ + return camelcase_to_words(prefix) + + @property + def message(self) -> str: + """Human-readable error message.""" + return "-this exception has no message-" + + @property + def should_retry(self) -> bool: + """Whether the call that called the exception can be retried.""" + return False + + def __str__(self) -> str: # noqa: D105 + return f"{self.prefix}: {self.message}" + + +class _ResponseMixin: + def __init__(self, response: Response): + self.response = response + super().__init__() + + +class UnsupportedResponseError(_ResponseMixin, KsefError): + """Unsupported response status code.""" + + @property + def message(self) -> str: + """Human-readable error message.""" + return f"Unsupported response status code: {self.response.status_code}" + + +class RateLimitExceededError(_ResponseMixin, KsefError): + """Rate limit exceeded.""" + + should_retry = True + message = ( + "Your client has sent too many requests and has been throttled. Please try again later." + ) diff --git a/src/ksef/utils.py b/src/ksef/utils.py new file mode 100644 index 0000000..d69dca9 --- /dev/null +++ b/src/ksef/utils.py @@ -0,0 +1,36 @@ +"""Miscellaneous utilities.""" + +import re +from http import HTTPStatus +from typing import Optional + +from requests import Response + +from ksef.exceptions import KsefError, RateLimitExceededError, UnsupportedResponseError + +_CAMELCASE_TO_UNDERSCORE_RE = re.compile("((?<=[a-z0-9])[A-Z]|(?!^)[A-Z](?=[a-z]))") +_HTTP_STATUS_RANGE_START = 200 +_HTTP_STATUS_RANGE_END = 299 + + +def camelcase_to_words(value: str) -> str: + """ + Convert a CamelCase string to a readable "Camel case" string. + + Remove the camel case, capitalize the first letter. + + :param value: Value to convert + """ + new_value = _CAMELCASE_TO_UNDERSCORE_RE.sub(r" \1", value).lower() + return new_value[0].upper() + new_value[1:] + + +def response_to_exception(response: Response) -> Optional[KsefError]: + """Convert a requests.Response object to a KsefError exception instance.""" + if _HTTP_STATUS_RANGE_START <= response.status_code <= _HTTP_STATUS_RANGE_END: + return None + + if response.status_code == HTTPStatus.TOO_MANY_REQUESTS: + return RateLimitExceededError(response=response) + + return UnsupportedResponseError(response=response) diff --git a/tests/auth/test_token.py b/tests/auth/test_token.py index c580d18..1abf498 100644 --- a/tests/auth/test_token.py +++ b/tests/auth/test_token.py @@ -16,7 +16,7 @@ def test_enrich() -> None: request = auth.modify_request(request) - assert request.headers["Authorization"] == "abc123" + assert request.headers["SessionToken"] == "abc123" def test_get_authorization_challenge(mocked_responses: RequestsMock) -> None: diff --git a/tests/test_utils.py b/tests/test_utils.py new file mode 100644 index 0000000..b5105f7 --- /dev/null +++ b/tests/test_utils.py @@ -0,0 +1,16 @@ +"""Test the utilities module.""" +import pytest + +from ksef.utils import camelcase_to_words + + +@pytest.mark.parametrize( + ("value", "expected_value"), + [ + ("Test", "Test"), + ("TestTest", "Test test"), + ], +) +def test_camelcase_to_words(value: str, expected_value: str) -> None: + """Test the camelcase_to_words function.""" + assert camelcase_to_words(value) == expected_value From 72114f061232de3253dd9fa04d75ed4471e810b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Szafra=C5=84ski?= Date: Mon, 22 Jan 2024 13:37:55 +0100 Subject: [PATCH 10/13] feat: Base types for models --- src/ksef/compat.py | 12 ++++ src/ksef/models/invoice.py | 98 +++++++++++++++++++++++++- src/ksef/models/invoice_annotations.py | 89 +++++++++++++++++++++++ src/ksef/models/invoice_rows.py | 20 ++++++ 4 files changed, 218 insertions(+), 1 deletion(-) create mode 100644 src/ksef/compat.py create mode 100644 src/ksef/models/invoice_annotations.py create mode 100644 src/ksef/models/invoice_rows.py diff --git a/src/ksef/compat.py b/src/ksef/compat.py new file mode 100644 index 0000000..d653747 --- /dev/null +++ b/src/ksef/compat.py @@ -0,0 +1,12 @@ +"""Compatibility libraries for python 3.x.""" + +try: + from enum import StrEnum # type: ignore[attr-defined] +except ImportError: + from enum import Enum + + class StrEnum(str, Enum): # type: ignore[no-redef] + """Compatibility class for StrEnum for older python versions.""" + + +__all__ = ["StrEnum"] diff --git a/src/ksef/models/invoice.py b/src/ksef/models/invoice.py index fe6d15b..bc85ccd 100644 --- a/src/ksef/models/invoice.py +++ b/src/ksef/models/invoice.py @@ -1,6 +1,102 @@ """Invoice model.""" +from datetime import date +from decimal import Decimal +from typing import Optional + from pydantic import BaseModel +from ksef.compat import StrEnum +from ksef.models.invoice_annotations import InvoiceAnnotations +from ksef.models.invoice_rows import InvoiceRows + + +class IdentificationData(BaseModel): + """ + Subject identification data. + + Corresponds to the field TPodmiot1/TPodmiot2 from the invoice XML schema. + """ + + nip: str + full_name: str + + +class Address(BaseModel): + """Subject address data. + + Corresponds to the type TAdres from the invoice XML schema. + """ + + country_code: str + city: str + street: str + house_number: str + apartment_number: Optional[str] + postal_code: str + + +class Subject(BaseModel): + """ + A subject of the invoice (issuer or recipient). + + Corresponds to the field TPodmiot1/TPodmiot2 from the invoice XML schema. + """ + + identification_data: IdentificationData + email: str + phone: str + + +class InvoiceType(StrEnum): + """ + Type of the invoice. + + Corresponds to the field TRodzajFaktury from the invoice XML schema. + """ + + # Regularna faktura VAT + REGULAR_VAT = "VAT" + + # Faktura korekcyjna + CORRECTION = "KOR" + + # Faktura zaliczkowa + ADVANCE = "ZAL" + + # Faktura rozliczeniowa + SETTLEMENT = "ROZ" + + # Faktura uproszczona + SIMPLIFIED = "UPR" + + # Faktura korygująca fakturę zaliczkową + CORRECTION_ADVANCE = "KOR_ZAL" + + # Faktura korygująca fakturę rozliczeniową + CORRECTION_SETTLEMENT = "KOR_ROZ" + + +class InvoiceData(BaseModel): + """Invoice data. + + Corresponds to the field Fa from the invoice XML schema. + """ + + currency_code: str + issue_date: date + issue_number: str + sell_date: date + total_amount: Decimal + invoice_annotations: InvoiceAnnotations + invoice_type: InvoiceType + invoice_rows: InvoiceRows + class Invoice(BaseModel): - """Single invoice model.""" + """Single invoice model. + + Corresponds to the root field Faktura from the invoice XML schema. + """ + + issuer: Subject + recipient: Subject diff --git a/src/ksef/models/invoice_annotations.py b/src/ksef/models/invoice_annotations.py new file mode 100644 index 0000000..462afce --- /dev/null +++ b/src/ksef/models/invoice_annotations.py @@ -0,0 +1,89 @@ +"""Models for invoice annotations/metadata.""" + +from pydantic import BaseModel + +from ksef.compat import StrEnum + + +class ReverseCharge(StrEnum): + """Possible values for the reverse charge field.""" + + YES = "1" + NO = "2" + + +class TaxSettlementOnPayment(StrEnum): + """Possible values for the tax settlement on payment field.""" + + ON_PAYMENT = "1" + REGULAR = "2" + + +class SelfInvoicing(StrEnum): + """Possible values for the self invoicing field.""" + + YES = "1" + NO = "2" + + +class SplitPayment(StrEnum): + """Possible values for the split payment field.""" + + YES = "1" + NO = "2" + + +class FreeFromVat(StrEnum): + """Possible values for the free from vat tax field.""" + + YES = "1" + NO = "2" + + +class IntraCommunitySupplyOfNewTransportMethods(StrEnum): + """Possible values for the intra community supply of new transport methods field.""" + + YES = "1" + NO = "2" + + +class SimplifiedProcedureBySecondTaxPayer(StrEnum): + """Possible values of the simplified procedure by second tax payer field.""" + + YES = "1" + NO = "2" + + +class MarginProcedure(StrEnum): + """Possible values for the margin procedure field.""" + + YES = "1" + NO = "2" + + +class InvoiceAnnotations(BaseModel): + """Invoice annotations/metadata.""" + + # P_16, Metoda kasowa + tax_settlement_on_payment: TaxSettlementOnPayment + + # P_17, Samofakturowanie + self_invoice: SelfInvoicing + + # P_18, Odwrotne obciążenie + reverse_charge: ReverseCharge + + # P_18A, Mechanizm podzielonej płatności + split_payment: SplitPayment + + # P_19, Zwolnienie z VAT + free_from_vat: FreeFromVat + + # P_22, Wewnątrzwspólnotowa dostawa nowych środków transportu + intra_community_supply_of_new_transport_methods: IntraCommunitySupplyOfNewTransportMethods + + # P_23, faktura wystawiona uproszczoną procedurą przez drugiego w kolejności podatnika + simplified_procedure_by_second_tax_payer: SimplifiedProcedureBySecondTaxPayer + + # P_PMarzy, znacznik wystąpienia procedur marży + margin_procedure: MarginProcedure diff --git a/src/ksef/models/invoice_rows.py b/src/ksef/models/invoice_rows.py new file mode 100644 index 0000000..92a75fa --- /dev/null +++ b/src/ksef/models/invoice_rows.py @@ -0,0 +1,20 @@ +"""Models for individual invoice rows/positions.""" + +from typing import Sequence + +from pydantic import BaseModel + + +class InvoiceRow(BaseModel): + """Single individual invoice position.""" + + row_number: int # NrWierszaFa + name: str # P_7, nazwa (rodzaj) towaru lub usługi + tax: int # P_12, stawka podatku + + +class InvoiceRows(BaseModel): + """Group of invoice positions.""" + + rows_count: int + rows: Sequence[InvoiceRow] From 63c7f5568ce98f646681b9358727bc5a70813ee3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jan 2024 12:41:04 +0000 Subject: [PATCH 11/13] build(deps): bump types-urllib3 from 1.26.25.8 to 1.26.25.13 (#14) Bumps [types-urllib3](https://github.com/python/typeshed) from 1.26.25.8 to 1.26.25.13.
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=types-urllib3&package-manager=pip&previous-version=1.26.25.8&new-version=1.26.25.13)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index 2f7bf13..a2a8610 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1601,7 +1601,8 @@ files = [ {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win32.whl", hash = "sha256:763d65baa3b952479c4e972669f679fe490eee058d5aa85da483ebae2009d231"}, {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:d000f258cf42fec2b1bbf2863c61d7b8918d31ffee905da62dede869254d3b8a"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:045e0626baf1c52e5527bd5db361bc83180faaba2ff586e763d3d5982a876a9e"}, - {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_12_6_arm64.whl", hash = "sha256:721bc4ba4525f53f6a611ec0967bdcee61b31df5a56801281027a3a6d1c2daf5"}, + {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:1a6391a7cabb7641c32517539ca42cf84b87b667bad38b78d4d42dd23e957c81"}, + {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:9c7617df90c1365638916b98cdd9be833d31d337dbcd722485597b43c4a215bf"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:41d0f1fa4c6830176eef5b276af04c89320ea616655d01327d5ce65e50575c94"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-win32.whl", hash = "sha256:f6d3d39611ac2e4f62c3128a9eed45f19a6608670c5a2f4f07f24e8de3441d38"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-win_amd64.whl", hash = "sha256:da538167284de58a52109a9b89b8f6a53ff8437dd6dc26d33b57bf6699153122"}, @@ -1852,13 +1853,13 @@ types-urllib3 = "<1.27" [[package]] name = "types-urllib3" -version = "1.26.25.8" +version = "1.26.25.13" description = "Typing stubs for urllib3" optional = false python-versions = "*" files = [ - {file = "types-urllib3-1.26.25.8.tar.gz", hash = "sha256:ecf43c42d8ee439d732a1110b4901e9017a79a38daca26f08e42c8460069392c"}, - {file = "types_urllib3-1.26.25.8-py3-none-any.whl", hash = "sha256:95ea847fbf0bf675f50c8ae19a665baedcf07e6b4641662c4c3c72e7b2edf1a9"}, + {file = "types-urllib3-1.26.25.13.tar.gz", hash = "sha256:3300538c9dc11dad32eae4827ac313f5d986b8b21494801f1bf97a1ac6c03ae5"}, + {file = "types_urllib3-1.26.25.13-py3-none-any.whl", hash = "sha256:5dbd1d2bef14efee43f5318b5d36d805a489f6600252bb53626d4bfafd95e27c"}, ] [[package]] From 2966b402cb52f2227d2afb33a816130a2ca68e12 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jan 2024 14:20:31 +0000 Subject: [PATCH 12/13] build(deps): bump filelock from 3.10.0 to 3.12.0 (#12) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [filelock](https://github.com/tox-dev/py-filelock) from 3.10.0 to 3.12.0.
Release notes

Sourced from filelock's releases.

3.12.0

What's Changed

Full Changelog: https://github.com/tox-dev/py-filelock/compare/3.11.0...3.12.0

3.11.0

What's Changed

New Contributors

Full Changelog: https://github.com/tox-dev/py-filelock/compare/3.10.7...3.11.0

3.10.7

What's Changed

New Contributors

Full Changelog: https://github.com/tox-dev/py-filelock/compare/3.10.6...3.10.7

3.10.6

What's Changed

Full Changelog: https://github.com/tox-dev/py-filelock/compare/3.10.5...3.10.6

3.10.5

What's Changed

Full Changelog: https://github.com/tox-dev/py-filelock/compare/3.10.4...3.10.5

3.10.4

What's Changed

... (truncated)

Changelog

Sourced from filelock's changelog.

v3.12.0 (2023-04-18)

  • Make the thread local behaviour something the caller can enable/disable via a flag during the lock creation, it's on by default.
  • Better error handling on Windows.

v3.11.0 (2023-04-06)

  • Make the lock thread local.

v3.10.7 (2023-03-27)

  • Use fchmod instead of chmod to work around bug in PyPy via Anaconda.

v3.10.6 (2023-03-25)

  • Enhance the robustness of the try/catch block in _soft.py. by :user:jahrules.

v3.10.5 (2023-03-25)

  • Add explicit error check as certain UNIX filesystems do not support flock. by :user:jahrules.

v3.10.4 (2023-03-24)

  • Update os.open to preserve mode= for certain edge cases. by :user:jahrules.

v3.10.3 (2023-03-23)

  • Fix permission issue - by :user:jahrules.

v3.10.2 (2023-03-22)

  • Bug fix for using filelock with threaded programs causing undesired file permissions - by :user:jahrules.

v3.10.1 (2023-03-22)

  • Handle pickle for :class:filelock.Timeout :pr:203 - by :user:TheMatt2.
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=filelock&package-manager=pip&previous-version=3.10.0&new-version=3.12.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index a2a8610..165eed3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -521,18 +521,18 @@ testing = ["pre-commit"] [[package]] name = "filelock" -version = "3.10.0" +version = "3.12.0" description = "A platform independent file lock." optional = false python-versions = ">=3.7" files = [ - {file = "filelock-3.10.0-py3-none-any.whl", hash = "sha256:e90b34656470756edf8b19656785c5fea73afa1953f3e1b0d645cef11cab3182"}, - {file = "filelock-3.10.0.tar.gz", hash = "sha256:3199fd0d3faea8b911be52b663dfccceb84c95949dd13179aa21436d1a79c4ce"}, + {file = "filelock-3.12.0-py3-none-any.whl", hash = "sha256:ad98852315c2ab702aeb628412cbf7e95b7ce8c3bf9565670b4eaecf1db370a9"}, + {file = "filelock-3.12.0.tar.gz", hash = "sha256:fc03ae43288c013d2ea83c8597001b1129db351aad9c57fe2409327916b8e718"}, ] [package.extras] -docs = ["furo (>=2022.12.7)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.22,!=1.23.4)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.2.1)", "pytest (>=7.2.2)", "pytest-cov (>=4)", "pytest-timeout (>=2.1)"] +docs = ["furo (>=2023.3.27)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.2.3)", "diff-cover (>=7.5)", "pytest (>=7.3.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)"] [[package]] name = "ghp-import" From 164ea5b8a742581cf755ab0280d22059ce081e13 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jan 2024 15:33:32 +0100 Subject: [PATCH 13/13] build(deps-dev): bump dparse from 0.6.2 to 0.6.3 (#23) Bumps [dparse](https://github.com/pyupio/dparse) from 0.6.2 to 0.6.3.
Changelog

Sourced from dparse's changelog.

0.6.3 (2023-06-26)

Commits
  • eb917b3 Release 0.6.3
  • 47b82ba Merge pull request #63 from pyupio/fix/pinning-ci-images
  • 802baaa Drop Python 3.5 support.
  • bf0c82f Remove Python 3.5 from CI tests; we are close to removing it in subsequent re...
  • 5162932 Removed old test patch.
  • 0a50261 Pinning CI image.
  • 56073fd Merge pull request #62 from mgorny/tomllib
  • 31a1d5b Use the modern tomli/tomllib to parse TOML files
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dparse&package-manager=pip&previous-version=0.6.2&new-version=0.6.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/poetry.lock b/poetry.lock index 165eed3..0c0827a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -474,22 +474,22 @@ files = [ [[package]] name = "dparse" -version = "0.6.2" +version = "0.6.3" description = "A parser for Python dependency files" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" files = [ - {file = "dparse-0.6.2-py3-none-any.whl", hash = "sha256:8097076f1dd26c377f30d4745e6ec18fef42f3bf493933b842ac5bafad8c345f"}, - {file = "dparse-0.6.2.tar.gz", hash = "sha256:d45255bda21f998bc7ddf2afd5e62505ba6134756ba2d42a84c56b0826614dfe"}, + {file = "dparse-0.6.3-py3-none-any.whl", hash = "sha256:0d8fe18714056ca632d98b24fbfc4e9791d4e47065285ab486182288813a5318"}, + {file = "dparse-0.6.3.tar.gz", hash = "sha256:27bb8b4bcaefec3997697ba3f6e06b2447200ba273c0b085c3d012a04571b528"}, ] [package.dependencies] packaging = "*" -toml = "*" +tomli = {version = "*", markers = "python_version < \"3.11\""} [package.extras] conda = ["pyyaml"] -pipenv = ["pipenv"] +pipenv = ["pipenv (<=2022.12.19)"] [[package]] name = "exceptiongroup" @@ -1758,17 +1758,6 @@ files = [ {file = "text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"}, ] -[[package]] -name = "toml" -version = "0.10.2" -description = "Python Library for Tom's Obvious, Minimal Language" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, - {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, -] - [[package]] name = "tomli" version = "2.0.1"