efoli 0.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. efoli-0.0.1/.github/dependabot.yml +18 -0
  2. efoli-0.0.1/.github/workflows/codeql-analysis.yml +70 -0
  3. efoli-0.0.1/.github/workflows/coverage.yml +26 -0
  4. efoli-0.0.1/.github/workflows/dependabot_automerge.yml +18 -0
  5. efoli-0.0.1/.github/workflows/dev_test.yml +28 -0
  6. efoli-0.0.1/.github/workflows/formatting.yml +27 -0
  7. efoli-0.0.1/.github/workflows/no_byte_order_mark.yml +15 -0
  8. efoli-0.0.1/.github/workflows/packaging_test.yml +26 -0
  9. efoli-0.0.1/.github/workflows/python-publish.yml +61 -0
  10. efoli-0.0.1/.github/workflows/pythonlint.yml +28 -0
  11. efoli-0.0.1/.github/workflows/unittests.yml +26 -0
  12. efoli-0.0.1/.gitignore +136 -0
  13. efoli-0.0.1/.pre-commit-config.yaml +24 -0
  14. efoli-0.0.1/PKG-INFO +59 -0
  15. efoli-0.0.1/README.md +38 -0
  16. efoli-0.0.1/dev_requirements/requirements-coverage.in +2 -0
  17. efoli-0.0.1/dev_requirements/requirements-coverage.txt +9 -0
  18. efoli-0.0.1/dev_requirements/requirements-formatting.in +3 -0
  19. efoli-0.0.1/dev_requirements/requirements-formatting.txt +21 -0
  20. efoli-0.0.1/dev_requirements/requirements-linting.in +2 -0
  21. efoli-0.0.1/dev_requirements/requirements-linting.txt +21 -0
  22. efoli-0.0.1/dev_requirements/requirements-packaging.in +3 -0
  23. efoli-0.0.1/dev_requirements/requirements-packaging.txt +72 -0
  24. efoli-0.0.1/dev_requirements/requirements-spell_check.in +1 -0
  25. efoli-0.0.1/dev_requirements/requirements-spell_check.txt +9 -0
  26. efoli-0.0.1/dev_requirements/requirements-tests.in +2 -0
  27. efoli-0.0.1/dev_requirements/requirements-tests.txt +15 -0
  28. efoli-0.0.1/dev_requirements/requirements-type_check.in +2 -0
  29. efoli-0.0.1/dev_requirements/requirements-type_check.txt +13 -0
  30. efoli-0.0.1/domain-specific-terms.txt +2 -0
  31. efoli-0.0.1/pyproject.toml +65 -0
  32. efoli-0.0.1/requirements.txt +6 -0
  33. efoli-0.0.1/src/_efoli_version.py +1 -0
  34. efoli-0.0.1/src/efoli/__init__.py +14 -0
  35. efoli-0.0.1/src/efoli/edifact_format.py +78 -0
  36. efoli-0.0.1/src/efoli/edifact_format_version.py +61 -0
  37. efoli-0.0.1/src/efoli/py.typed +2 -0
  38. efoli-0.0.1/tox.ini +95 -0
