python-picnic-api2 1.2.2__tar.gz → 1.2.4__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 (27) hide show
  1. python_picnic_api2-1.2.4/.devcontainer/devcontainer.json +28 -0
  2. python_picnic_api2-1.2.4/.env.example +4 -0
  3. python_picnic_api2-1.2.4/.github/ISSUE_TEMPLATE/bug_report.yml +24 -0
  4. python_picnic_api2-1.2.4/.github/ISSUE_TEMPLATE/config.yml +14 -0
  5. python_picnic_api2-1.2.4/.github/dependabot.yml +12 -0
  6. python_picnic_api2-1.2.4/.github/release.yml +17 -0
  7. python_picnic_api2-1.2.4/.github/workflows/ci.yaml +56 -0
  8. python_picnic_api2-1.2.4/.github/workflows/it.yaml +38 -0
  9. python_picnic_api2-1.2.4/.github/workflows/release.yml +49 -0
  10. python_picnic_api2-1.2.4/.gitignore +129 -0
  11. {python_picnic_api2-1.2.2 → python_picnic_api2-1.2.4}/PKG-INFO +9 -17
  12. python_picnic_api2-1.2.4/codecov.yml +3 -0
  13. python_picnic_api2-1.2.4/integration_tests/__init__.py +0 -0
  14. python_picnic_api2-1.2.4/integration_tests/test_client.py +147 -0
  15. python_picnic_api2-1.2.4/integration_tests/test_helper.py +35 -0
  16. python_picnic_api2-1.2.4/integration_tests/test_session.py +40 -0
  17. {python_picnic_api2-1.2.2 → python_picnic_api2-1.2.4}/pyproject.toml +12 -9
  18. {python_picnic_api2-1.2.2 → python_picnic_api2-1.2.4/src}/python_picnic_api2/client.py +2 -1
  19. {python_picnic_api2-1.2.2 → python_picnic_api2-1.2.4/src}/python_picnic_api2/helper.py +13 -7
  20. python_picnic_api2-1.2.4/tests/__init__.py +0 -0
  21. python_picnic_api2-1.2.4/tests/test_client.py +221 -0
  22. python_picnic_api2-1.2.4/tests/test_session.py +75 -0
  23. python_picnic_api2-1.2.4/uv.lock +324 -0
  24. {python_picnic_api2-1.2.2 → python_picnic_api2-1.2.4}/LICENSE.md +0 -0
  25. {python_picnic_api2-1.2.2 → python_picnic_api2-1.2.4}/README.rst +0 -0
  26. {python_picnic_api2-1.2.2 → python_picnic_api2-1.2.4/src}/python_picnic_api2/__init__.py +0 -0
  27. {python_picnic_api2-1.2.2 → python_picnic_api2-1.2.4/src}/python_picnic_api2/session.py +0 -0
