diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..b99730a --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,7 @@ +ARG VARIANT="3.12" +FROM mcr.microsoft.com/vscode/devcontainers/python:0-${VARIANT} + +COPY requirements*.txt /tmp/pip-tmp/ +RUN pip --disable-pip-version-check --no-cache-dir install -r /tmp/pip-tmp/requirements-test.txt -r /tmp/pip-tmp/requirements.txt && rm -rf /tmp/pip-tmp + +ENV SHELL /bin/bash diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..4904ef7 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,32 @@ +{ + "name": "IMGW-PIB", + "build": { + "dockerfile": "Dockerfile", + "context": ".." + }, + "customizations": { + "vscode": { + "settings": { + "terminal.integrated.profiles.linux": { + "zsh": { + "path": "/usr/bin/zsh" + } + }, + "terminal.integrated.defaultProfile.linux": "zsh", + "python.pythonPath": "/usr/local/bin/python", + "python.languageServer": "Pylance", + "[python]": { + "editor.defaultFormatter": "charliermarsh.ruff" + } + }, + "extensions": [ + "ms-python.python", + "ms-python.vscode-pylance", + "ms-python.pylint", + "charliermarsh.ruff" + ] + } + }, + "postCreateCommand": "scripts/setup-devcontainer-env.sh", + "remoteUser": "vscode" +} diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..61ac2d6 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +custom: ['https://www.paypal.me/bieniu79'] \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..36ce860 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,10 @@ +version: 2 +updates: + - package-ecosystem: "pip" + directory: "/" + schedule: + interval: "weekly" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" \ No newline at end of file diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml new file mode 100644 index 0000000..bacac71 --- /dev/null +++ b/.github/release-drafter.yml @@ -0,0 +1,41 @@ +change-template: "- #$NUMBER $TITLE @$AUTHOR" +sort-direction: ascending + +categories: + - title: ":boom: Breaking Changes" + label: "breaking-change" + + - title: ":sparkles: New Features" + label: "new-feature" + + - title: ":zap: Performance" + label: "performance" + + - title: ":recycle: Refactor" + label: "refactor" + + - title: ":green_heart: CI" + label: "ci" + + - title: ":bug: Bug Fixes" + label: "bugfix" + + - title: ":white_check_mark: Tests" + label: "tests" + + - title: ":arrow_up: Dependency Updates" + label: "dependencies" + collapse-after: 1 + +include-labels: + - "breaking-change" + - "performance" + - "refactor" + - "new-feature" + - "bugfix" + - "dependencies" + - "test" + - "ci" + +template: | + $CHANGES diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..927545f --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,38 @@ +name: "CodeQL" + +on: + push: + branches: [master] + pull_request: + branches: [master] + schedule: + - cron: "21 5 * * 0" + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: ["python"] + + steps: + - name: Checkout repository + uses: actions/checkout@v4.1.2 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + + - name: Autobuild + uses: github/codeql-action/autobuild@v3 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/pre-commit-update.yml b/.github/workflows/pre-commit-update.yml new file mode 100644 index 0000000..3a3e61f --- /dev/null +++ b/.github/workflows/pre-commit-update.yml @@ -0,0 +1,34 @@ +name: Pre-commit auto-update +on: + schedule: + # Run on fridays + - cron: "0 0 * * 5" + +jobs: + auto-update: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4.1.2 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.x" + + - name: Install pre-commit + run: pip install pre-commit + + - name: Run pre-commit autoupdate + run: pre-commit autoupdate + + - name: Create Pull Request + uses: peter-evans/create-pull-request@v6.0.3 + with: + token: ${{ secrets.GITHUB_TOKEN }} + branch: update/pre-commit-autoupdate + title: Auto-update pre-commit hooks + commit-message: Auto-update pre-commit hooks + body: | + Update versions of tools in pre-commit + configs to latest version + labels: dependencies diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..ccd7783 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,30 @@ +name: Upload Python Package + +on: + release: + types: [published] + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - name: Check out repository + uses: actions/checkout@v4.1.2 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install setuptools wheel twine + + - name: Build and publish + env: + TWINE_USERNAME: __token__ + TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} + run: | + python setup.py sdist bdist_wheel + twine upload dist/* diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml new file mode 100644 index 0000000..361db6e --- /dev/null +++ b/.github/workflows/release-drafter.yml @@ -0,0 +1,32 @@ +name: Release Drafter + +on: + push: + branches: + - master + +jobs: + update_release_draft: + runs-on: ubuntu-latest + name: Release Drafter + steps: + - name: Checkout the repository + uses: actions/checkout@v4.1.2 + with: + fetch-depth: 0 + + - name: Find Version + id: version + run: | + declare -i newpost + version=$(python setup.py --version) + echo Version from setup.py: $version + echo "::set-output name=version::$version" + + - name: Run Release Drafter + uses: release-drafter/release-drafter@v6.0.0 + with: + tag: ${{ steps.version.outputs.version }} + name: Version ${{ steps.version.outputs.version }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 0000000..9cc23c4 --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,23 @@ +name: Mark stale issues and pull requests + +on: + schedule: + - cron: '25 8 * * *' + +jobs: + stale: + + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + + steps: + - name: Stale + uses: actions/stale@v9 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-issue-message: 'Stale issue message' + stale-pr-message: 'Stale pull request message' + stale-issue-label: 'no-issue-activity' + stale-pr-label: 'no-pr-activity' \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..425111d --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,33 @@ +name: Test + +on: + push: + branches: [master] + pull_request: + branches: [master] + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: + - "3.12" + + steps: + - name: Check out repository + uses: actions/checkout@v4.1.2 + with: + fetch-depth: 2 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Install dependencies + run: | + pip install uv tox tox-gh-actions tox-uv + + - name: Test with tox + run: tox diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..7ef4488 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,43 @@ +repos: + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.4.1 + hooks: + - id: ruff + args: + - --fix + - id: ruff-format + - repo: https://github.com/codespell-project/codespell + rev: v2.2.6 + hooks: + - id: codespell + args: + - --ignore-words-list=hass,alot,datas,dof,dur,ether,farenheit,hist,iff,ines,ist,lightsensor,mut,nd,pres,referer,ser,serie,te,technik,ue,uint,visability,wan,wanna,withing,iam,incomfort,ba + - --skip="./.*,*.csv,*.json" + - --quiet-level=2 + exclude_types: [csv, json] + exclude: ^tests/fixtures/ + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.6.0 + hooks: + - id: end-of-file-fixer + - id: mixed-line-ending + - id: trailing-whitespace + - id: check-yaml + - id: check-json + - id: check-toml + - id: pretty-format-json + args: + - --no-sort-keys + - id: no-commit-to-branch + args: + - --branch=master + - repo: https://github.com/pre-commit/mirrors-prettier + rev: v4.0.0-alpha.8 + hooks: + - id: prettier + stages: [manual] + - repo: https://github.com/pre-commit/mirrors-mypy + rev: "v1.9.0" + hooks: + - id: mypy + files: ^(imgw_pib)/.+\.py$ diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..566409c --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Fetch data", + "type": "python", + "request": "launch", + "program": "example.py", + "console": "integratedTerminal" + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c635d04 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,10 @@ +{ + "python.testing.pytestArgs": [ + "tests" + ], + "python.testing.unittestEnabled": false, + "python.testing.pytestEnabled": true, + "[python]": { + "editor.defaultFormatter": "charliermarsh.ruff" + } +} diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..50d9d38 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,3 @@ +include LICENSE README.md +include requirements.txt +include requirements-test.txt \ No newline at end of file diff --git a/imgw_pib/py.typed b/imgw_pib/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..3d4eb03 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,33 @@ +[tool.pytest.ini_options] +asyncio_mode = "strict" + +[tool.mypy] +python_version = "3.12" +show_error_codes = true +follow_imports = "silent" +ignore_missing_imports = true +warn_incomplete_stub = true +warn_redundant_casts = true +warn_unused_configs = true +check_untyped_defs = true +disallow_incomplete_defs = true +disallow_subclassing_any = true +disallow_untyped_calls = true +disallow_untyped_decorators = true +disallow_untyped_defs = true +no_implicit_optional = true +strict_equality = true +warn_return_any = true +warn_unused_ignores = true +warn_unreachable = true + +[tool.ruff] +target-version = "py312" + +lint.select = ["ALL"] + +[tool.ruff.lint.mccabe] +max-complexity = 25 + +[tool.coverage.run] +source = ["imgw_pib"] diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 0000000..09e1263 --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1,5 @@ +-r requirements.txt +-r requirements-test.txt +pre-commit==3.7.0 + +-e . diff --git a/requirements-test.txt b/requirements-test.txt new file mode 100644 index 0000000..85ccb41 --- /dev/null +++ b/requirements-test.txt @@ -0,0 +1,10 @@ +aioresponses==0.7.6 +coverage==7.4.4 +mypy==1.9.0 +pytest-asyncio==0.23.6 +pytest-cov==5.0.0 +pytest-error-for-skips==2.0.2 +pytest-timeout==2.3.1 +pytest==8.1.1 +ruff==0.4.1 +syrupy==4.6.1 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..6cea0c0 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +aiohttp>=3.8.0 diff --git a/scripts/setup-devcontainer-env.sh b/scripts/setup-devcontainer-env.sh new file mode 100755 index 0000000..a89a54b --- /dev/null +++ b/scripts/setup-devcontainer-env.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +pip install --upgrade pip setuptools wheel +pip --disable-pip-version-check --no-cache-dir install -r requirements-dev.txt +pre-commit install diff --git a/scripts/setup-local-env.sh b/scripts/setup-local-env.sh new file mode 100755 index 0000000..ac93efc --- /dev/null +++ b/scripts/setup-local-env.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +PYTHON_VERSION=3.12 + +python$PYTHON_VERSION -m pip install uv +python$PYTHON_VERSION -m uv venv venv --seed --python=$PYTHON_VERSION +source venv/bin/activate +pip install uv +uv pip install -r requirements-dev.txt +pre-commit install diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..17b80b5 --- /dev/null +++ b/setup.py @@ -0,0 +1,35 @@ +"""Setup module for imgw-pib.""" + +from pathlib import Path + +from setuptools import setup + +PROJECT_DIR = Path(__file__).parent.resolve() +README_FILE = PROJECT_DIR / "README.md" +VERSION = "0.0.1" + +setup( + name="imgw_pib", + version=VERSION, + author="Maciej Bieniek", + description="Python wrapper for IMGW-PIB API.", + long_description=README_FILE.read_text(encoding="utf-8"), + long_description_content_type="text/markdown", + include_package_data=True, + url="https://github.com/bieniu/imgw-pib", + license="Apache-2.0 License", + packages=["imgw_pib"], + package_data={"imgw_pib": ["py.typed"]}, + python_requires=">=3.12", + install_requires=["aiohttp>=3.8.0"], + classifiers=[ + "Development Status :: 5 - Production/Stable", + "License :: OSI Approved :: Apache Software License", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3 :: Only", + "Typing :: Typed", + ], +) diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..d3a598d --- /dev/null +++ b/tox.ini @@ -0,0 +1,40 @@ +[tox] +envlist = py312, lint, typing, coverage +skip_missing_interpreters = True + +[gh-actions] +python = + 3.12: py312, lint, typing, coverage + +[testenv] +commands = + pytest --timeout=30 --cov=imgw-pib --cov-report=xml {posargs} --error-for-skips +deps = + -rrequirements.txt + -rrequirements-test.txt + +[testenv:lint] +basepython = python3 +ignore_errors = True +commands = + ruff check . + ruff format --check . +deps = + -rrequirements.txt + -rrequirements-test.txt + +[testenv:typing] +basepython = python3 +ignore_errors = True +commands = + mypy imgw_pib +deps = + -rrequirements.txt + -rrequirements-test.txt + +[testenv:coverage] +deps = + -rrequirements.txt + -rrequirements-test.txt +commands = + coverage report --fail-under=79