@@ -0,0 +1,18 @@
1
+ # To get started with Dependabot version updates, you'll need to specify which
2
+ # package ecosystems to update and where the package manifests are located.
3
+ # Please see the documentation for all configuration options:
4
+ # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5
+
6
+ version: 2
7
+ updates:
8
+ - package-ecosystem: "pip" # See documentation for possible values
9
+ directory: "/" # Location of package manifests
10
+ schedule:
11
+ interval: "weekly"
12
+ reviewers:
13
+ - "@Hochfrequenz/python-developers-review-team"
14
+ # Maintain dependencies for GitHub Actions
15
+ - package-ecosystem: "github-actions"
16
+ directory: "/"
17
+ schedule:
18
+ interval: "weekly"
@@ -0,0 +1,70 @@
1
+ # For most projects, this workflow file will not need changing; you simply need
2
+ # to commit it to your repository.
3
+ #
4
+ # You may wish to alter this file to override the set of languages analyzed,
5
+ # or to provide custom queries or build logic.
6
+ #
7
+ # ******** NOTE ********
8
+ # We have attempted to detect the languages in your repository. Please check
9
+ # the `language` matrix defined below to confirm you have the correct set of
10
+ # supported CodeQL languages.
11
+ #
12
+ name: "CodeQL"
13
+
14
+ on:
15
+ push:
16
+ branches: [main]
17
+ pull_request:
18
+ # The branches below must be a subset of the branches above
19
+ branches: [main]
20
+ schedule:
21
+ - cron: "29 14 * * 6"
22
+
23
+ jobs:
24
+ analyze:
25
+ name: Analyze
26
+ runs-on: ubuntu-latest
27
+ permissions:
28
+ actions: read
29
+ contents: read
30
+ security-events: write
31
+
32
+ strategy:
33
+ fail-fast: false
34
+ matrix:
35
+ language: ["python"]
36
+ # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
37
+ # Learn more about CodeQL language support at https://git.io/codeql-language-support
38
+
39
+ steps:
40
+ - name: Checkout repository
41
+ uses: actions/checkout@v4
42
+
43
+ # Initializes the CodeQL tools for scanning.
44
+ - name: Initialize CodeQL
45
+ uses: github/codeql-action/init@v3
46
+ with:
47
+ languages: ${{ matrix.language }}
48
+ # If you wish to specify custom queries, you can do so here or in a config file.
49
+ # By default, queries listed here will override any specified in a config file.
50
+ # Prefix the list here with "+" to use these queries and those in the config file.
51
+ # queries: ./path/to/local/query, your-org/your-repo/queries@main
52
+
53
+ # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
54
+ # If this step fails, then you should remove it and run the build manually (see below)
55
+ - name: Autobuild
56
+ uses: github/codeql-action/autobuild@v3
57
+
58
+ # ℹ️ Command-line programs to run using the OS shell.
59
+ # 📚 https://git.io/JvXDl
60
+
61
+ # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
62
+ # and modify them (or add more) to build your code if your project
63
+ # uses a compiled language
64
+
65
+ #- run: |
66
+ # make bootstrap
67
+ # make release
68
+
69
+ - name: Perform CodeQL Analysis
70
+ uses: github/codeql-action/analyze@v3
@@ -0,0 +1,26 @@
1
+ name: "Coverage"
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request: {}
7
+ jobs:
8
+ coverage:
9
+ runs-on: ${{ matrix.os }}
10
+ strategy:
11
+ matrix:
12
+ python-version: ["3.12"]
13
+ os: [ubuntu-latest]
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ - name: Set up Python ${{ matrix.python-version }}
17
+ uses: actions/setup-python@v5
18
+ with:
19
+ python-version: ${{ matrix.python-version }}
20
+ - name: Install dependencies
21
+ run: |
22
+ python -m pip install --upgrade pip
23
+ pip install tox
24
+ - name: Run Tests and Record Coverage
25
+ run: |
26
+ tox -e coverage
@@ -0,0 +1,18 @@
1
+ name: Dependabot auto-approve / -merge
2
+ on: pull_request
3
+
4
+ jobs:
5
+ dependabot:
6
+ permissions:
7
+ contents: write
8
+ pull-requests: write
9
+ runs-on: ubuntu-latest
10
+ env:
11
+ PR_URL: ${{github.event.pull_request.html_url}}
12
+ GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
13
+ if: ${{ github.actor == 'dependabot[bot]' }}
14
+ steps:
15
+ - name: Approve a PR
16
+ run: gh pr review --approve "$PR_URL"
17
+ - name: Enable auto-merge for Dependabot PRs
18
+ run: gh pr merge --auto --squash "$PR_URL"
@@ -0,0 +1,28 @@
1
+ name: "Test Dev Environment"
2
+ # Checks that the dev environment (tox -e dev) can be set up.
3
+ # This might not work, if different linting/testing envs refer to different versions of the same lib (e.g. typing-extensions).
4
+ # Different versions of the same package might work for isolated specific envs (only linting, only testing...) but the dev environment inherits from all of them.
5
+ on:
6
+ push:
7
+ branches: [main]
8
+ pull_request: {}
9
+ jobs:
10
+ check:
11
+ runs-on: ${{ matrix.os }}
12
+ strategy:
13
+ matrix:
14
+ python-version: ["3.11", "3.12"]
15
+ os: [ubuntu-latest]
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+ - name: Set up Python ${{ matrix.python-version }}
19
+ uses: actions/setup-python@v5
20
+ with:
21
+ python-version: ${{ matrix.python-version }}
22
+ - name: Install Dependencies
23
+ run: |
24
+ python -m pip install --upgrade pip
25
+ pip install tox
26
+ - name: Create a Dev Environment
27
+ run: |
28
+ tox -e dev
@@ -0,0 +1,27 @@
1
+ name: "Formatting"
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request: {}
7
+ jobs:
8
+ black:
9
+ runs-on: ${{ matrix.os }}
10
+ strategy:
11
+ matrix:
12
+ python-version: ["3.12"]
13
+ os: [ubuntu-latest]
14
+ tool: ["black", "isort"]
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - name: Set up Python ${{ matrix.python-version }}
18
+ uses: actions/setup-python@v5
19
+ with:
20
+ python-version: ${{ matrix.python-version }}
21
+ - name: Install dependencies
22
+ run: |
23
+ python -m pip install --upgrade pip
24
+ pip install -r dev_requirements/requirements-formatting.txt
25
+ - name: ${{ matrix.tool }} Code Formatter
26
+ run: |
27
+ ${{ matrix.tool }} . --check
@@ -0,0 +1,15 @@
1
+ name: Prevent ByteOrderMarks
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ pull_request: {}
8
+
9
+ jobs:
10
+ bom-check:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+ - uses: arma-actions/bom-check@v1
15
+ name: Check for BOM
@@ -0,0 +1,26 @@
1
+ name: "Packaging Test"
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request: {}
7
+ jobs:
8
+ check_packaging:
9
+ runs-on: ${{ matrix.os }}
10
+ strategy:
11
+ matrix:
12
+ python-version: ["3.12"]
13
+ os: [ubuntu-latest]
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ - name: Set up Python ${{ matrix.python-version }}
17
+ uses: actions/setup-python@v5
18
+ with:
19
+ python-version: ${{ matrix.python-version }}
20
+ - name: Install dependencies
21
+ run: |
22
+ python -m pip install --upgrade pip
23
+ pip install tox
24
+ - name: Run Packaging Test
25
+ run: |
26
+ tox -e test_packaging
@@ -0,0 +1,61 @@
1
+ # This GitHub workflow is only needed for python package releases which are supposed to be published on pypi.
2
+ # It requires the Github "environments" feature (see instructions below) it might not be available for private free accounts (but works for public or organization repos).
3
+ # After creating the "release" environment in the Github repo settings, you need to enter your Github organization/user name + repo name + "python-publish.yml" workflow file name in the PyPI UI to make this work.
4
+
5
+ # This workflow uploads a Python Package using Twine when a release is created.
6
+ # For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries
7
+
8
+ name: Upload Python Package
9
+
10
+ on:
11
+ release:
12
+ types: [ created, edited ]
13
+
14
+ jobs:
15
+ tests:
16
+ if: startsWith(github.ref, 'refs/tags/v')
17
+ runs-on: ${{ matrix.os }}
18
+ strategy:
19
+ matrix:
20
+ python-version: [ "3.12" ]
21
+ os: [ ubuntu-latest ]
22
+ steps:
23
+ - uses: actions/checkout@v4
24
+ - name: Set up Python ${{ matrix.python-version }}
25
+ uses: actions/setup-python@v5
26
+ with:
27
+ python-version: ${{ matrix.python-version }}
28
+ - name: Install tox
29
+ run: |
30
+ python -m pip install --upgrade pip
31
+ pip install tox
32
+ - name: Run tox
33
+ run: |
34
+ tox
35
+
36
+ build-n-publish:
37
+ name: Build and publish Python 🐍 distributions 📦 to PyPI and TestPyPI
38
+ runs-on: ubuntu-latest
39
+ # Specifying a GitHub environment, # Specifying a GitHub environment, which is strongly recommended by PyPI: https://docs.pypi.org/trusted-publishers/adding-a-publisher/
40
+ # you have to create an environment in your repository settings and add the environment name here
41
+ environment: release
42
+ permissions:
43
+ # IMPORTANT: this permission is mandatory for trusted publishing
44
+ id-token: write
45
+ needs: tests
46
+ steps:
47
+ - uses: actions/checkout@v4
48
+ - name: Set up Python
49
+ uses: actions/setup-python@v5
50
+ with:
51
+ python-version: ${{ matrix.python-version }}
52
+ - name: Install dependencies
53
+ run: |
54
+ python -m pip install --upgrade pip
55
+ pip install -r dev_requirements/requirements-packaging.txt
56
+ - name: Build wheel and source distributions
57
+ run: |
58
+ python -m build
59
+ - name: Publish distribution 📦 to PyPI
60
+ if: startsWith(github.ref, 'refs/tags/v')
61
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,28 @@
1
+ name: "Linting"
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request: {}
7
+ jobs:
8
+ pylint:
9
+ name: Python Code Quality and Lint
10
+ runs-on: ${{ matrix.os }}
11
+ strategy:
12
+ matrix:
13
+ python-version: ["3.12"]
14
+ os: [ubuntu-latest]
15
+ linter-env: ["linting", "type_check", "spell_check"]
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+ - name: Set up Python ${{ matrix.python-version }}
19
+ uses: actions/setup-python@v5
20
+ with:
21
+ python-version: ${{ matrix.python-version }}
22
+ - name: Install Dependencies
23
+ run: |
24
+ python -m pip install --upgrade pip
25
+ pip install tox
26
+ - name: Run ${{ matrix.linter-env }} via Tox
27
+ run: |
28
+ tox -e ${{ matrix.linter-env }}
@@ -0,0 +1,26 @@
1
+ name: "Unittests"
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request: {}
7
+ jobs:
8
+ pytest:
9
+ runs-on: ${{ matrix.os }}
10
+ strategy:
11
+ matrix:
12
+ python-version: ["3.11", "3.12"]
13
+ os: [ubuntu-latest]
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ - name: Set up Python ${{ matrix.python-version }}
17
+ uses: actions/setup-python@v5
18
+ with:
19
+ python-version: ${{ matrix.python-version }}
20
+ - name: Install Dependencies
21
+ run: |
22
+ python -m pip install --upgrade pip
23
+ pip install tox
24
+ - name: Run the Unit Tests via Tox
25
+ run: |
26
+ tox -e tests
efoli-0.0.1/.gitignore ADDED
@@ -0,0 +1,136 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ pip-wheel-metadata/
24
+ share/python-wheels/
25
+ *.egg-info/
26
+ .installed.cfg
27
+ *.egg
28
+ MANIFEST
29
+
30
+ # PyInstaller
31
+ # Usually these files are written by a python script from a template
32
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
33
+ *.manifest
34
+ *.spec
35
+
36
+ # Installer logs
37
+ pip-log.txt
38
+ pip-delete-this-directory.txt
39
+
40
+ # Unit test / coverage reports
41
+ htmlcov/
42
+ .tox/
43
+ .nox/
44
+ .coverage
45
+ .coverage.*
46
+ .cache
47
+ nosetests.xml
48
+ coverage.xml
49
+ *.cover
50
+ *.py,cover
51
+ .hypothesis/
52
+ .pytest_cache/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ target/
76
+
77
+ # Jupyter Notebook
78
+ .ipynb_checkpoints
79
+
80
+ # IPython
81
+ profile_default/
82
+ ipython_config.py
83
+
84
+ # pyenv
85
+ .python-version
86
+
87
+ # pipenv
88
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
90
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
91
+ # install all needed dependencies.
92
+ #Pipfile.lock
93
+
94
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow
95
+ __pypackages__/
96
+
97
+ # Celery stuff
98
+ celerybeat-schedule
99
+ celerybeat.pid
100
+
101
+ # SageMath parsed files
102
+ *.sage.py
103
+
104
+ # Environments
105
+ .env
106
+ .venv
107
+ env/
108
+ venv/
109
+ ENV/
110
+ env.bak/
111
+ venv.bak/
112
+
113
+ # Spyder project settings
114
+ .spyderproject
115
+ .spyproject
116
+
117
+ # Rope project settings
118
+ .ropeproject
119
+
120
+ # mkdocs documentation
121
+ /site
122
+
123
+ # mypy
124
+ .mypy_cache/
125
+ .dmypy.json
126
+ dmypy.json
127
+
128
+ # Pyre type checker
129
+ .pyre/
130
+
131
+ .idea/
132
+
133
+ # vscode settings
134
+ .vscode/
135
+
136
+ src/_your_package_version.py
@@ -0,0 +1,24 @@
1
+ # to update all repo revisions just run: pre-commit autoupdate
2
+ repos:
3
+ - repo: https://github.com/pre-commit/pre-commit-hooks
4
+ rev: v4.4.0
5
+ hooks:
6
+ - id: check-yaml
7
+ - id: end-of-file-fixer
8
+ - id: trailing-whitespace
9
+ - repo: https://github.com/psf/black
10
+ rev: 23.9.1
11
+ hooks:
12
+ - id: black
13
+ language_version: python3
14
+ - repo: https://github.com/pycqa/isort
15
+ rev: 5.12.0
16
+ hooks:
17
+ - id: isort
18
+ name: isort (python)
19
+ - id: isort
20
+ name: isort (cython)
21
+ types: [cython]
22
+ - id: isort
23
+ name: isort (pyi)
24
+ types: [pyi]
efoli-0.0.1/PKG-INFO ADDED
@@ -0,0 +1,59 @@
1
+ Metadata-Version: 2.3
2
+ Name: efoli
3
+ Version: 0.0.1
4
+ Summary: Enums and related helper functions that model EDIFACT relevant data for German utilities
5
+ Project-URL: Changelog, https://github.com/Hochfrequenz/efoli/releases
6
+ Project-URL: Homepage, https://github.com/Hochfrequenz/efoli
7
+ Author-email: Hochfrequenz Unternehmensberatung GmbH <info+github@hochfrequenz.de>
8
+ License: MIT
9
+ Keywords: bdew,edifact,enums
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Environment :: Console
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python
16
+ Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Requires-Python: >=3.11
20
+ Description-Content-Type: text/markdown
21
+
22
+ # E-Foli
23
+
24
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
25
+ ![Python Versions (officially) supported](https://img.shields.io/pypi/pyversions/efoli.svg)
26
+ ![Pypi status badge](https://img.shields.io/pypi/v/efoli)
27
+ ![Unittests status badge](https://github.com/Hochfrequenz/efoli/workflows/Unittests/badge.svg)
28
+ ![Coverage status badge](https://github.com/Hochfrequenz/efoli/workflows/Coverage/badge.svg)
29
+ ![Linting status badge](https://github.com/Hochfrequenz/efoli/workflows/Linting/badge.svg)
30
+ ![Black status badge](https://github.com/Hochfrequenz/efoli/workflows/Formatting/badge.svg)
31
+
32
+ `efoli` is a Python package, that contains
33
+ - an Enum `EdifactFormat` that models EDIFACT formats used by German utilities like, e.g.
34
+ - `UTILMD`
35
+ - `MSCONS`
36
+ - `INVOIC`
37
+ - …
38
+ - an Enum `EdifactFormatVersion` that models validity periods of different message versions, e.g.
39
+ - `FV2310` is valid from 2023-10-01 onwards
40
+ - `FV2404` is valid from 2024-04-03 onwards
41
+ - …
42
+ - helper methods that allow
43
+ - to derive the `EdifactFormat` from a given _Prüfidentifikator_ (e.g. `55001`➡`UTILMD`)
44
+ - that derive the `EdifactFormatVersion` from a given date(time) (e.g. `2024-01-01`➡`FV2310`)
45
+
46
+ It's not much, but we need it at many places.
47
+ This is why we need a central place to define these formats and versions.
48
+
49
+ ## Installation
50
+ ```bash
51
+ pip install efoli
52
+ ```
53
+
54
+ ## Setup for Local Development
55
+ Follow the instructions from our [template repository](https://github.com/Hochfrequenz/python_template_repository?tab=readme-ov-file#how-to-use-this-repository-on-your-machine).
56
+ tl;dr: `tox`.
57
+
58
+ ## Contribute
59
+ You are very welcome to contribute to this template repository by opening a pull request against the main branch.
efoli-0.0.1/README.md ADDED
@@ -0,0 +1,38 @@
1
+ # E-Foli
2
+
3
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
4
+ ![Python Versions (officially) supported](https://img.shields.io/pypi/pyversions/efoli.svg)
5
+ ![Pypi status badge](https://img.shields.io/pypi/v/efoli)
6
+ ![Unittests status badge](https://github.com/Hochfrequenz/efoli/workflows/Unittests/badge.svg)
7
+ ![Coverage status badge](https://github.com/Hochfrequenz/efoli/workflows/Coverage/badge.svg)
8
+ ![Linting status badge](https://github.com/Hochfrequenz/efoli/workflows/Linting/badge.svg)
9
+ ![Black status badge](https://github.com/Hochfrequenz/efoli/workflows/Formatting/badge.svg)
10
+
11
+ `efoli` is a Python package, that contains
12
+ - an Enum `EdifactFormat` that models EDIFACT formats used by German utilities like, e.g.
13
+ - `UTILMD`
14
+ - `MSCONS`
15
+ - `INVOIC`
16
+ - …
17
+ - an Enum `EdifactFormatVersion` that models validity periods of different message versions, e.g.
18
+ - `FV2310` is valid from 2023-10-01 onwards
19
+ - `FV2404` is valid from 2024-04-03 onwards
20
+ - …
21
+ - helper methods that allow
22
+ - to derive the `EdifactFormat` from a given _Prüfidentifikator_ (e.g. `55001`➡`UTILMD`)
23
+ - that derive the `EdifactFormatVersion` from a given date(time) (e.g. `2024-01-01`➡`FV2310`)
24
+
25
+ It's not much, but we need it at many places.
26
+ This is why we need a central place to define these formats and versions.
27
+
28
+ ## Installation
29
+ ```bash
30
+ pip install efoli
31
+ ```
32
+
33
+ ## Setup for Local Development
34
+ Follow the instructions from our [template repository](https://github.com/Hochfrequenz/python_template_repository?tab=readme-ov-file#how-to-use-this-repository-on-your-machine).
35
+ tl;dr: `tox`.
36
+
37
+ ## Contribute
38
+ You are very welcome to contribute to this template repository by opening a pull request against the main branch.
@@ -0,0 +1,2 @@
1
+ # specific requirements for the tox coverage env
2
+ coverage
@@ -0,0 +1,9 @@
1
+ # SHA1:6dafbcf610e9f81897b65ee9142715ab2e793f9e
2
+ #
3
+ # This file is autogenerated by pip-compile-multi
4
+ # To update, run:
5
+ #
6
+ # pip-compile-multi
7
+ #
8
+ coverage==7.6.0
9
+ # via -r dev_requirements/requirements-coverage.in
@@ -0,0 +1,3 @@
1
+ # specific requirements for the formatting envs
2
+ black
3
+ isort
@@ -0,0 +1,21 @@
1
+ # SHA1:2c7ffcd29222de3114c7f7994911f1b69d06b6b3
2
+ #
3
+ # This file is autogenerated by pip-compile-multi
4
+ # To update, run:
5
+ #
6
+ # pip-compile-multi
7
+ #
8
+ black==24.4.2
9
+ # via -r dev_requirements/requirements-formatting.in
10
+ click==8.1.7
11
+ # via black
12
+ isort==5.13.2
13
+ # via -r dev_requirements/requirements-formatting.in
14
+ mypy-extensions==1.0.0
15
+ # via black
16
+ packaging==24.0
17
+ # via black
18
+ pathspec==0.12.1
19
+ # via black
20
+ platformdirs==4.2.0
21
+ # via black
@@ -0,0 +1,2 @@
1
+ # specific requirements for the tox linting env
2
+ pylint
@@ -0,0 +1,21 @@
1
+ # SHA1:0e15f8789b9d62fe90d1f1b0b6a7e32f13b99b19
2
+ #
3
+ # This file is autogenerated by pip-compile-multi
4
+ # To update, run:
5
+ #
6
+ # pip-compile-multi
7
+ #
8
+ astroid==3.2.4
9
+ # via pylint
10
+ dill==0.3.8
11
+ # via pylint
12
+ isort==5.13.2
13
+ # via pylint
14
+ mccabe==0.7.0
15
+ # via pylint
16
+ platformdirs==4.2.0
17
+ # via pylint
18
+ pylint==3.2.6
19
+ # via -r dev_requirements/requirements-linting.in
20
+ tomlkit==0.12.4
21
+ # via pylint
@@ -0,0 +1,3 @@
1
+ # requirements for the hatchling build ssystem
2
+ build
3
+ twine
@@ -0,0 +1,72 @@
1
+ #
2
+ # This file is autogenerated by pip-compile with Python 3.12
3
+ # by the following command:
4
+ #
5
+ # pip-compile dev_requirements/requirements-packaging.in
6
+ #
7
+ build==1.2.1
8
+ # via -r requirements-packaging.in
9
+ certifi==2024.7.4
10
+ # via requests
11
+ cffi==1.16.0
12
+ # via cryptography
13
+ charset-normalizer==3.3.2
14
+ # via requests
15
+ cryptography==42.0.5
16
+ # via secretstorage
17
+ docutils==0.20.1
18
+ # via readme-renderer
19
+ idna==3.7
20
+ # via requests
21
+ importlib-metadata==7.0.2
22
+ # via twine
23
+ jaraco-classes==3.3.1
24
+ # via keyring
25
+ jeepney==0.8.0
26
+ # via
27
+ # keyring
28
+ # secretstorage
29
+ keyring==24.3.1
30
+ # via twine
31
+ markdown-it-py==3.0.0
32
+ # via rich
33
+ mdurl==0.1.2
34
+ # via markdown-it-py
35
+ more-itertools==10.2.0
36
+ # via jaraco-classes
37
+ nh3==0.2.15
38
+ # via readme-renderer
39
+ packaging==24.0
40
+ # via build
41
+ pkginfo==1.10.0
42
+ # via twine
43
+ pycparser==2.21
44
+ # via cffi
45
+ pygments==2.17.2
46
+ # via
47
+ # readme-renderer
48
+ # rich
49
+ pyproject-hooks==1.0.0
50
+ # via build
51
+ readme-renderer==43.0
52
+ # via twine
53
+ requests==2.32.0
54
+ # via
55
+ # requests-toolbelt
56
+ # twine
57
+ requests-toolbelt==1.0.0
58
+ # via twine
59
+ rfc3986==2.0.0
60
+ # via twine
61
+ rich==13.7.1
62
+ # via twine
63
+ secretstorage==3.3.3
64
+ # via keyring
65
+ twine==5.1.1
66
+ # via -r requirements-packaging.in
67
+ urllib3==2.2.2
68
+ # via
69
+ # requests
70
+ # twine
71
+ zipp==3.19.1
72
+ # via importlib-metadata
@@ -0,0 +1 @@
1
+ codespell
@@ -0,0 +1,9 @@
1
+ # SHA1:a7062511e9640ed2a5c2dea1da5c8b5f59c0f0d7
2
+ #
3
+ # This file is autogenerated by pip-compile-multi
4
+ # To update, run:
5
+ #
6
+ # pip-compile-multi
7
+ #
8
+ codespell==2.3.0
9
+ # via -r dev_requirements/requirements-spell_check.in
@@ -0,0 +1,2 @@
1
+ # specific requirements for the tox tests env
2
+ pytest
@@ -0,0 +1,15 @@
1
+ # SHA1:0eaa389e1fdb3a1917c0f987514bd561be5718ee
2
+ #
3
+ # This file is autogenerated by pip-compile-multi
4
+ # To update, run:
5
+ #
6
+ # pip-compile-multi
7
+ #
8
+ iniconfig==2.0.0
9
+ # via pytest
10
+ packaging==24.0
11
+ # via pytest
12
+ pluggy==1.5.0
13
+ # via pytest
14
+ pytest==8.3.2
15
+ # via -r dev_requirements/requirements-tests.in
@@ -0,0 +1,2 @@
1
+ # specific requirements for the tox type_check environment
2
+ mypy
@@ -0,0 +1,13 @@
1
+ # SHA1:7983aaa01d64547827c20395d77e248c41b2572f
2
+ #
3
+ # This file is autogenerated by pip-compile-multi
4
+ # To update, run:
5
+ #
6
+ # pip-compile-multi
7
+ #
8
+ mypy==1.11.1
9
+ # via -r dev_requirements/requirements-type_check.in
10
+ mypy-extensions==1.0.0
11
+ # via mypy
12
+ typing-extensions==4.10.0
13
+ # via mypy
@@ -0,0 +1,2 @@
1
+ # contains 1 lower case word per line which are ignored in the spell_check
2
+ contrl
@@ -0,0 +1,65 @@
1
+ [project]
2
+ name = "efoli"
3
+ description = "Enums and related helper functions that model EDIFACT relevant data for German utilities"
4
+ license = { text = "MIT" }
5
+ requires-python = ">=3.11"
6
+ authors = [{ name = "Hochfrequenz Unternehmensberatung GmbH", email = "info+github@hochfrequenz.de" }]
7
+ keywords = ["edifact", "enums", "bdew"]
8
+ classifiers = [
9
+ "Development Status :: 4 - Beta",
10
+ "Environment :: Console",
11
+ "Intended Audience :: Developers",
12
+ "License :: OSI Approved :: MIT License",
13
+ "Operating System :: OS Independent",
14
+ "Programming Language :: Python",
15
+ "Programming Language :: Python :: 3 :: Only",
16
+ "Programming Language :: Python :: 3.11",
17
+ "Programming Language :: Python :: 3.12",
18
+ ]
19
+ dependencies = [] # add all the dependencies here
20
+ dynamic = ["readme", "version"]
21
+
22
+ [project.urls]
23
+ Changelog = "https://github.com/Hochfrequenz/efoli/releases"
24
+ Homepage = "https://github.com/Hochfrequenz/efoli"
25
+
26
+ [tool.black]
27
+ line-length = 120
28
+ target_version = ["py311", "py312"]
29
+
30
+ [tool.isort]
31
+ line_length = 120
32
+ profile = "black"
33
+
34
+ [tool.pylint."MESSAGES CONTROL"]
35
+ max-line-length = 120
36
+
37
+ [mypy]
38
+ truethy-bool = true
39
+
40
+ [tool.mypy]
41
+ disable_error_code = []
42
+
43
+ [build-system]
44
+ requires = ["hatchling>=1.8.0", "hatch-vcs", "hatch-fancy-pypi-readme"]
45
+ build-backend = "hatchling.build"
46
+
47
+ [tool.hatch.metadata.hooks.fancy-pypi-readme]
48
+ content-type = "text/markdown"
49
+ fragments = [{ path = "README.md" }]
50
+
51
+ [tool.hatch.version]
52
+ source = "vcs"
53
+
54
+ [tool.hatch.build.hooks.vcs]
55
+ version-file = "src/_efoli_version.py"
56
+ template = '''
57
+ version = "{version}"
58
+ '''
59
+
60
+ [tool.hatch.build.targets.sdist]
61
+ exclude = ["/unittests"]
62
+
63
+ [tool.hatch.build.targets.wheel]
64
+ only-include = ["src"]
65
+ sources = ["src"]
@@ -0,0 +1,6 @@
1
+ #
2
+ # This file is autogenerated by pip-compile with Python 3.11
3
+ # by the following command:
4
+ #
5
+ # pip-compile pyproject.toml
6
+ #
@@ -0,0 +1 @@
1
+ version = "0.0.1"
@@ -0,0 +1,14 @@
1
+ """
2
+ efoli contains enums and related helper functions for EDIFACT formats and format versions
3
+ """
4
+
5
+ from .edifact_format import EdifactFormat, get_format_of_pruefidentifikator
6
+ from .edifact_format_version import EdifactFormatVersion, get_current_edifact_format_version, get_edifact_format_version
7
+
8
+ __all__ = [
9
+ "EdifactFormat",
10
+ "get_format_of_pruefidentifikator",
11
+ "EdifactFormatVersion",
12
+ "get_current_edifact_format_version",
13
+ "get_edifact_format_version",
14
+ ]
@@ -0,0 +1,78 @@
1
+ """
2
+ contains the EdifactFormat enum and helper methods
3
+ """
4
+
5
+ import re
6
+ from enum import StrEnum
7
+
8
+ _PRUEFI_REGEX = r"^[1-9]\d{4}$"
9
+ pruefidentifikator_pattern = re.compile(_PRUEFI_REGEX)
10
+
11
+
12
+ # pylint: disable=too-few-public-methods
13
+ class EdifactFormat(StrEnum):
14
+ """
15
+ existing EDIFACT formats
16
+ """
17
+
18
+ APERAK = "APERAK"
19
+ COMDIS = "COMDIS" #: communication dispute
20
+ CONTRL = "CONTRL" #: control messages
21
+ IFTSTA = "IFTSTA" #: Multimodaler Statusbericht
22
+ INSRPT = "INSRPT" #: Prüfbericht
23
+ INVOIC = "INVOIC" #: invoice
24
+ MSCONS = "MSCONS" #: meter readings
25
+ ORDCHG = "ORDCHG" #: changing an order
26
+ ORDERS = "ORDERS" #: orders
27
+ ORDRSP = "ORDRSP" #: orders response
28
+ PRICAT = "PRICAT" #: price catalogue
29
+ QUOTES = "QUOTES" #: quotes
30
+ REMADV = "REMADV" #: zahlungsavis
31
+ REQOTE = "REQOTE" #: request quote
32
+ PARTIN = "PARTIN" #: market partner data
33
+ UTILMD = "UTILMD" #: utilities master data
34
+ UTILMDG = "UTILMDG" #: utilities master data for 'Gas'
35
+ UTILMDS = "UTILMDS" #: utilities master data for 'Strom'
36
+ UTILMDW = "UTILMDW" #: utilities master data 'Wasser'
37
+ UTILTS = "UTILTS" #: formula
38
+
39
+ def __str__(self) -> str:
40
+ return self.value
41
+
42
+
43
+ _edifact_mapping: dict[str, EdifactFormat] = {
44
+ "99": EdifactFormat.APERAK,
45
+ "29": EdifactFormat.COMDIS,
46
+ "21": EdifactFormat.IFTSTA,
47
+ "23": EdifactFormat.INSRPT,
48
+ "31": EdifactFormat.INVOIC,
49
+ "13": EdifactFormat.MSCONS,
50
+ "39": EdifactFormat.ORDCHG,
51
+ "17": EdifactFormat.ORDERS,
52
+ "19": EdifactFormat.ORDRSP,
53
+ "27": EdifactFormat.PRICAT,
54
+ "15": EdifactFormat.QUOTES,
55
+ "33": EdifactFormat.REMADV,
56
+ "35": EdifactFormat.REQOTE,
57
+ "37": EdifactFormat.PARTIN,
58
+ "11": EdifactFormat.UTILMD,
59
+ "25": EdifactFormat.UTILTS,
60
+ "91": EdifactFormat.CONTRL,
61
+ "92": EdifactFormat.APERAK,
62
+ "44": EdifactFormat.UTILMD, # UTILMD for GAS since FV2310
63
+ "55": EdifactFormat.UTILMD, # UTILMD for STROM since FV2310
64
+ }
65
+
66
+
67
+ def get_format_of_pruefidentifikator(pruefidentifikator: str) -> EdifactFormat:
68
+ """
69
+ returns the format corresponding to a given pruefi
70
+ """
71
+ if not pruefidentifikator:
72
+ raise ValueError("The pruefidentifikator must not be falsy")
73
+ if not pruefidentifikator_pattern.match(pruefidentifikator):
74
+ raise ValueError(f"The pruefidentifikator '{pruefidentifikator}' is invalid.")
75
+ try:
76
+ return _edifact_mapping[pruefidentifikator[:2]]
77
+ except KeyError as key_error:
78
+ raise ValueError(f"No Edifact format was found for pruefidentifikator '{pruefidentifikator}'.") from key_error
@@ -0,0 +1,61 @@
1
+ """contains the EdifactFormatVersion enum"""
2
+
3
+ import datetime
4
+ from enum import StrEnum
5
+
6
+
7
+ class EdifactFormatVersion(StrEnum):
8
+ """
9
+ One format version refers to the period in which an AHB is valid.
10
+ """
11
+
12
+ FV2104 = "FV2104" #: valid from 2021-04-01 until 2021-10-01
13
+ FV2110 = "FV2110" #: valid from 2021-10-01 until 2022-04-01
14
+ FV2210 = "FV2210" #: valid from 2022-10-01 onwards ("MaKo 2022", was 2204 previously)
15
+ FV2304 = "FV2304" #: valid from 2023-04-01 onwards
16
+ FV2310 = "FV2310" #: valid from 2023-10-01 onwards
17
+ FV2404 = "FV2404" #: valid from 2024-04-01 onwards
18
+ FV2410 = "FV2410" #: valid from 2024-10-01 onwards
19
+ FV2504 = "FV2504" #: valid from 2025-04-04 onwards
20
+ FV2510 = "FV2510" #: valid from 2025-10-01 onwards
21
+ # whenever you add another value here, please also make sure to add its key date to get_edifact_format_version below
22
+
23
+ def __str__(self) -> str:
24
+ return self.value
25
+
26
+
27
+ def get_edifact_format_version(key_date: datetime.datetime) -> EdifactFormatVersion:
28
+ """
29
+ Retrieves the appropriate Edifact format version applicable for the given key date.
30
+
31
+ This function determines the correct Edifact format version by comparing the provided key date
32
+ against a series of predefined datetime thresholds. Each threshold corresponds to a specific
33
+ version of the Edifact format.
34
+
35
+ :param key_date: The date for which the Edifact format version is to be determined.
36
+ :return: The Edifact format version valid for the specified key date.
37
+ """
38
+ format_version_thresholds = [
39
+ (datetime.datetime(2021, 9, 30, 22, 0, 0, 0, tzinfo=datetime.timezone.utc), EdifactFormatVersion.FV2104),
40
+ (datetime.datetime(2022, 9, 30, 22, 0, 0, 0, tzinfo=datetime.timezone.utc), EdifactFormatVersion.FV2110),
41
+ (datetime.datetime(2023, 3, 31, 22, 0, 0, 0, tzinfo=datetime.timezone.utc), EdifactFormatVersion.FV2210),
42
+ (datetime.datetime(2023, 9, 30, 22, 0, 0, 0, tzinfo=datetime.timezone.utc), EdifactFormatVersion.FV2304),
43
+ (datetime.datetime(2024, 4, 2, 22, 0, 0, 0, tzinfo=datetime.timezone.utc), EdifactFormatVersion.FV2310),
44
+ (datetime.datetime(2024, 9, 30, 22, 0, 0, 0, tzinfo=datetime.timezone.utc), EdifactFormatVersion.FV2404),
45
+ (datetime.datetime(2025, 4, 3, 22, 0, 0, 0, tzinfo=datetime.timezone.utc), EdifactFormatVersion.FV2410),
46
+ (datetime.datetime(2025, 9, 30, 22, 0, 0, 0, tzinfo=datetime.timezone.utc), EdifactFormatVersion.FV2504),
47
+ ]
48
+
49
+ for threshold_date, version in format_version_thresholds:
50
+ if key_date < threshold_date:
51
+ return version
52
+
53
+ return EdifactFormatVersion.FV2510
54
+
55
+
56
+ def get_current_edifact_format_version() -> EdifactFormatVersion:
57
+ """
58
+ returns the edifact_format_version that is valid as of now
59
+ """
60
+ tz_aware_now = datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc)
61
+ return get_edifact_format_version(tz_aware_now)
@@ -0,0 +1,2 @@
1
+ # This file marks mypackage as PEP561 compatible.
2
+ # Further reading: https://mypy.readthedocs.io/en/stable/installed_packages.html#creating-pep-561-compatible-packages
efoli-0.0.1/tox.ini ADDED
@@ -0,0 +1,95 @@
1
+ [tox]
2
+ envlist =
3
+ tests
4
+ linting
5
+ coverage
6
+ type_check
7
+ skip_missing_interpreters = True
8
+ skipsdist = True
9
+
10
+ [testenv]
11
+ commands = python -m pip install --upgrade pip
12
+
13
+ [testenv:tests]
14
+ # the tests environment is called by the Github action that runs the unit tests
15
+ deps =
16
+ -r requirements.txt
17
+ -r dev_requirements/requirements-tests.txt
18
+ setenv = PYTHONPATH = {toxinidir}/src
19
+ commands = python -m pytest --basetemp={envtmpdir} {posargs}
20
+
21
+ [testenv:linting]
22
+ # the linting environment is called by the Github Action that runs the linter
23
+ deps =
24
+ {[testenv:tests]deps}
25
+ -r dev_requirements/requirements-linting.txt
26
+ # add your fixtures like e.g. pytest_datafiles here
27
+ setenv = PYTHONPATH = {toxinidir}/src
28
+ commands =
29
+ pylint efoli
30
+ pylint unittests --rcfile=unittests/.pylintrc
31
+ # add single files (ending with .py) or packages here
32
+
33
+ [testenv:type_check]
34
+ # the type_check environment checks the type hints using mypy
35
+ setenv = PYTHONPATH = {toxinidir}/src
36
+ deps =
37
+ {[testenv:tests]deps}
38
+ -r dev_requirements/requirements-type_check.txt
39
+ commands =
40
+ mypy --show-error-codes src/efoli --strict
41
+ mypy --show-error-codes unittests --strict
42
+ # add single files (ending with .py) or packages here
43
+
44
+ [testenv:spell_check]
45
+ # the spellcheck environment checks the code for typos
46
+ setenv = PYTHONPATH = {toxinidir}/src
47
+ deps =
48
+ -r requirements.txt
49
+ -r dev_requirements/requirements-spell_check.txt
50
+ commands =
51
+ codespell --ignore-words=domain-specific-terms.txt src
52
+ codespell --ignore-words=domain-specific-terms.txt README.md
53
+ # add single files (ending with .py) or packages here
54
+
55
+ [testenv:coverage]
56
+ # the coverage environment is called by the Github Action that runs the coverage measurement
57
+ changedir = unittests
58
+ deps =
59
+ {[testenv:tests]deps}
60
+ -r dev_requirements/requirements-coverage.txt
61
+ setenv = PYTHONPATH = {toxinidir}/src
62
+ commands =
63
+ coverage run -m pytest --basetemp={envtmpdir} {posargs}
64
+ coverage html --omit .tox/*,unittests/*
65
+ coverage report --fail-under 80 --omit .tox/*,unittests/*
66
+
67
+ [testenv:compile_requirements]
68
+ deps =
69
+ pip-compile-multi
70
+ commands =
71
+ pip-compile-multi -d dev_requirements --autoresolve
72
+
73
+ [testenv:dev]
74
+ # the dev environment contains everything you need to start developing on your local machine.
75
+ deps =
76
+ {[testenv:tests]deps}
77
+ {[testenv:linting]deps}
78
+ {[testenv:type_check]deps}
79
+ {[testenv:coverage]deps}
80
+ {[testenv:spell_check]deps}
81
+ -r dev_requirements/requirements-formatting.txt
82
+ pip-tools
83
+ pre-commit
84
+ commands =
85
+ python -m pip install --upgrade pip
86
+ pip install -r requirements.txt
87
+ pre-commit install
88
+
89
+ [testenv:test_packaging]
90
+ skip_install = true
91
+ deps =
92
+ -r dev_requirements/requirements-packaging.txt
93
+ commands =
94
+ python -m build
95
+ twine check dist/*