@@ -0,0 +1,28 @@
1
+ // For format details, see https://aka.ms/devcontainer.json. For config options, see the
2
+ // README at: https://github.com/devcontainers/templates/tree/main/src/python
3
+ {
4
+ "name": "Python Picnic API",
5
+ // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
6
+ "image": "mcr.microsoft.com/devcontainers/python:1-3.12-bullseye",
7
+ "features": {
8
+ //"ghcr.io/devcontainers-extra/features/poetry:2": {}
9
+ },
10
+ // Features to add to the dev container. More info: https://containers.dev/features.
11
+ // "features": {},
12
+ // Use 'forwardPorts' to make a list of ports inside the container available locally.
13
+ // "forwardPorts": [],
14
+ // Use 'postCreateCommand' to run commands after the container is created.
15
+ // "postCreateCommand": "pip3 install --user -r requirements.txt",
16
+ // Configure tool-specific properties.
17
+ "customizations": {
18
+ "vscode": {
19
+ "extensions": [
20
+ "charliermarsh.ruff",
21
+ "-ms-python.vscode-pylance"
22
+ ]
23
+ }
24
+ },
25
+ "postAttachCommand": "python -m pip install --upgrade pip && python -m pip install uv==0.6.6 && python -m uv sync"
26
+ // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
27
+ // "remoteUser": "root"
28
+ }
@@ -0,0 +1,4 @@
1
+ # you can use this .env file when running pytest
2
+ USERNAME="john@doe.com"
3
+ PASSWORD="password123"
4
+ COUNTRY_CODE="NL" # use either "NL" or "DE"
@@ -0,0 +1,24 @@
1
+ name: Bug report
2
+ description: Create a report to help us improve
3
+ title: 'Enter a summary of the issue'
4
+ labels: "bug"
5
+ body:
6
+ - type: textarea
7
+ attributes:
8
+ label: Describe the bug
9
+ validations:
10
+ required: true
11
+ - type: textarea
12
+ attributes:
13
+ label: Steps to reproduce the issue
14
+ validations:
15
+ required: true
16
+ - type: textarea
17
+ attributes:
18
+ label: What did you expect to happen instead?
19
+ validations:
20
+ required: true
21
+ - type: input
22
+ attributes:
23
+ label: Python Version
24
+ placeholder: X.YY
@@ -0,0 +1,14 @@
1
+ blank_issues_enabled: false
2
+ contact_links:
3
+ - name: Report a bug with the Picnic Integration
4
+ url: https://github.com/home-assistant/core/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22integration%3A%20picnic%22
5
+ about: Please report issues with Picnic in the Home Assistant core repository unless a developer told you otherwise.
6
+ - name: I have a question or need support
7
+ url: https://www.home-assistant.io/help
8
+ about: We use GitHub for tracking bugs, check the Home Assistant website for resources on getting help.
9
+ - name: Feature Request
10
+ url: https://community.home-assistant.io/c/feature-requests
11
+ about: Please use the Home Assistant Community Forum for making feature requests.
12
+ - name: I'm unsure where to go
13
+ url: https://www.home-assistant.io/join-chat
14
+ about: If you are unsure where to go, then joining our chat is recommended; Just ask!
@@ -0,0 +1,12 @@
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 more information:
4
+ # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5
+ # https://containers.dev/guide/dependabot
6
+
7
+ version: 2
8
+ updates:
9
+ - package-ecosystem: "devcontainers"
10
+ directory: "/"
11
+ schedule:
12
+ interval: weekly
@@ -0,0 +1,17 @@
1
+ changelog:
2
+ categories:
3
+ - title: ⚠️ Breaking Changes
4
+ labels:
5
+ - breaking
6
+ - title: 🎉 New Features
7
+ labels:
8
+ - enhancement
9
+ - title: 🛠 Bugfixes
10
+ labels:
11
+ - bug
12
+ - title: 👒 Dependencies
13
+ labels:
14
+ - dependencies
15
+ - title: Others
16
+ labels:
17
+ - "*"
@@ -0,0 +1,56 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [ main ]
6
+ pull_request:
7
+ branches: [ main ]
8
+
9
+ jobs:
10
+ build:
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ python-version: [3.11,3.12]
15
+ uv-version: [0.6.6]
16
+
17
+ runs-on: ubuntu-latest
18
+
19
+ steps:
20
+ - uses: actions/checkout@v2
21
+
22
+ - name: Set up Python ${{ matrix.python-version }}
23
+ uses: actions/setup-python@v2
24
+ with:
25
+ python-version: ${{ matrix.python-version }}
26
+
27
+ - name: Install uv ${{ matrix.uv-version }}
28
+ run: |
29
+ python -m ensurepip
30
+ python -m pip install --upgrade pip
31
+ python -m pip install uv==${{ matrix.uv-version }}
32
+
33
+ - name: Install dependencies
34
+ shell: bash
35
+ run: uv sync
36
+
37
+ - name: Test with pytest
38
+ env:
39
+ USERNAME: ${{ secrets.PICNIC_USERNAME }}
40
+ PASSWORD: ${{ secrets.PICNIC_PASSWORD }}
41
+ COUNTRY_CODE: ${{ secrets.PICNIC_COUNTRY_CODE }}
42
+ run: |
43
+ uv run pytest tests/ --cov --cov-report=xml
44
+
45
+ - name: Lint with ruff
46
+ run: |
47
+ uv run ruff check --output-format=github --ignore FIX
48
+
49
+ - name: Upload coverage reports to Codecov
50
+ uses: codecov/codecov-action@v5
51
+ with:
52
+ token: ${{ secrets.CODECOV_TOKEN }}
53
+
54
+
55
+
56
+
@@ -0,0 +1,38 @@
1
+ name: Regular Integration Tests
2
+
3
+ on:
4
+ schedule:
5
+ # * is a special character in YAML so you have to quote this string
6
+ - cron: '0 0 */7 * *'
7
+ workflow_dispatch:
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+
13
+ steps:
14
+ - uses: actions/checkout@v2
15
+
16
+ - name: Set up Python 3.12
17
+ uses: actions/setup-python@v2
18
+ with:
19
+ python-version: 3.12
20
+
21
+ - name: Install uv 0.6.6
22
+ run: |
23
+ python -m ensurepip
24
+ python -m pip install --upgrade pip
25
+ python -m pip install uv==0.6.6
26
+
27
+ - name: Install dependencies
28
+ shell: bash
29
+ run: uv sync
30
+
31
+ - name: Test with pytest
32
+ env:
33
+ USERNAME: ${{ secrets.PICNIC_USERNAME }}
34
+ PASSWORD: ${{ secrets.PICNIC_PASSWORD }}
35
+ COUNTRY_CODE: ${{ secrets.PICNIC_COUNTRY_CODE }}
36
+ run: |
37
+ uv run pytest -v integration_tests
38
+
@@ -0,0 +1,49 @@
1
+ name: Release to PyPi
2
+ on: [workflow_dispatch]
3
+ jobs:
4
+ build:
5
+ runs-on: ubuntu-latest
6
+ steps:
7
+ - uses: actions/checkout@v2
8
+
9
+ - name: Set up Python 3.11
10
+ uses: actions/setup-python@v2
11
+ with:
12
+ python-version: 3.11
13
+
14
+ - name: Install uv 0.6.6
15
+ run: |
16
+ python -m ensurepip
17
+ python -m pip install --upgrade pip
18
+ python -m pip install uv==0.6.6
19
+
20
+ - name: Install dependencies
21
+ shell: bash
22
+ run: uv sync
23
+
24
+ - name: Build package
25
+ shell: bash
26
+ run: uv build
27
+
28
+ - name: Upload artifacts
29
+ uses: actions/upload-artifact@v4
30
+ with:
31
+ name: release-dists
32
+ path: dist/
33
+ pypi-publish:
34
+ runs-on: ubuntu-latest
35
+ environment: pypi
36
+ needs:
37
+ - build
38
+ permissions:
39
+ id-token: write
40
+
41
+ steps:
42
+ - name: Retrieve release distributions
43
+ uses: actions/download-artifact@v4
44
+ with:
45
+ name: release-dists
46
+ path: dist/
47
+
48
+ - name: Publish release distributions to PyPI
49
+ uses: pypa/gh-action-pypi-publish@v1.12.4
@@ -0,0 +1,129 @@
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
+ .hypothesis/
51
+ .pytest_cache/
52
+
53
+ # Translations
54
+ *.mo
55
+ *.pot
56
+
57
+ # Django stuff:
58
+ *.log
59
+ local_settings.py
60
+ db.sqlite3
61
+ db.sqlite3-journal
62
+
63
+ # Flask stuff:
64
+ instance/
65
+ .webassets-cache
66
+
67
+ # Scrapy stuff:
68
+ .scrapy
69
+
70
+ # Sphinx documentation
71
+ docs/_build/
72
+
73
+ # PyBuilder
74
+ target/
75
+
76
+ # Jupyter Notebook
77
+ .ipynb_checkpoints
78
+
79
+ # IPython
80
+ profile_default/
81
+ ipython_config.py
82
+
83
+ # pyenv
84
+ .python-version
85
+
86
+ # pipenv
87
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
88
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
89
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
90
+ # install all needed dependencies.
91
+ #Pipfile.lock
92
+
93
+ # celery beat schedule file
94
+ celerybeat-schedule
95
+
96
+ # SageMath parsed files
97
+ *.sage.py
98
+
99
+ # Environments
100
+ .env
101
+ .venv
102
+ env/
103
+ venv/
104
+ ENV/
105
+ env.bak/
106
+ venv.bak/
107
+
108
+ # Spyder project settings
109
+ .spyderproject
110
+ .spyproject
111
+
112
+ # Rope project settings
113
+ .ropeproject
114
+
115
+ # mkdocs documentation
116
+ /site
117
+
118
+ # mypy
119
+ .mypy_cache/
120
+ .dmypy.json
121
+ dmypy.json
122
+
123
+ # Pyre type checker
124
+ .pyre/
125
+
126
+ # Visual Studio Code
127
+ .vscode
128
+ .direnv
129
+ .ruff_cache
@@ -1,22 +1,15 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: python-picnic-api2
3
- Version: 1.2.2
4
- Summary:
3
+ Version: 1.2.4
4
+ Project-URL: homepage, https://github.com/codesalatdev/python-picnic-api
5
+ Project-URL: repository, https://github.com/codesalatdev/python-picnic-api
6
+ Author-email: Mike Brink <mjh.brink@icloud.com>, CodeSalat <pypi@codesalat.dev>
7
+ Maintainer-email: CodeSalat <pypi@codesalat.dev>
5
8
  License: Apache-2.0
