visor-python 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.
- visor_python-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +90 -0
- visor_python-0.1.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
- visor_python-0.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +57 -0
- visor_python-0.1.0/.github/dependabot.yml +30 -0
- visor_python-0.1.0/.github/workflows/ci.yml +63 -0
- visor_python-0.1.0/.github/workflows/publish.yml +85 -0
- visor_python-0.1.0/.gitignore +36 -0
- visor_python-0.1.0/.pre-commit-config.yaml +26 -0
- visor_python-0.1.0/CHANGELOG.md +29 -0
- visor_python-0.1.0/CODE_OF_CONDUCT.md +59 -0
- visor_python-0.1.0/CONTRIBUTING.md +38 -0
- visor_python-0.1.0/LICENSE +21 -0
- visor_python-0.1.0/PKG-INFO +250 -0
- visor_python-0.1.0/README.md +214 -0
- visor_python-0.1.0/SECURITY.md +33 -0
- visor_python-0.1.0/pyproject.toml +85 -0
- visor_python-0.1.0/src/visor/__init__.py +95 -0
- visor_python-0.1.0/src/visor/_client.py +588 -0
- visor_python-0.1.0/src/visor/_pagination.py +109 -0
- visor_python-0.1.0/src/visor/_transport.py +130 -0
- visor_python-0.1.0/src/visor/exceptions.py +72 -0
- visor_python-0.1.0/src/visor/models/__init__.py +82 -0
- visor_python-0.1.0/src/visor/models/_base.py +353 -0
- visor_python-0.1.0/src/visor/models/dealers.py +81 -0
- visor_python-0.1.0/src/visor/models/facets.py +142 -0
- visor_python-0.1.0/src/visor/models/listings.py +205 -0
- visor_python-0.1.0/src/visor/models/usage.py +30 -0
- visor_python-0.1.0/src/visor/models/vins.py +9 -0
- visor_python-0.1.0/src/visor/py.typed +0 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Report a problem with visor-python.
|
|
3
|
+
title: "[Bug]: "
|
|
4
|
+
labels: ["bug"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Thanks for taking the time to report this.
|
|
10
|
+
|
|
11
|
+
Please do not include API keys, secrets, or sensitive live API response data.
|
|
12
|
+
|
|
13
|
+
- type: textarea
|
|
14
|
+
id: summary
|
|
15
|
+
attributes:
|
|
16
|
+
label: Summary
|
|
17
|
+
description: What happened?
|
|
18
|
+
placeholder: Describe the bug clearly and briefly.
|
|
19
|
+
validations:
|
|
20
|
+
required: true
|
|
21
|
+
|
|
22
|
+
- type: textarea
|
|
23
|
+
id: reproduce
|
|
24
|
+
attributes:
|
|
25
|
+
label: Reproduction
|
|
26
|
+
description: Minimal code or steps that reproduce the issue.
|
|
27
|
+
render: python
|
|
28
|
+
placeholder: |
|
|
29
|
+
from visor import VisorClient
|
|
30
|
+
|
|
31
|
+
with VisorClient(api_key="...") as client:
|
|
32
|
+
...
|
|
33
|
+
validations:
|
|
34
|
+
required: true
|
|
35
|
+
|
|
36
|
+
- type: textarea
|
|
37
|
+
id: expected
|
|
38
|
+
attributes:
|
|
39
|
+
label: Expected behavior
|
|
40
|
+
description: What did you expect to happen?
|
|
41
|
+
validations:
|
|
42
|
+
required: true
|
|
43
|
+
|
|
44
|
+
- type: textarea
|
|
45
|
+
id: actual
|
|
46
|
+
attributes:
|
|
47
|
+
label: Actual behavior
|
|
48
|
+
description: What happened instead? Include traceback text if available.
|
|
49
|
+
render: text
|
|
50
|
+
validations:
|
|
51
|
+
required: true
|
|
52
|
+
|
|
53
|
+
- type: input
|
|
54
|
+
id: version
|
|
55
|
+
attributes:
|
|
56
|
+
label: visor-python version
|
|
57
|
+
placeholder: "0.1.0"
|
|
58
|
+
validations:
|
|
59
|
+
required: true
|
|
60
|
+
|
|
61
|
+
- type: dropdown
|
|
62
|
+
id: python-version
|
|
63
|
+
attributes:
|
|
64
|
+
label: Python version
|
|
65
|
+
options:
|
|
66
|
+
- "3.10"
|
|
67
|
+
- "3.11"
|
|
68
|
+
- "3.12"
|
|
69
|
+
- "3.13"
|
|
70
|
+
- "Other"
|
|
71
|
+
validations:
|
|
72
|
+
required: true
|
|
73
|
+
|
|
74
|
+
- type: dropdown
|
|
75
|
+
id: client
|
|
76
|
+
attributes:
|
|
77
|
+
label: Client type
|
|
78
|
+
options:
|
|
79
|
+
- Sync VisorClient
|
|
80
|
+
- Async AsyncVisorClient
|
|
81
|
+
- Both
|
|
82
|
+
- Not sure
|
|
83
|
+
validations:
|
|
84
|
+
required: true
|
|
85
|
+
|
|
86
|
+
- type: textarea
|
|
87
|
+
id: context
|
|
88
|
+
attributes:
|
|
89
|
+
label: Additional context
|
|
90
|
+
description: Any other details that may help. Redact secrets and identifiers if needed.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
name: Feature request or API coverage
|
|
2
|
+
description: Request a new SDK feature, endpoint wrapper, or model coverage.
|
|
3
|
+
title: "[Feature]: "
|
|
4
|
+
labels: ["enhancement"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Thanks for helping improve visor-python.
|
|
10
|
+
|
|
11
|
+
Please do not include API keys, secrets, or sensitive live API response data.
|
|
12
|
+
|
|
13
|
+
- type: textarea
|
|
14
|
+
id: goal
|
|
15
|
+
attributes:
|
|
16
|
+
label: What do you want to do?
|
|
17
|
+
description: Describe the workflow or capability you want the SDK to support.
|
|
18
|
+
placeholder: I want to...
|
|
19
|
+
validations:
|
|
20
|
+
required: true
|
|
21
|
+
|
|
22
|
+
- type: input
|
|
23
|
+
id: api-area
|
|
24
|
+
attributes:
|
|
25
|
+
label: Related Visor API area
|
|
26
|
+
description: Endpoint, resource, or SDK area if known.
|
|
27
|
+
placeholder: listings, dealers, VIN lookup, facets, usage, pagination, models
|
|
28
|
+
|
|
29
|
+
- type: textarea
|
|
30
|
+
id: proposed-api
|
|
31
|
+
attributes:
|
|
32
|
+
label: Proposed SDK API
|
|
33
|
+
description: If you have a preferred Python API shape, sketch it here.
|
|
34
|
+
render: python
|
|
35
|
+
placeholder: |
|
|
36
|
+
with VisorClient() as client:
|
|
37
|
+
result = client.some_method(...)
|
|
38
|
+
|
|
39
|
+
- type: textarea
|
|
40
|
+
id: value
|
|
41
|
+
attributes:
|
|
42
|
+
label: Why is this useful?
|
|
43
|
+
description: Explain the use case or user impact.
|
|
44
|
+
validations:
|
|
45
|
+
required: true
|
|
46
|
+
|
|
47
|
+
- type: textarea
|
|
48
|
+
id: alternatives
|
|
49
|
+
attributes:
|
|
50
|
+
label: Alternatives considered
|
|
51
|
+
description: Any workaround or different API shape you considered.
|
|
52
|
+
|
|
53
|
+
- type: textarea
|
|
54
|
+
id: context
|
|
55
|
+
attributes:
|
|
56
|
+
label: Additional context
|
|
57
|
+
description: Links, examples, or redacted response shapes that may help.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: "pip"
|
|
4
|
+
directory: "/"
|
|
5
|
+
schedule:
|
|
6
|
+
interval: "weekly"
|
|
7
|
+
day: "monday"
|
|
8
|
+
time: "09:00"
|
|
9
|
+
timezone: "America/Chicago"
|
|
10
|
+
open-pull-requests-limit: 5
|
|
11
|
+
groups:
|
|
12
|
+
python-dev-dependencies:
|
|
13
|
+
dependency-type: "development"
|
|
14
|
+
update-types:
|
|
15
|
+
- "minor"
|
|
16
|
+
- "patch"
|
|
17
|
+
python-runtime-dependencies:
|
|
18
|
+
dependency-type: "production"
|
|
19
|
+
update-types:
|
|
20
|
+
- "minor"
|
|
21
|
+
- "patch"
|
|
22
|
+
|
|
23
|
+
- package-ecosystem: "github-actions"
|
|
24
|
+
directory: "/"
|
|
25
|
+
schedule:
|
|
26
|
+
interval: "weekly"
|
|
27
|
+
day: "monday"
|
|
28
|
+
time: "09:15"
|
|
29
|
+
timezone: "America/Chicago"
|
|
30
|
+
open-pull-requests-limit: 5
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
pull_request:
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
lint:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v6
|
|
12
|
+
|
|
13
|
+
- uses: actions/setup-python@v6
|
|
14
|
+
with:
|
|
15
|
+
python-version: "3.10"
|
|
16
|
+
|
|
17
|
+
- name: Install dependencies
|
|
18
|
+
run: pip install -e ".[dev]"
|
|
19
|
+
|
|
20
|
+
- name: ruff check
|
|
21
|
+
run: ruff check .
|
|
22
|
+
|
|
23
|
+
- name: ruff format --check
|
|
24
|
+
run: ruff format --check .
|
|
25
|
+
|
|
26
|
+
- name: mypy
|
|
27
|
+
run: mypy src
|
|
28
|
+
|
|
29
|
+
test:
|
|
30
|
+
runs-on: ubuntu-latest
|
|
31
|
+
strategy:
|
|
32
|
+
matrix:
|
|
33
|
+
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
34
|
+
steps:
|
|
35
|
+
- uses: actions/checkout@v6
|
|
36
|
+
|
|
37
|
+
- uses: actions/setup-python@v6
|
|
38
|
+
with:
|
|
39
|
+
python-version: ${{ matrix.python-version }}
|
|
40
|
+
|
|
41
|
+
- name: Install dependencies
|
|
42
|
+
run: pip install -e ".[dev]"
|
|
43
|
+
|
|
44
|
+
- name: pytest
|
|
45
|
+
run: pytest --cov=visor --cov-report=term-missing
|
|
46
|
+
|
|
47
|
+
build:
|
|
48
|
+
runs-on: ubuntu-latest
|
|
49
|
+
steps:
|
|
50
|
+
- uses: actions/checkout@v6
|
|
51
|
+
|
|
52
|
+
- uses: actions/setup-python@v6
|
|
53
|
+
with:
|
|
54
|
+
python-version: "3.12"
|
|
55
|
+
|
|
56
|
+
- name: Install build tools
|
|
57
|
+
run: pip install build twine
|
|
58
|
+
|
|
59
|
+
- name: Build
|
|
60
|
+
run: python -m build
|
|
61
|
+
|
|
62
|
+
- name: Check dist
|
|
63
|
+
run: python -m twine check dist/*
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
inputs:
|
|
6
|
+
target:
|
|
7
|
+
description: "Package index to publish to"
|
|
8
|
+
required: true
|
|
9
|
+
default: "testpypi"
|
|
10
|
+
type: choice
|
|
11
|
+
options:
|
|
12
|
+
- testpypi
|
|
13
|
+
- pypi
|
|
14
|
+
push:
|
|
15
|
+
tags:
|
|
16
|
+
- "v*"
|
|
17
|
+
|
|
18
|
+
permissions:
|
|
19
|
+
contents: read
|
|
20
|
+
|
|
21
|
+
jobs:
|
|
22
|
+
build:
|
|
23
|
+
name: Build distribution
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
steps:
|
|
26
|
+
- uses: actions/checkout@v6
|
|
27
|
+
|
|
28
|
+
- uses: actions/setup-python@v6
|
|
29
|
+
with:
|
|
30
|
+
python-version: "3.12"
|
|
31
|
+
|
|
32
|
+
- name: Install build tools
|
|
33
|
+
run: python -m pip install --upgrade build twine
|
|
34
|
+
|
|
35
|
+
- name: Build
|
|
36
|
+
run: python -m build
|
|
37
|
+
|
|
38
|
+
- name: Check distributions
|
|
39
|
+
run: python -m twine check dist/*
|
|
40
|
+
|
|
41
|
+
- name: Upload distributions
|
|
42
|
+
uses: actions/upload-artifact@v7
|
|
43
|
+
with:
|
|
44
|
+
name: python-package-distributions
|
|
45
|
+
path: dist/
|
|
46
|
+
|
|
47
|
+
publish-testpypi:
|
|
48
|
+
name: Publish to TestPyPI
|
|
49
|
+
needs: build
|
|
50
|
+
runs-on: ubuntu-latest
|
|
51
|
+
environment: testpypi
|
|
52
|
+
permissions:
|
|
53
|
+
contents: read
|
|
54
|
+
id-token: write
|
|
55
|
+
if: github.event_name == 'workflow_dispatch' && github.event.inputs.target == 'testpypi'
|
|
56
|
+
steps:
|
|
57
|
+
- name: Download distributions
|
|
58
|
+
uses: actions/download-artifact@v8
|
|
59
|
+
with:
|
|
60
|
+
name: python-package-distributions
|
|
61
|
+
path: dist/
|
|
62
|
+
|
|
63
|
+
- name: Publish to TestPyPI
|
|
64
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
65
|
+
with:
|
|
66
|
+
repository-url: https://test.pypi.org/legacy/
|
|
67
|
+
|
|
68
|
+
publish-pypi:
|
|
69
|
+
name: Publish to PyPI
|
|
70
|
+
needs: build
|
|
71
|
+
runs-on: ubuntu-latest
|
|
72
|
+
environment: pypi
|
|
73
|
+
permissions:
|
|
74
|
+
contents: read
|
|
75
|
+
id-token: write
|
|
76
|
+
if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.target == 'pypi')
|
|
77
|
+
steps:
|
|
78
|
+
- name: Download distributions
|
|
79
|
+
uses: actions/download-artifact@v8
|
|
80
|
+
with:
|
|
81
|
+
name: python-package-distributions
|
|
82
|
+
path: dist/
|
|
83
|
+
|
|
84
|
+
- name: Publish to PyPI
|
|
85
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Python caches
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.pyo
|
|
5
|
+
|
|
6
|
+
# Virtual environments
|
|
7
|
+
.venv/
|
|
8
|
+
venv/
|
|
9
|
+
env/
|
|
10
|
+
|
|
11
|
+
# Test / lint / type caches
|
|
12
|
+
.pytest_cache/
|
|
13
|
+
.ruff_cache/
|
|
14
|
+
.mypy_cache/
|
|
15
|
+
.coverage
|
|
16
|
+
coverage.xml
|
|
17
|
+
htmlcov/
|
|
18
|
+
|
|
19
|
+
# Build artifacts
|
|
20
|
+
dist/
|
|
21
|
+
build/
|
|
22
|
+
*.egg-info/
|
|
23
|
+
|
|
24
|
+
# Claude
|
|
25
|
+
.claude/
|
|
26
|
+
CLAUDE.md
|
|
27
|
+
|
|
28
|
+
# Docs (local reference material)
|
|
29
|
+
Design Docs/
|
|
30
|
+
Visor API docs/
|
|
31
|
+
|
|
32
|
+
# Graphify knowledge graph outputs
|
|
33
|
+
graphify-out/
|
|
34
|
+
|
|
35
|
+
# Environment variables
|
|
36
|
+
.env
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: local
|
|
3
|
+
hooks:
|
|
4
|
+
- id: ruff-check
|
|
5
|
+
name: ruff check
|
|
6
|
+
entry: ruff check .
|
|
7
|
+
language: system
|
|
8
|
+
pass_filenames: false
|
|
9
|
+
|
|
10
|
+
- id: ruff-format-check
|
|
11
|
+
name: ruff format --check
|
|
12
|
+
entry: ruff format --check .
|
|
13
|
+
language: system
|
|
14
|
+
pass_filenames: false
|
|
15
|
+
|
|
16
|
+
- id: mypy
|
|
17
|
+
name: mypy
|
|
18
|
+
entry: mypy src
|
|
19
|
+
language: system
|
|
20
|
+
pass_filenames: false
|
|
21
|
+
|
|
22
|
+
- id: pytest
|
|
23
|
+
name: pytest
|
|
24
|
+
entry: pytest
|
|
25
|
+
language: system
|
|
26
|
+
pass_filenames: false
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.1.0] - 2026-06-13
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Initial package scaffold: exceptions, filter models, response models
|
|
15
|
+
- `visor.exceptions` — typed exception hierarchy
|
|
16
|
+
- `visor.models._base` — shared building blocks and `ListingsFilterBase`
|
|
17
|
+
- `visor.models.listings` — `ListingsFilter` and listing response models
|
|
18
|
+
- `visor.models.facets` — `FacetsFilter` and facet response models
|
|
19
|
+
- `AsyncVisorClient` — async HTTP client with context-manager support
|
|
20
|
+
- `VisorClient` — synchronous HTTP client with context-manager support
|
|
21
|
+
- Auto-pagination helpers: `paginate_listings`, `paginate_dealers` (async generators),
|
|
22
|
+
`iter_listings`, `iter_dealers` (sync iterators)
|
|
23
|
+
- Public export audit and test suite (`tests/test_exports.py`)
|
|
24
|
+
- `src/visor/py.typed` PEP 561 marker for typed-package distribution
|
|
25
|
+
- Publish-grade `pyproject.toml` metadata: authors, classifiers, keywords, license files, URLs
|
|
26
|
+
- CI matrix across Python 3.10–3.13 with separate lint, test, and build jobs
|
|
27
|
+
|
|
28
|
+
[Unreleased]: https://github.com/whitewalls86/visor-python/compare/v0.1.0...HEAD
|
|
29
|
+
[0.1.0]: https://github.com/whitewalls86/visor-python/releases/tag/v0.1.0
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Code of Conduct
|
|
2
|
+
|
|
3
|
+
## Our Pledge
|
|
4
|
+
|
|
5
|
+
We want visor-python to be a welcoming, useful project for people building with
|
|
6
|
+
the Visor Public API. Everyone participating in this project is expected to help
|
|
7
|
+
keep the community respectful, inclusive, and focused on constructive work.
|
|
8
|
+
|
|
9
|
+
## Expected Behavior
|
|
10
|
+
|
|
11
|
+
Examples of behavior that helps this community:
|
|
12
|
+
|
|
13
|
+
- Be respectful of different experience levels, backgrounds, and viewpoints.
|
|
14
|
+
- Give and receive technical feedback with patience and specificity.
|
|
15
|
+
- Assume good intent, while being willing to clarify and correct mistakes.
|
|
16
|
+
- Keep discussions relevant to the project and its users.
|
|
17
|
+
- Respect maintainers' time by using clear bug reports, examples, and context.
|
|
18
|
+
|
|
19
|
+
## Unacceptable Behavior
|
|
20
|
+
|
|
21
|
+
Examples of behavior that is not acceptable:
|
|
22
|
+
|
|
23
|
+
- Harassment, intimidation, personal attacks, or discriminatory language.
|
|
24
|
+
- Sexualized language or imagery in project spaces.
|
|
25
|
+
- Trolling, sustained disruption, or deliberately derailing discussions.
|
|
26
|
+
- Publishing private information without explicit permission.
|
|
27
|
+
- Any conduct that would reasonably make participation unsafe or unwelcome.
|
|
28
|
+
|
|
29
|
+
## Scope
|
|
30
|
+
|
|
31
|
+
This Code of Conduct applies in project spaces, including GitHub issues, pull
|
|
32
|
+
requests, discussions, documentation, and any other public or private space used
|
|
33
|
+
for project work. It also applies when someone represents the project in public.
|
|
34
|
+
|
|
35
|
+
## Reporting
|
|
36
|
+
|
|
37
|
+
If you experience or witness unacceptable behavior, contact the maintainer at
|
|
38
|
+
miller.andrew.preston@gmail.com. Reports will be handled as respectfully and
|
|
39
|
+
privately as possible.
|
|
40
|
+
|
|
41
|
+
Please include:
|
|
42
|
+
|
|
43
|
+
- What happened and where.
|
|
44
|
+
- Any relevant links, screenshots, or context.
|
|
45
|
+
- Whether immediate action is needed to keep someone safe.
|
|
46
|
+
|
|
47
|
+
## Enforcement
|
|
48
|
+
|
|
49
|
+
Maintainers may take any action they judge appropriate to protect the community,
|
|
50
|
+
including warnings, removing comments, closing issues or pull requests,
|
|
51
|
+
temporary bans, or permanent bans from project spaces.
|
|
52
|
+
|
|
53
|
+
Enforcement decisions should be guided by impact, context, and the goal of
|
|
54
|
+
keeping the project healthy and safe for contributors and users.
|
|
55
|
+
|
|
56
|
+
## Attribution
|
|
57
|
+
|
|
58
|
+
This Code of Conduct is adapted from common open source community standards,
|
|
59
|
+
including the Contributor Covenant.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Contributions are welcome. Please open an issue before starting significant work
|
|
4
|
+
so we can discuss the approach.
|
|
5
|
+
|
|
6
|
+
## Setup
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
git clone https://github.com/whitewalls86/visor-python
|
|
10
|
+
cd visor-python
|
|
11
|
+
pip install -e ".[dev]"
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Running checks
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pytest
|
|
18
|
+
ruff check src/ tests/
|
|
19
|
+
ruff format src/ tests/
|
|
20
|
+
mypy src/
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Pull requests
|
|
24
|
+
|
|
25
|
+
- Keep PRs focused — one logical change per PR.
|
|
26
|
+
- All tests must pass and mypy must be clean before merging.
|
|
27
|
+
- Add a `CHANGELOG.md` entry under `[Unreleased]`.
|
|
28
|
+
|
|
29
|
+
## Versioning and releases
|
|
30
|
+
|
|
31
|
+
This package follows [Semantic Versioning](https://semver.org/) and
|
|
32
|
+
[PEP 440](https://peps.python.org/pep-0440/) version strings.
|
|
33
|
+
|
|
34
|
+
- The package is pre-1.0 (`0.x`). Minor version bumps may include breaking changes.
|
|
35
|
+
- Release tags use a `v` prefix — e.g. `v0.1.0`, `v0.2.0`.
|
|
36
|
+
- After `v1.0.0`, breaking changes require a major version bump.
|
|
37
|
+
- Version is set in `pyproject.toml`. Do not version-bump in a feature PR;
|
|
38
|
+
maintainers handle releases separately.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 visor-python contributors
|
|
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.
|