asanypath 2.0.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.
Files changed (67) hide show
  1. asanypath-2.0.0/.copilot/skills/async-python-lib/SKILL.md +52 -0
  2. asanypath-2.0.0/.copilot/skills/gitguro/SKILL.md +37 -0
  3. asanypath-2.0.0/.github/CODEOWNERS +1 -0
  4. asanypath-2.0.0/.github/ISSUE_TEMPLATE/bug_report.md +22 -0
  5. asanypath-2.0.0/.github/ISSUE_TEMPLATE/feature_request.md +13 -0
  6. asanypath-2.0.0/.github/PULL_REQUEST_TEMPLATE.md +9 -0
  7. asanypath-2.0.0/.github/dependabot.yml +27 -0
  8. asanypath-2.0.0/.github/workflows/publish.yml +182 -0
  9. asanypath-2.0.0/.github/workflows/unittests.yml +61 -0
  10. asanypath-2.0.0/.gitignore +26 -0
  11. asanypath-2.0.0/.pre-commit-config.yaml +25 -0
  12. asanypath-2.0.0/CODE_OF_CONDUCT.md +12 -0
  13. asanypath-2.0.0/CONTRIBUTING.md +42 -0
  14. asanypath-2.0.0/LICENSE +21 -0
  15. asanypath-2.0.0/PKG-INFO +591 -0
  16. asanypath-2.0.0/README.md +533 -0
  17. asanypath-2.0.0/SECURITY.md +17 -0
  18. asanypath-2.0.0/asanypath.png +0 -0
  19. asanypath-2.0.0/compose.yml +104 -0
  20. asanypath-2.0.0/hatch_build.py +20 -0
  21. asanypath-2.0.0/pyproject.toml +153 -0
  22. asanypath-2.0.0/scripts/bench.py +1693 -0
  23. asanypath-2.0.0/src/asanypath/__init__.py +81 -0
  24. asanypath-2.0.0/src/asanypath/__init__.pyi +62 -0
  25. asanypath-2.0.0/src/asanypath/_credstore.py +102 -0
  26. asanypath-2.0.0/src/asanypath/_transfer.py +216 -0
  27. asanypath-2.0.0/src/asanypath/_version.py +24 -0
  28. asanypath-2.0.0/src/asanypath/artifactory.py +366 -0
  29. asanypath-2.0.0/src/asanypath/asanypath.py +556 -0
  30. asanypath-2.0.0/src/asanypath/asanypath.pyi +225 -0
  31. asanypath-2.0.0/src/asanypath/azure.py +274 -0
  32. asanypath-2.0.0/src/asanypath/batcher.py +206 -0
  33. asanypath-2.0.0/src/asanypath/cli.py +2566 -0
  34. asanypath-2.0.0/src/asanypath/cloud.py +1042 -0
  35. asanypath-2.0.0/src/asanypath/common.py +355 -0
  36. asanypath-2.0.0/src/asanypath/exceptions.py +43 -0
  37. asanypath-2.0.0/src/asanypath/ftp.py +543 -0
  38. asanypath-2.0.0/src/asanypath/gcs.py +253 -0
  39. asanypath-2.0.0/src/asanypath/http.py +516 -0
  40. asanypath-2.0.0/src/asanypath/local.py +817 -0
  41. asanypath-2.0.0/src/asanypath/options.py +57 -0
  42. asanypath-2.0.0/src/asanypath/s3.py +277 -0
  43. asanypath-2.0.0/src/asanypath/ssh.py +776 -0
  44. asanypath-2.0.0/src/asanypath/sync.py +220 -0
  45. asanypath-2.0.0/src/asanypath/unsupported.py +202 -0
  46. asanypath-2.0.0/src/asanypath_native.pyi +97 -0
  47. asanypath-2.0.0/tests/__init__.py +7 -0
  48. asanypath-2.0.0/tests/conftest.py +99 -0
  49. asanypath-2.0.0/tests/test_artifactory.py +419 -0
  50. asanypath-2.0.0/tests/test_asanypath.py +189 -0
  51. asanypath-2.0.0/tests/test_azure.py +479 -0
  52. asanypath-2.0.0/tests/test_batcher.py +215 -0
  53. asanypath-2.0.0/tests/test_cli.py +1322 -0
  54. asanypath-2.0.0/tests/test_cloudpathmixin.py +937 -0
  55. asanypath-2.0.0/tests/test_commonpathmixin.py +372 -0
  56. asanypath-2.0.0/tests/test_credstore.py +126 -0
  57. asanypath-2.0.0/tests/test_ftp.py +644 -0
  58. asanypath-2.0.0/tests/test_gcs.py +398 -0
  59. asanypath-2.0.0/tests/test_http.py +660 -0
  60. asanypath-2.0.0/tests/test_http_auth.py +188 -0
  61. asanypath-2.0.0/tests/test_local.py +1163 -0
  62. asanypath-2.0.0/tests/test_s3.py +511 -0
  63. asanypath-2.0.0/tests/test_ssh.py +995 -0
  64. asanypath-2.0.0/tests/test_sync.py +183 -0
  65. asanypath-2.0.0/tests/test_syncpath.py +349 -0
  66. asanypath-2.0.0/tests/test_unsupported_path.py +83 -0
  67. asanypath-2.0.0/uv.lock +2804 -0