6
- Author: Mike Brink
7
- Author-email: mjh.brink@icloud.com
8
- Maintainer: CodeSalat
9
- Maintainer-email: pypi@codesalat.dev
9
+ License-File: LICENSE.md
10
10
  Requires-Python: >=3.11
11
- Classifier: License :: OSI Approved :: Apache Software License
12
- Classifier: Programming Language :: Python :: 3
13
- Classifier: Programming Language :: Python :: 3.11
14
- Classifier: Programming Language :: Python :: 3.12
15
- Classifier: Programming Language :: Python :: 3.13
16
- Requires-Dist: requests (>=2.24.0)
17
- Requires-Dist: typing_extensions (>=4.12.2)
18
- Project-URL: Homepage, https://github.com/codesalatdev/python-picnic-api
19
- Project-URL: Repository, https://github.com/codesalatdev/python-picnic-api
11
+ Requires-Dist: requests>=2.24.0
12
+ Requires-Dist: typing-extensions>=4.12.2
20
13
  Description-Content-Type: text/x-rst
21
14
 
22
15
  """""""""""""""""
@@ -100,4 +93,3 @@ See available delivery slots
100
93
 
101
94
  >>> picnic.get_delivery_slots()
102
95
 
103
-
@@ -0,0 +1,3 @@
1
+ ignore:
2
+ - "tests"
3
+ - "integration_tests"
File without changes
@@ -0,0 +1,147 @@
1
+ import os
2
+ import time
3
+
4
+ import pytest
5
+ from dotenv import load_dotenv
6
+
7
+ from python_picnic_api2 import PicnicAPI
8
+
9
+ load_dotenv()
10
+
11
+ username = os.getenv("USERNAME")
12
+ password = os.getenv("PASSWORD")
13
+ country_code = os.getenv("COUNTRY_CODE")
14
+
15
+ picnic = PicnicAPI(username, password, country_code=country_code)
16
+
17
+
18
+ @pytest.fixture(autouse=True)
19
+ def slow_down_tests():
20
+ yield
21
+ time.sleep(2)
22
+
23
+
24
+ def _get_amount(cart: dict, product_id: str):
25
+ items = cart["items"][0]["items"]
26
+ product = next((item for item in items if item["id"] == product_id), None)
27
+ return product["decorators"][0]["quantity"]
28
+
29
+
30
+ def test_get_user():
31
+ response = picnic.get_user()
32
+ assert isinstance(response, dict)
33
+ assert "contact_email" in response
34
+ assert response["contact_email"] == username
35
+
36
+
37
+ def test_search():
38
+ response = picnic.search("kaffee")
39
+ assert isinstance(response, list)
40
+ assert isinstance(response[0], dict)
41
+ assert "items" in response[0]
42
+ assert isinstance(response[0]["items"], list)
43
+ assert "id" in response[0]["items"][0]
44
+
45
+
46
+ def test_get_article():
47
+ response = picnic.get_article("s1018620")
48
+ assert isinstance(response, dict)
49
+ assert "id" in response
50
+ assert response["id"] == "s1018620"
51
+ assert response["name"] == "Gut&Günstig H-Milch 3,5%"
52
+
53
+
54
+ def test_get_article_with_category_name():
55
+ with pytest.raises(NotImplementedError):
56
+ picnic.get_article("s1018620", add_category_name=True)
57
+
58
+
59
+ def test_get_cart():
60
+ response = picnic.get_cart()
61
+ assert isinstance(response, dict)
62
+ assert "id" in response
63
+ assert response["id"] == "shopping_cart"
64
+
65
+
66
+ def test_add_product():
67
+ # need a clear cart for reproducibility
68
+ picnic.clear_cart()
69
+ response = picnic.add_product("s1018620", count=2)
70
+
71
+ assert isinstance(response, dict)
72
+ assert "items" in response
73
+ assert any(item["id"] == "s1018620" for item in response["items"][0]["items"])
74
+ assert _get_amount(response, "s1018620") == 2
75
+
76
+
77
+ def test_remove_product():
78
+ # need a clear cart for reproducibility
79
+ picnic.clear_cart()
80
+ # add two milk to the cart so we can remove 1
81
+ picnic.add_product("s1018620", count=2)
82
+
83
+ response = picnic.remove_product("s1018620", count=1)
84
+ amount = _get_amount(response, "s1018620")
85
+
86
+ assert isinstance(response, dict)
87
+ assert "items" in response
88
+ assert amount == 1
89
+
90
+
91
+ def test_clear_cart():
92
+ # need a clear cart for reproducibility
93
+ picnic.clear_cart()
94
+ # add two coffee to the cart so we can clear it
95
+ picnic.add_product("s1018620", count=2)
96
+
97
+ response = picnic.clear_cart()
98
+
99
+ assert isinstance(response, dict)
100
+ assert "items" in response
101
+ assert len(response["items"]) == 0
102
+
103
+
104
+ def test_get_delivery_slots():
105
+ response = picnic.get_delivery_slots()
106
+ assert isinstance(response, dict)
107
+ assert "delivery_slots" in response
108
+ assert isinstance(response["delivery_slots"], list)
109
+
110
+
111
+ def test_get_deliveries():
112
+ response = picnic.get_deliveries()
113
+
114
+ assert isinstance(response, list)
115
+ assert isinstance(response[0], dict)
116
+ assert response[0]["status"] == "COMPLETED"
117
+
118
+
119
+ def test_get_delivery():
120
+ # get a id to test against
121
+ response = picnic.get_deliveries()
122
+ deliveryId = response[0]["delivery_id"]
123
+
124
+ response = picnic.get_delivery(deliveryId)
125
+ assert isinstance(response, dict)
126
+ assert response["status"] == "COMPLETED"
127
+ assert response["id"] == deliveryId
128
+
129
+
130
+ def test_get_current_deliveries():
131
+ response = picnic.get_current_deliveries()
132
+ assert isinstance(response, list)
133
+
134
+
135
+ def test_get_categories():
136
+ response = picnic.get_categories()
137
+ assert isinstance(response, list)
138
+
139
+
140
+ def test_print_categories(capsys):
141
+ picnic.print_categories()
142
+ captured = capsys.readouterr()
143
+
144
+ assert isinstance(captured.out, str)
145
+
146
+
147
+ # TODO: add test for re-logging
@@ -0,0 +1,35 @@
1
+ import requests
2
+
3
+ from python_picnic_api2.helper import get_image, get_recipe_image
4
+
5
+
6
+ def test_get_image():
7
+ id = "8560e1f1c2d2811dfefbbb2342ef0d95250533f2131416aca459bde35d73e901"
8
+ size = "tile-medium"
9
+ suffix = "webp"
10
+ url = get_image(id, size=size, suffix=suffix)
11
+
12
+ response = requests.get(url)
13
+
14
+ # Check if the response status code indicates success
15
+ assert response.status_code == 200, "Failed to fetch URL"
16
+
17
+ # Check if the response content type is an image format
18
+ content_type = response.headers.get("content-type")
19
+ assert content_type.startswith("image/"), "URL does not return an image"
20
+
21
+
22
+ def test_get_recipe_image():
23
+ id = "5c4cc7cb7a0429695da708394eb0cae1bd9b92935ac76c8fda63bbc57ad5b826"
24
+ size = "medium"
25
+ url = get_recipe_image(id, size=size)
26
+ print(url)
27
+
28
+ response = requests.get(url)
29
+
30
+ # Check if the response status code indicates success
31
+ assert response.status_code == 200, "Failed to fetch URL"
32
+
33
+ # Check if the response content type is an image format
34
+ content_type = response.headers.get("content-type")
35
+ assert content_type.startswith("image/"), "URL does not return an image"
@@ -0,0 +1,40 @@
1
+ import os
2
+
3
+ from dotenv import load_dotenv
4
+ from requests import Session
5
+
6
+ from python_picnic_api2.client import PicnicAPI
7
+ from python_picnic_api2.session import PicnicAPISession, PicnicAuthError
8
+
9
+ load_dotenv()
10
+
11
+ username = os.getenv("USERNAME")
12
+ password = os.getenv("PASSWORD")
13
+ country_code = os.getenv("COUNTRY_CODE")
14
+
15
+ DEFAULT_URL = "https://storefront-prod.{}.picnicinternational.com/api/{}"
16
+ DEFAULT_API_VERSION = "15"
17
+
18
+
19
+ def test_init():
20
+ assert issubclass(PicnicAPISession, Session)
21
+
22
+
23
+ def test_login():
24
+ client = PicnicAPI(
25
+ username=username, password=password, country_code=country_code
26
+ )
27
+ assert "x-picnic-auth" in client.session.headers
28
+
29
+
30
+ def test_login_auth_error():
31
+ try:
32
+ PicnicAPI(
33
+ username="doesnotexistblue@me.com",
34
+ password="PasSWorD12345!",
35
+ country_code=country_code,
36
+ )
37
+ except PicnicAuthError:
38
+ assert True
39
+ else:
40
+ raise AssertionError()
@@ -1,9 +1,9 @@
1
1
  [project]
2
2
  name = "python-picnic-api2"
3
- version = "1.2.2"
3
+ version = "1.2.4"
4
4
  description = ""
5
5
  readme = "README.rst"
6
- license = "Apache-2.0"
6
+ license = {text = "Apache-2.0"}
7
7
  maintainers = [
8
8
  { name = "CodeSalat", email = "pypi@codesalat.dev"}
9
9
  ]
@@ -18,11 +18,6 @@ dependencies = [
18
18
  "typing_extensions>=4.12.2"
19
19
  ]
20
20
 
21
- [tool.poetry.group.dev.dependencies]
22
- pytest = "^8.3"
23
- ruff = "^0.9.6"
24
- python-dotenv = "^0.15.0"
25
-
26
21
  [tool.ruff]
27
22
  line-length = 88
28
23
  indent-width = 4
@@ -46,6 +41,14 @@ select = [
46
41
  "FIX"
47
42
  ]
48
43
 
44
+ [dependency-groups]
45
+ dev = [
46
+ "pytest>=8.3.5",
47
+ "pytest-cov>=6.0.0",
48
+ "python-dotenv>=1.0.1",
49
+ "ruff>=0.9.10",
50
+ ]
51
+
49
52
  [build-system]
50
- requires = ["poetry-core"]
51
- build-backend = "poetry.core.masonry.api"
53
+ requires = ["hatchling"]
54
+ build-backend = "hatchling.build"