yoki5 0.1.0__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.
@@ -0,0 +1,15 @@
1
+ * yoki5 version:
2
+ * Python version:
3
+ * Operating System:
4
+
5
+ ### Description
6
+
7
+ Describe what you were trying to get done.
8
+ Tell us what happened, what went wrong, and what you expected to happen.
9
+
10
+ ### What I Did
11
+
12
+ ```
13
+ Paste the command(s) you ran and the output.
14
+ If there was a crash, please include the traceback here.
15
+ ```
@@ -0,0 +1,12 @@
1
+ ---
2
+ title: "{{ env.TITLE }}"
3
+ labels: [bug]
4
+ ---
5
+ The {{ workflow }} workflow failed on {{ date | date("YYYY-MM-DD HH:mm") }} UTC
6
+
7
+ The most recent failing test was on {{ env.PLATFORM }} py{{ env.PYTHON }}
8
+ with commit: {{ sha }}
9
+
10
+ Full run: https://github.com/{{ repo }}/actions/runs/{{ env.RUN_ID }}
11
+
12
+ (This post will be updated if another test fails, as long as this issue remains open.)
@@ -0,0 +1,10 @@
1
+ # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
2
+
3
+ version: 2
4
+ updates:
5
+ - package-ecosystem: "github-actions"
6
+ directory: "/"
7
+ schedule:
8
+ interval: "weekly"
9
+ commit-message:
10
+ prefix: "ci(dependabot):"
@@ -0,0 +1,131 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ tags:
8
+ - "v*"
9
+ pull_request:
10
+ workflow_dispatch:
11
+ schedule:
12
+ - cron: "0 0 * * 0" # every week (for --pre release tests)
13
+
14
+ jobs:
15
+ check-manifest:
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+ - run: pipx run check-manifest
20
+
21
+ test:
22
+
23
+ name: ${{ matrix.platform }} (${{ matrix.python-version }})
24
+ runs-on: ${{ matrix.platform }}
25
+ timeout-minutes: 10
26
+ strategy:
27
+ fail-fast: false
28
+ matrix:
29
+ python-version: ['3.8', '3.9', '3.10', '3.11']
30
+ platform: [ubuntu-latest, macos-latest, windows-latest]
31
+
32
+ steps:
33
+ - name: Cancel Previous Runs
34
+ uses: styfle/cancel-workflow-action@0.12.1
35
+ with:
36
+ access_token: ${{ github.token }}
37
+
38
+ - uses: actions/checkout@v4
39
+
40
+ - name: Set up Python ${{ matrix.python-version }}
41
+ uses: actions/setup-python@v5
42
+ with:
43
+ python-version: ${{ matrix.python-version }}
44
+ cache-dependency-path: "pyproject.toml"
45
+ cache: "pip"
46
+
47
+ # if running a cron job, we add the --pre flag to test against pre-releases
48
+ - name: Install dependencies
49
+ run: |
50
+ python -m pip install -U pip
51
+ python -m pip install .[test] ${{ github.event_name == 'schedule' && '--pre' || '' }}
52
+
53
+ - name: Test
54
+ run: pytest --color=yes --cov --cov-report=xml --cov-report=term-missing
55
+
56
+ # If something goes wrong, we can open an issue in the repo
57
+ - name: Report --pre Failures
58
+ if: failure() && github.event_name == 'schedule'
59
+ uses: JasonEtco/create-an-issue@v2
60
+ env:
61
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
62
+ PLATFORM: ${{ matrix.platform }}
63
+ PYTHON: ${{ matrix.python-version }}
64
+ RUN_ID: ${{ github.run_id }}
65
+ TITLE: '[test-bot] pip install --pre is failing'
66
+ with:
67
+ filename: .github/TEST_FAIL_TEMPLATE.md
68
+ update_existing: true
69
+
70
+ - name: Coverage
71
+ uses: codecov/codecov-action@v3
72
+
73
+ deploy_test:
74
+ name: Deploy to PyPI (test)
75
+ needs: test
76
+ if: success() && startsWith(github.ref, 'refs/tags/') && github.event_name != 'schedule'
77
+ runs-on: ubuntu-latest
78
+
79
+ steps:
80
+ - uses: actions/checkout@v4
81
+
82
+ - name: Set up Python
83
+ uses: actions/setup-python@v5
84
+ with:
85
+ python-version: "3.x"
86
+
87
+ - name: install
88
+ run: |
89
+ git tag
90
+ pip install -U pip build twine
91
+ python -m build
92
+ twine check dist/*
93
+ ls -lh dist
94
+
95
+ - name: Build and publish
96
+ run: twine upload --repository testpypi dist/*
97
+ env:
98
+ TWINE_USERNAME: __token__
99
+ TWINE_PASSWORD: ${{ secrets.TEST_PYPI_TOKEN }}
100
+
101
+ deploy:
102
+ name: Deploy
103
+ needs: test
104
+ if: success() && startsWith(github.ref, 'refs/tags/') && github.event_name != 'schedule'
105
+ runs-on: ubuntu-latest
106
+
107
+ steps:
108
+ - uses: actions/checkout@v4
109
+
110
+ - name: Set up Python
111
+ uses: actions/setup-python@v5
112
+ with:
113
+ python-version: "3.x"
114
+
115
+ - name: install
116
+ run: |
117
+ git tag
118
+ pip install -U pip build twine
119
+ python -m build
120
+ twine check dist/*
121
+ ls -lh dist
122
+
123
+ - name: Build and publish
124
+ run: twine upload dist/*
125
+ env:
126
+ TWINE_USERNAME: __token__
127
+ TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
128
+
129
+ - uses: softprops/action-gh-release@v1
130
+ with:
131
+ generate_release_notes: true
@@ -0,0 +1,61 @@
1
+ <component name="InspectionProjectProfileManager">
2
+ <profile version="1.0">
3
+ <option name="myName" value="Project Default" />
4
+ <inspection_tool class="DuplicatedCode" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
5
+ <inspection_tool class="PyCompatibilityInspection" enabled="true" level="WARNING" enabled_by_default="true">
6
+ <option name="ourVersions">
7
+ <value>
8
+ <list size="4">
9
+ <item index="0" class="java.lang.String" itemvalue="3.8" />
10
+ <item index="1" class="java.lang.String" itemvalue="3.9" />
11
+ <item index="2" class="java.lang.String" itemvalue="3.10" />
12
+ <item index="3" class="java.lang.String" itemvalue="3.11" />
13
+ </list>
14
+ </value>
15
+ </option>
16
+ </inspection_tool>
17
+ <inspection_tool class="PyMissingOrEmptyDocstringInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
18
+ <inspection_tool class="PyPackageRequirementsInspection" enabled="false" level="WARNING" enabled_by_default="false">
19
+ <option name="ignoredPackages">
20
+ <value>
21
+ <list size="19">
22
+ <item index="0" class="java.lang.String" itemvalue="coverage" />
23
+ <item index="1" class="java.lang.String" itemvalue="autopep8" />
24
+ <item index="2" class="java.lang.String" itemvalue="peakutils" />
25
+ <item index="3" class="java.lang.String" itemvalue="tabulate" />
26
+ <item index="4" class="java.lang.String" itemvalue="pytest" />
27
+ <item index="5" class="java.lang.String" itemvalue="matplotlib" />
28
+ <item index="6" class="java.lang.String" itemvalue="bokeh" />
29
+ <item index="7" class="java.lang.String" itemvalue="numpy" />
30
+ <item index="8" class="java.lang.String" itemvalue="Pillow" />
31
+ <item index="9" class="java.lang.String" itemvalue="astropy" />
32
+ <item index="10" class="java.lang.String" itemvalue="Cython" />
33
+ <item index="11" class="java.lang.String" itemvalue="gdecomp" />
34
+ <item index="12" class="java.lang.String" itemvalue="pyimzml" />
35
+ <item index="13" class="java.lang.String" itemvalue="scikit-learn" />
36
+ <item index="14" class="java.lang.String" itemvalue="pylint" />
37
+ <item index="15" class="java.lang.String" itemvalue="black" />
38
+ <item index="16" class="java.lang.String" itemvalue="pep8" />
39
+ <item index="17" class="java.lang.String" itemvalue="flake8" />
40
+ <item index="18" class="java.lang.String" itemvalue="seaborn" />
41
+ </list>
42
+ </value>
43
+ </option>
44
+ </inspection_tool>
45
+ <inspection_tool class="PyPep8Inspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
46
+ <option name="ignoredErrors">
47
+ <list>
48
+ <option value="E203" />
49
+ </list>
50
+ </option>
51
+ </inspection_tool>
52
+ <inspection_tool class="PyPep8NamingInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
53
+ <option name="ignoredErrors">
54
+ <list>
55
+ <option value="N802" />
56
+ </list>
57
+ </option>
58
+ </inspection_tool>
59
+ <inspection_tool class="PyProtectedMemberInspection" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
60
+ </profile>
61
+ </component>
@@ -0,0 +1,6 @@
1
+ <component name="InspectionProjectProfileManager">
2
+ <settings>
3
+ <option name="USE_PROJECT_PROFILE" value="false" />
4
+ <version value="1.0" />
5
+ </settings>
6
+ </component>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectModuleManager">
4
+ <modules>
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/yoki5.iml" filepath="$PROJECT_DIR$/.idea/yoki5.iml" />
6
+ </modules>
7
+ </component>
8
+ </project>
@@ -0,0 +1,15 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectViewState">
4
+ <option name="autoscrollToSource" value="true" />
5
+ <option name="compactDirectories" value="true" />
6
+ <option name="hideEmptyMiddlePackages" value="true" />
7
+ <option name="showLibraryContents" value="true" />
8
+ <option name="showMembers" value="true" />
9
+ </component>
10
+ <component name="PropertiesComponent">{
11
+ &quot;keyToString&quot;: {
12
+ &quot;settings.editor.selected.configurable&quot;: &quot;MTConfigurable&quot;
13
+ }
14
+ }</component>
15
+ </project>
@@ -0,0 +1,50 @@
1
+ ci:
2
+ autoupdate_schedule: monthly
3
+ autofix_commit_msg: "style(pre-commit.ci): auto fixes [...]"
4
+ autoupdate_commit_msg: "ci(pre-commit.ci): autoupdate"
5
+
6
+ default_install_hook_types: [pre-commit, commit-msg]
7
+
8
+ repos:
9
+ # - repo: https://github.com/pre-commit/pre-commit-hooks
10
+ # rev: v4.4.0
11
+ # hooks:
12
+ # - id: no-commit-to-branch
13
+ # args: ['--branch', 'master', "--branch", "main"]
14
+
15
+ - repo: https://github.com/MarcoGorelli/absolufy-imports
16
+ rev: v0.3.1
17
+ hooks:
18
+ - id: absolufy-imports
19
+ exclude: _vendor|vendored
20
+
21
+ - repo: https://github.com/hadialqattan/pycln
22
+ rev: v2.1.3
23
+ hooks:
24
+ - id: pycln
25
+
26
+ - repo: https://github.com/abravalheri/validate-pyproject
27
+ rev: v0.12.1
28
+ hooks:
29
+ - id: validate-pyproject
30
+
31
+ - repo: https://github.com/psf/black
32
+ rev: 23.1.0
33
+ hooks:
34
+ - id: black
35
+ pass_filenames: true
36
+
37
+ - repo: https://github.com/charliermarsh/ruff-pre-commit
38
+ rev: v0.0.252
39
+ hooks:
40
+ - id: ruff
41
+ args: [--fix]
42
+
43
+ # - repo: https://github.com/pre-commit/mirrors-mypy
44
+ # rev: v1.0.1
45
+ # hooks:
46
+ # - id: mypy
47
+ # files: "^src/"
48
+ # # # you have to add the things you want to type check against here
49
+ # # additional_dependencies:
50
+ # # - numpy
yoki5-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Lukasz Migas
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,16 @@
1
+ # Things to always exclude
2
+ global-exclude .git*
3
+ global-exclude .ipynb_checkpoints
4
+ global-exclude *.py[co]
5
+ recursive-exclude * __pycache__
6
+ recursive-exclude * *.py[co]
7
+
8
+ # Top-level config
9
+ include MANIFEST.in
10
+ include LICENSE
11
+ recursive-include tests *
12
+ recursive-include src *.typed
13
+
14
+ # Always include
15
+ global-include *.pyx
16
+ global-include *.c
yoki5-0.1.0/Makefile ADDED
@@ -0,0 +1,89 @@
1
+ .PHONY: clean clean-test clean-pyc clean-build docs help
2
+ .DEFAULT_GOAL := help
3
+
4
+ define BROWSER_PYSCRIPT
5
+ import os, webbrowser, sys
6
+
7
+ from urllib.request import pathname2url
8
+
9
+ webbrowser.open("file://" + pathname2url(os.path.abspath(sys.argv[1])))
10
+ endef
11
+ export BROWSER_PYSCRIPT
12
+
13
+ define PRINT_HELP_PYSCRIPT
14
+ import re, sys
15
+
16
+ for line in sys.stdin:
17
+ match = re.match(r'^([a-zA-Z_-]+):.*?## (.*)$$', line)
18
+ if match:
19
+ target, help = match.groups()
20
+ print("%-20s %s" % (target, help))
21
+ endef
22
+ export PRINT_HELP_PYSCRIPT
23
+
24
+ BROWSER := python -c "$$BROWSER_PYSCRIPT"
25
+
26
+ help:
27
+ @python -c "$$PRINT_HELP_PYSCRIPT" < $(MAKEFILE_LIST)
28
+
29
+ clean: clean-build clean-pyc clean-test ## remove all build, test, coverage and Python artifacts
30
+
31
+ clean-build: ## remove build artifacts
32
+ rm -fr build/
33
+ rm -fr dist/
34
+ rm -fr .eggs/
35
+ find . -name '*.egg-info' -exec rm -fr {} +
36
+ find . -name '*.egg' -exec rm -f {} +
37
+
38
+ clean-pyc: ## remove Python file artifacts
39
+ find . -name '*.pyc' -exec rm -f {} +
40
+ find . -name '*.pyo' -exec rm -f {} +
41
+ find . -name '*~' -exec rm -f {} +
42
+ find . -name '__pycache__' -exec rm -fr {} +
43
+
44
+ clean-test: ## remove test and coverage artifacts
45
+ rm -fr .tox/
46
+ rm -f .coverage
47
+ rm -fr htmlcov/
48
+ rm -fr .pytest_cache
49
+
50
+ test: ## run tests quickly with the default Python
51
+ pytest
52
+
53
+ test-all: ## run tests on every Python version with tox
54
+ tox
55
+
56
+ coverage: ## check code coverage quickly with the default Python
57
+ coverage run --source src/yoki5 -m pytest
58
+ coverage report -m
59
+ coverage html
60
+ $(BROWSER) htmlcov/index.html
61
+
62
+ servedocs: docs ## compile the docs watching for changes
63
+ watchmedo shell-command -p '*.rst' -c '$(MAKE) -C docs html' -R -D .
64
+
65
+ release: dist ## package and upload a release
66
+ twine upload dist/*
67
+
68
+ dist: clean ## builds source and wheel package
69
+ python setup.py sdist
70
+ python setup.py bdist_wheel
71
+ ls -l dist
72
+
73
+ install: clean ## install the package to the active Python's site-packages
74
+ python setup.py install
75
+
76
+ develop:
77
+ python setup.py develop
78
+
79
+ pre:
80
+ pre-commit run -a
81
+
82
+ lint:
83
+ ruff format .
84
+ ruff . --fix
85
+
86
+ untrack:
87
+ git rm -r --cached .
88
+ git add .
89
+ git commit -m ".gitignore fix"
yoki5-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,94 @@
1
+ Metadata-Version: 2.1
2
+ Name: yoki5
3
+ Version: 0.1.0
4
+ Summary: Wrapper around h5py to give easier interface around complex files.
5
+ Author-email: "Lukasz G. Migas" <lukas.migas@yahoo.com>
6
+ License: BSD 3-Clause License
7
+ Project-URL: homepage, https://github.com/lukasz-migas/yoki5
8
+ Project-URL: repository, https://github.com/lukasz-migas/yoki5
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: License :: OSI Approved :: BSD License
11
+ Classifier: Natural Language :: English
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.8
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Typing :: Typed
17
+ Requires-Python: >=3.8
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: h5py
21
+ Requires-Dist: hdf5plugin
22
+ Requires-Dist: natsort
23
+ Requires-Dist: loguru
24
+ Requires-Dist: scipy
25
+ Requires-Dist: koyo
26
+ Requires-Dist: pandas<2
27
+ Provides-Extra: test
28
+ Requires-Dist: pytest>=6.0; extra == "test"
29
+ Requires-Dist: pytest-cov; extra == "test"
30
+ Provides-Extra: dev
31
+ Requires-Dist: black; extra == "dev"
32
+ Requires-Dist: ipython; extra == "dev"
33
+ Requires-Dist: mypy; extra == "dev"
34
+ Requires-Dist: pdbpp; extra == "dev"
35
+ Requires-Dist: pre-commit; extra == "dev"
36
+ Requires-Dist: rich; extra == "dev"
37
+ Requires-Dist: ruff; extra == "dev"
38
+ Requires-Dist: yoki5[test]; extra == "dev"
39
+
40
+ # yoki5
41
+
42
+ [![License](https://img.shields.io/pypi/l/yoki5.svg?color=green)](https://github.com/lukasz-migas/yoki5/raw/main/LICENSE)
43
+ [![PyPI](https://img.shields.io/pypi/v/yoki5.svg?color=green)](https://pypi.org/project/yoki5)
44
+ [![Python Version](https://img.shields.io/pypi/pyversions/yoki5.svg?color=green)](https://python.org)
45
+ [![CI](https://github.com/lukasz-migas/yoki5/actions/workflows/ci.yml/badge.svg)](https://github.com/lukasz-migas/yoki5/actions/workflows/ci.yml)
46
+ [![codecov](https://codecov.io/gh/lukasz-migas/yoki5/branch/main/graph/badge.svg)](https://codecov.io/gh/lukasz-migas/yoki5)
47
+
48
+ ## Overview
49
+
50
+ A simple wrapper around h5py to give easier interface around complex HDF5 files.
51
+
52
+ This library is designed to simplify the process of reading and writing HDF5 files by providing several methods
53
+ that make it easy to add/remove datasets or groups.
54
+
55
+ ## Getting started
56
+
57
+ ```python
58
+ import numpy as np
59
+ from yoki5.base import Store
60
+ from scipy.sparse import csr_matrix
61
+
62
+ # Create a new HDF5 file
63
+ store = Store('path/to/file.h5')
64
+ store.add_data_to_group(
65
+ "group-1",
66
+ {"data": np.random.rand(100, 100)},
67
+ {"attribute": "value"},
68
+ compression="gzip",
69
+ chunks=(10, 10),
70
+ )
71
+ # Retrieve the array
72
+ array = store.get_array("group-1", "data")
73
+
74
+ # Add sparse matrix
75
+ store.add_data_to_group(
76
+ "group-2",
77
+ csr_matrix(np.random.randint(0, 255, (100, 100))),
78
+ {"attribute": "value"},
79
+ )
80
+ # Retrieve the data
81
+ matrix = store.get_sparse_array("group-2")
82
+
83
+ ```
84
+
85
+
86
+ ## Contributing
87
+
88
+ Contributions are always welcome. Please feel free to submit PRs with new features, bug fixes, or documentation improvements.
89
+
90
+ ```bash
91
+ git clone https://github.com/lukasz-migas/yoki5.git
92
+
93
+ pip install -e .[dev]
94
+ ```
yoki5-0.1.0/README.md ADDED
@@ -0,0 +1,55 @@
1
+ # yoki5
2
+
3
+ [![License](https://img.shields.io/pypi/l/yoki5.svg?color=green)](https://github.com/lukasz-migas/yoki5/raw/main/LICENSE)
4
+ [![PyPI](https://img.shields.io/pypi/v/yoki5.svg?color=green)](https://pypi.org/project/yoki5)
5
+ [![Python Version](https://img.shields.io/pypi/pyversions/yoki5.svg?color=green)](https://python.org)
6
+ [![CI](https://github.com/lukasz-migas/yoki5/actions/workflows/ci.yml/badge.svg)](https://github.com/lukasz-migas/yoki5/actions/workflows/ci.yml)
7
+ [![codecov](https://codecov.io/gh/lukasz-migas/yoki5/branch/main/graph/badge.svg)](https://codecov.io/gh/lukasz-migas/yoki5)
8
+
9
+ ## Overview
10
+
11
+ A simple wrapper around h5py to give easier interface around complex HDF5 files.
12
+
13
+ This library is designed to simplify the process of reading and writing HDF5 files by providing several methods
14
+ that make it easy to add/remove datasets or groups.
15
+
16
+ ## Getting started
17
+
18
+ ```python
19
+ import numpy as np
20
+ from yoki5.base import Store
21
+ from scipy.sparse import csr_matrix
22
+
23
+ # Create a new HDF5 file
24
+ store = Store('path/to/file.h5')
25
+ store.add_data_to_group(
26
+ "group-1",
27
+ {"data": np.random.rand(100, 100)},
28
+ {"attribute": "value"},
29
+ compression="gzip",
30
+ chunks=(10, 10),
31
+ )
32
+ # Retrieve the array
33
+ array = store.get_array("group-1", "data")
34
+
35
+ # Add sparse matrix
36
+ store.add_data_to_group(
37
+ "group-2",
38
+ csr_matrix(np.random.randint(0, 255, (100, 100))),
39
+ {"attribute": "value"},
40
+ )
41
+ # Retrieve the data
42
+ matrix = store.get_sparse_array("group-2")
43
+
44
+ ```
45
+
46
+
47
+ ## Contributing
48
+
49
+ Contributions are always welcome. Please feel free to submit PRs with new features, bug fixes, or documentation improvements.
50
+
51
+ ```bash
52
+ git clone https://github.com/lukasz-migas/yoki5.git
53
+
54
+ pip install -e .[dev]
55
+ ```