@@ -0,0 +1,52 @@
1
+ # Copilot Skill: Async Python Library Development
2
+
3
+ ## Purpose
4
+ Guide development of async Python libraries with clean APIs, proper typing, and thorough testing.
5
+
6
+ ## Technical Stack
7
+ - **Python**: 3.10+ with full async/await
8
+ - **Package Manager**: uv (sync, run, build)
9
+ - **Build**: hatchling
10
+ - **Lint/Format**: ruff
11
+ - **Type Checking**: mypy with strict settings
12
+ - **Testing**: pytest + pytest-asyncio (asyncio_mode = "auto")
13
+
14
+ ## Development Commands
15
+ - Install: `uv sync --all-extras`
16
+ - Test: `uv run pytest tests/ -x -q`
17
+ - Lint: `uvx ruff check --fix && uvx ruff format`
18
+ - Type check: `uv run mypy src/`
19
+ - Build wheel: `uv build --wheel`
20
+
21
+ ## Code Conventions
22
+ - All I/O operations must be async (`async def`)
23
+ - Use `anyio` over raw `asyncio` where available for backend-agnostic code
24
+ - Type every function signature — no `Any` unless unavoidable
25
+ - Public API lives in `__init__.py` via `__all__`
26
+ - Use `src/` layout (`src/<package>/`)
27
+ - Exceptions go in `exceptions.py`, inherit from a single base error
28
+
29
+ ## Async Patterns
30
+ - Never call blocking I/O in async functions — use `anyio.to_thread.run_sync()` if needed
31
+ - Prefer `async with` for resource management (connections, sessions, file handles)
32
+ - Use `asynccontextmanager` for custom async context managers
33
+ - Avoid `asyncio.get_event_loop()` — let the framework manage the loop
34
+
35
+ ## Testing
36
+ - All async tests use bare `async def test_*()` (pytest-asyncio auto mode)
37
+ - Use fixtures for shared setup (`@pytest.fixture`)
38
+ - Mock external services (S3, DB) — never hit real infra in unit tests
39
+ - Use `tmp_path` for filesystem tests
40
+ - Run with `-x -q` for fast feedback, `-v` for debugging
41
+
42
+ ## Library Design
43
+ - Keep dependencies minimal — use optional extras for heavy backends
44
+ - Expose a clean `__all__` — implementation details stay private
45
+ - Prefer composition over inheritance for mixins
46
+ - Document breaking changes in commit messages
47
+
48
+ ## What NOT to Do
49
+ - Don't add sync wrappers unless the user asks
50
+ - Don't add CLI features unless the user asks
51
+ - Don't change `__all__` exports without discussing
52
+ - Don't add new dependencies without mentioning it
@@ -0,0 +1,37 @@
1
+ # Copilot Skill: gitguro
2
+
3
+ ## Purpose
4
+ Create clean, focused local commits for completed work.
5
+
6
+ ## Trigger
7
+ Use this skill when the user asks to commit, finalize, or prepare local changes.
8
+
9
+ ## Local Commit Workflow
10
+ 1. Confirm the current directory is a Git repository with `git rev-parse --is-inside-work-tree`.
11
+ 2. Inspect the working tree with `git status --short` and `git diff --name-only`.
12
+ 3. Leave unrelated user changes unstaged and unmodified.
13
+ 4. Run the relevant validation. Pre-commit hooks enforce Ruff formatting and linting when installed; run `uvx ruff check --fix && uvx ruff format` before committing Python changes when practical.
14
+ 5. Group related files into one logical concern and stage only those paths.
15
+ 6. Commit with a concise imperative subject. Split unrelated work into separate commits.
16
+ 7. Confirm the remaining working tree state and report the commit hash and any intentionally uncommitted files.
17
+
18
+ ## Push Policy
19
+
20
+ **Never push commits, create or update a pull request, fetch, pull, rebase, or
21
+ change branches unless the user explicitly requests that exact remote action.**
22
+
23
+ Do not infer consent to publish from a request to commit or finalize work.
24
+ Report that commits remain local unless the user has specifically asked to push.
25
+
26
+ ## Good Commit Message Examples
27
+ - feat: add HTTP backend with async streaming
28
+ - fix: handle trailing slash in S3 glob patterns
29
+ - test: add integration tests for GCS path operations
30
+ - docs: document protocol registration API
31
+
32
+ ## Guardrails
33
+ - Never use destructive git commands unless explicitly requested.
34
+ - If there are unrelated workspace changes, avoid committing them.
35
+ - Prefer non-interactive git commands.
36
+ - Never amend, rebase, or rewrite commits unless explicitly requested.
37
+ - Never commit credentials, generated noise, or unreviewed changes.
@@ -0,0 +1 @@
1
+ * @hoshimura @hannabjorgvins
@@ -0,0 +1,22 @@
1
+ ---
2
+ name: Bug report
3
+ about: Report unexpected behavior
4
+ labels: bug
5
+ ---
6
+
7
+ ## Summary
8
+
9
+ ## Steps to reproduce
10
+
11
+ ## Expected behavior
12
+
13
+ ## Actual behavior
14
+
15
+ ## Environment
16
+
17
+ - AsAnyPath version:
18
+ - Python version:
19
+ - Operating system:
20
+
21
+ Do not include credentials, tokens, private endpoints, or customer data. Report
22
+ security vulnerabilities privately as described in `SECURITY.md`.
@@ -0,0 +1,13 @@
1
+ ---
2
+ name: Feature request
3
+ about: Propose an improvement
4
+ labels: enhancement
5
+ ---
6
+
7
+ ## Problem
8
+
9
+ ## Proposed solution
10
+
11
+ ## Alternatives considered
12
+
13
+ ## Additional context
@@ -0,0 +1,9 @@
1
+ ## Summary
2
+
3
+ ## Validation
4
+
5
+ ## Checklist
6
+
7
+ - [ ] Tests cover the changed behavior.
8
+ - [ ] Documentation reflects user-visible changes.
9
+ - [ ] No credentials, private endpoints, or confidential data are included.
@@ -0,0 +1,27 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: github-actions
4
+ directory: /
5
+ schedule:
6
+ interval: weekly
7
+ open-pull-requests-limit: 1
8
+ cooldown:
9
+ default-days: 14
10
+ groups:
11
+ github-actions:
12
+ patterns:
13
+ - "*"
14
+ - package-ecosystem: pip
15
+ directory: /
16
+ schedule:
17
+ interval: weekly
18
+ open-pull-requests-limit: 3
19
+ cooldown:
20
+ default-days: 14
21
+ - package-ecosystem: cargo
22
+ directory: /rust
23
+ schedule:
24
+ interval: weekly
25
+ open-pull-requests-limit: 3
26
+ cooldown:
27
+ default-days: 14
@@ -0,0 +1,182 @@
1
+ name: Publish Python and native Package to pypi
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ jobs:
11
+ release-version:
12
+ runs-on: ubuntu-latest
13
+ outputs:
14
+ value: ${{ steps.version.outputs.value }}
15
+ steps:
16
+ - name: Validate release tag
17
+ id: version
18
+ env:
19
+ TAG: ${{ github.event.release.tag_name }}
20
+ run: |
21
+ case "$TAG" in
22
+ v[0-9]*.[0-9]*.[0-9]*) ;;
23
+ *) echo "Release tag must be v<major>.<minor>.<patch>." >&2; exit 1 ;;
24
+ esac
25
+ echo "value=${TAG#v}" >> "$GITHUB_OUTPUT"
26
+
27
+ build-native:
28
+ needs: release-version
29
+ strategy:
30
+ fail-fast: false
31
+ matrix:
32
+ include:
33
+ - os: ubuntu-latest
34
+ target: x86_64
35
+ manylinux: auto
36
+ - os: macos-13
37
+ target: x86_64
38
+ manylinux: off
39
+ - os: macos-14
40
+ target: aarch64
41
+ manylinux: off
42
+ - os: windows-latest
43
+ target: x64
44
+ manylinux: off
45
+ runs-on: ${{ matrix.os }}
46
+ steps:
47
+ - name: Checkout release
48
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
49
+ with:
50
+ ref: ${{ github.event.release.tag_name }}
51
+ fetch-depth: 0
52
+ persist-credentials: false
53
+
54
+ - name: Set native package version
55
+ shell: bash
56
+ env:
57
+ VERSION: ${{ needs.release-version.outputs.value }}
58
+ run: |
59
+ sed -i.bak -E "s/^version = \".*\"$/version = \"${VERSION}\"/" rust/Cargo.toml
60
+ rm rust/Cargo.toml.bak
61
+
62
+ - name: Build native wheels
63
+ uses: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1
64
+ with:
65
+ working-directory: rust
66
+ target: ${{ matrix.target }}
67
+ manylinux: ${{ matrix.manylinux }}
68
+ args: --release --out dist --interpreter 3.10 3.11 3.12 3.13 3.14
69
+
70
+ - name: Upload native wheels
71
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
72
+ with:
73
+ name: native-${{ matrix.os }}-${{ matrix.target }}
74
+ path: rust/dist/*.whl
75
+ if-no-files-found: error
76
+
77
+ build-native-sdist:
78
+ needs: release-version
79
+ runs-on: ubuntu-latest
80
+ steps:
81
+ - name: Checkout release
82
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
83
+ with:
84
+ ref: ${{ github.event.release.tag_name }}
85
+ fetch-depth: 0
86
+ persist-credentials: false
87
+
88
+ - name: Set native package version
89
+ shell: bash
90
+ env:
91
+ VERSION: ${{ needs.release-version.outputs.value }}
92
+ run: |
93
+ sed -i.bak -E "s/^version = \".*\"$/version = \"${VERSION}\"/" rust/Cargo.toml
94
+ rm rust/Cargo.toml.bak
95
+
96
+ - name: Set up uv
97
+ uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
98
+ with:
99
+ enable-cache: false
100
+
101
+ - name: Build native source distribution
102
+ run: uvx maturin sdist --manifest-path rust/Cargo.toml --out dist
103
+
104
+ - name: Upload native source distribution
105
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
106
+ with:
107
+ name: native-sdist
108
+ path: dist/*.tar.gz
109
+ if-no-files-found: error
110
+
111
+ build-python:
112
+ needs: [release-version, build-native, build-native-sdist]
113
+ runs-on: ubuntu-latest
114
+ steps:
115
+ - name: Checkout release
116
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
117
+ with:
118
+ ref: ${{ github.event.release.tag_name }}
119
+ fetch-depth: 0
120
+ persist-credentials: false
121
+
122
+ - name: Set up uv
123
+ uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
124
+ with:
125
+ enable-cache: false
126
+
127
+ - name: Build Python distributions
128
+ run: uv build --out-dir dist
129
+
130
+ - name: Verify native dependency version
131
+ env:
132
+ VERSION: ${{ needs.release-version.outputs.value }}
133
+ run: |
134
+ unzip -p dist/*.whl '*/METADATA' | grep -Fx "Requires-Dist: asanypath-native~=${VERSION}.0"
135
+
136
+ - name: Upload Python distributions
137
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
138
+ with:
139
+ name: python-distributions
140
+ path: dist/*
141
+ if-no-files-found: error
142
+
143
+ publish-native:
144
+ needs: [build-native, build-native-sdist, build-python]
145
+ runs-on: ubuntu-latest
146
+ environment:
147
+ name: pypi-native
148
+ url: https://pypi.org/p/asanypath-native
149
+ permissions:
150
+ id-token: write
151
+ steps:
152
+ - name: Download native distributions
153
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
154
+ with:
155
+ pattern: native-*
156
+ path: dist
157
+ merge-multiple: true
158
+
159
+ - name: Publish native distribution
160
+ uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1
161
+ with:
162
+ packages-dir: dist
163
+
164
+ publish-python:
165
+ needs: [publish-native, build-python]
166
+ runs-on: ubuntu-latest
167
+ environment:
168
+ name: pypi
169
+ url: https://pypi.org/p/asanypath
170
+ permissions:
171
+ id-token: write
172
+ steps:
173
+ - name: Download Python distributions
174
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
175
+ with:
176
+ name: python-distributions
177
+ path: dist
178
+
179
+ - name: Publish Python distribution
180
+ uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1
181
+ with:
182
+ packages-dir: dist
@@ -0,0 +1,61 @@
1
+ name: Unit test, lint and coverage
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ rust:
14
+ name: Rust checks
15
+ runs-on: ubuntu-latest
16
+ steps:
17
+ - name: Checkout repository
18
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
19
+ with:
20
+ persist-credentials: false
21
+
22
+ - name: Check formatting
23
+ run: cargo fmt --manifest-path rust/Cargo.toml --check
24
+
25
+ - name: Check crate
26
+ run: cargo check --manifest-path rust/Cargo.toml --locked
27
+
28
+ test:
29
+ runs-on: ubuntu-latest
30
+ strategy:
31
+ fail-fast: true
32
+ matrix:
33
+ python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
34
+ steps:
35
+ - name: Checkout repository
36
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
37
+ with:
38
+ fetch-depth: 0
39
+ persist-credentials: false
40
+
41
+ - name: Set up Python
42
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7
43
+ with:
44
+ python-version: ${{ matrix.python-version }}
45
+
46
+ - name: Set up uv
47
+ uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
48
+
49
+ - name: Ruff checks
50
+ run: uvx ruff check src tests && uvx ruff format --check src tests
51
+
52
+ - name: Create virtual environment
53
+ run: uv venv --python "${{ matrix.python-version }}"
54
+
55
+ - name: Install project and native extension
56
+ run: uv pip install -e ".[dev]"
57
+
58
+ - name: Test with pytest and coverage
59
+ env:
60
+ PYTHONUNBUFFERED: 1
61
+ run: uv run --no-sync python -m pytest --cov=src --cov-report=term-missing --cov-fail-under=90 tests
@@ -0,0 +1,26 @@
1
+ # ignore all files
2
+ *
3
+ # allow listing directory contents
4
+ !*/
5
+ # venv directories
6
+ .venv/
7
+ rust/.venv/
8
+ __pycache__
9
+ # except for the following files and directories
10
+ !pyproject.toml
11
+ !*.md
12
+ !LICENSE
13
+ !.*ignore
14
+ !.copilot/**/SKILL.md
15
+ !.github/**
16
+ !*.py
17
+ !*.pyi
18
+ !asanypath.png
19
+ # auto-generated by hatch-vcs
20
+ _version.py
21
+ !compose.yml
22
+ !uv.lock
23
+ !rust/Cargo.toml
24
+ !rust/Cargo.lock
25
+ !rust/src/**/*.rs
26
+
@@ -0,0 +1,25 @@
1
+ repos:
2
+ - repo: https://github.com/astral-sh/ruff-pre-commit
3
+ # Ruff version.
4
+ rev: v0.15.4
5
+ hooks:
6
+ # Run the linter.
7
+ - id: ruff-check
8
+ args: [ --fix ]
9
+ # Run the formatter.
10
+ - id: ruff-format
11
+ - repo: local
12
+ hooks:
13
+ # Mirror the CI Rust checks (.github/workflows/unittests.yml).
14
+ - id: cargo-fmt
15
+ name: cargo fmt (rust)
16
+ entry: cargo fmt --manifest-path rust/Cargo.toml --check
17
+ language: system
18
+ files: ^rust/.*\.rs$
19
+ pass_filenames: false
20
+ - id: cargo-check
21
+ name: cargo check (rust)
22
+ entry: cargo check --manifest-path rust/Cargo.toml --locked
23
+ language: system
24
+ files: ^rust/.*\.(rs|toml|lock)$
25
+ pass_filenames: false
@@ -0,0 +1,12 @@
1
+ # Code of Conduct
2
+
3
+ We are committed to a respectful, collaborative community. Participate in good
4
+ faith, welcome different perspectives, and focus discussion on the work.
5
+
6
+ Harassment, discrimination, personal attacks, and sharing private or
7
+ confidential information are not acceptable.
8
+
9
+ Project maintainers may remove, edit, or reject contributions and comments that
10
+ do not follow this code of conduct. Report conduct concerns through the private
11
+ security-reporting route in [SECURITY.md](SECURITY.md). Reports will be handled
12
+ as confidentially as practical.
@@ -0,0 +1,42 @@
1
+ # Contributing to AsAnyPath
2
+
3
+ Thank you for contributing to AsAnyPath.
4
+
5
+ ## Getting Started
6
+
7
+ Use Python 3.10 or newer and install the development dependencies:
8
+
9
+ ```bash
10
+ uv sync --extra dev
11
+ uv pip install --reinstall --no-cache rust/
12
+ ```
13
+
14
+ Optionally install the repository's pre-commit hooks to run formatting and
15
+ linting checks before each commit:
16
+
17
+ ```bash
18
+ uv run pre-commit install
19
+ ```
20
+
21
+ Run the focused tests for your change, then the full suite before opening a pull
22
+ request:
23
+
24
+ ```bash
25
+ uv run --extra dev pytest -vx tests/
26
+ uvx ruff check --fix
27
+ uvx ruff format
28
+ cargo check --manifest-path rust/Cargo.toml
29
+ ```
30
+
31
+ ## Pull Requests
32
+
33
+ Keep pull requests focused and include tests for changed behavior. Preserve
34
+ compatibility with Python 3.10 through 3.14. Describe user-visible changes and
35
+ document new configuration, credentials, or backend behavior in the README.
36
+
37
+ Do not include credentials, private endpoints, customer data, or other
38
+ confidential information in issues, commits, tests, or pull requests. Report
39
+ security issues privately as described in [SECURITY.md](SECURITY.md).
40
+
41
+ By contributing, you agree that your contributions are licensed under the
42
+ [MIT License](LICENSE).
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Axis Communications AB
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.