Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .githooks/commit-msg
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
# Install: git config core.hooksPath .githooks

# Use python -m to avoid Windows .exe access issues
exec python -m commitizen check --commit-msg-file "$1"
exec uv run python -m commitizen check --commit-msg-file "$1"
60 changes: 60 additions & 0 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#!/bin/sh
# Run ruff lint and format on staged Python files.
# Install: git config core.hooksPath .githooks

# Get staged .py files (excluding deleted files)
STAGED_PY=$(git diff --cached --name-only --diff-filter=d -- '**/*.py')

if [ -z "$STAGED_PY" ]; then
exit 0
fi

# Check if running in an environment where ruff is available directly
if command -v ruff >/dev/null 2>&1; then
RUFF="ruff"
else
RUFF="uv run ruff"
fi

# Lint with auto-fix
echo "Running ruff check..."
$RUFF check --fix $STAGED_PY
LINT_EXIT=$?

# Format
echo "Running ruff format..."
$RUFF format $STAGED_PY
FORMAT_EXIT=$?

# Re-stage any auto-fixed files
git add $STAGED_PY

# Fail if lint had unfixable errors
if [ $LINT_EXIT -ne 0 ]; then
echo "ruff check found issues that could not be auto-fixed."
exit 1
fi

# Run complexipy to check cognitive complexity
if command -v complexipy >/dev/null 2>&1; then
COMPLEXIPY="complexipy"
else
COMPLEXIPY="uv run complexipy"
fi

# Run complexipy only on staged src/ files (matches pyproject.toml [tool.complexipy] paths)
STAGED_SRC=$(echo "$STAGED_PY" | grep "^src/" || true)

if [ -n "$STAGED_SRC" ]; then
echo "Running complexipy..."
$COMPLEXIPY $STAGED_SRC --max-complexity-allowed 15
COMPLEXITY_EXIT=$?

if [ $COMPLEXITY_EXIT -ne 0 ]; then
echo "complexipy found functions exceeding max cognitive complexity (15)."
exit 1
fi
fi

exit 0

22 changes: 9 additions & 13 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,33 @@
---
name: Bug report
about: Report an issue with libreclient
title: ''
title: 'BUG: [Short description]'
labels: 'bug'
assignees: ''

---

**Describe the bug**
A clear and concise description of what the bug is.
<!-- A clear and concise description of what the bug is. -->

**To Reproduce**
```python
# Minimal code to reproduce the issue
from libreclient import LibreClientSync

client = LibreClientSync(url="...", token="...")
# ...
```

**Expected behavior**
A clear and concise description of what you expected to happen.
<!-- A clear and concise description of what you expected to happen. -->

**Error output**
```
Paste full traceback or error message here
<!-- Paste full traceback or error message here -->
```

**Environment:**
- Python version: [e.g. 3.13]
- libreclient version: [e.g. 0.2.0]
- LibreNMS version: [e.g. 24.12.0]
- OS: [e.g. Ubuntu 24.04]
- Python version:
- libreclient version:
- LibreNMS version:
- OS:

**Additional context**
Add any other context about the problem here.
<!-- Add any other context about the problem here. -->
9 changes: 9 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
blank_issues_enabled: true
contact_links:
- name: LibreNMS API Documentation
url: https://docs.librenms.org/API/
about: Official LibreNMS API reference
- name: LibreNMS Community
url: https://community.librenms.org/
about: LibreNMS community forums for general LibreNMS questions

24 changes: 24 additions & 0 deletions .github/ISSUE_TEMPLATE/documentation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
name: Documentation
about: Report missing, incorrect, or unclear documentation
title: 'DOCS: [Short description]'
labels: 'documentation'
assignees: ''

---

**What needs documentation?**
<!-- Describe what is missing, incorrect, or unclear. -->

**Where?**
<!-- Link to the specific file, section, or page affected.
- e.g. README.md#configuration
- e.g. CONTRIBUTING.md
- e.g. A specific docstring in src/libreclient/routes/devices.py -->

**Suggested improvement**
<!-- Describe what you'd like to see instead, or provide a draft of the content. -->

**Additional context**
<!-- Any other context, screenshots, or references that would help. -->

14 changes: 7 additions & 7 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
---
name: Feature request
about: Suggest an idea for libreclient
title: ''
title: 'FEAT: [Short description]'
labels: 'enhancement'
assignees: ''

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->

**Describe the solution you'd like**
A clear and concise description of what you want to happen.
<!-- A clear and concise description of what you want to happen. -->

**API endpoint(s) involved**
If this relates to a specific LibreNMS API endpoint, link to the relevant docs:
- e.g. https://docs.librenms.org/API/Devices/#get-device
<!-- If this relates to a specific LibreNMS API endpoint, link to the relevant docs:
- e.g. https://docs.librenms.org/API/Devices/#get-device -->

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
<!-- A clear and concise description of any alternative solutions or features you've considered. -->

**Additional context**
Add any other context or screenshots about the feature request here.
<!-- Add any other context or screenshots about the feature request here. -->
25 changes: 25 additions & 0 deletions .github/ISSUE_TEMPLATE/new_route.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
name: New route request
about: Request support for a LibreNMS API endpoint not yet implemented
title: 'ROUTE: [Endpoint name]'
labels: 'enhancement,new-route'
assignees: ''

---

**API endpoint(s)**
<!-- Link to the LibreNMS API docs for the endpoint(s) you'd like supported.
- e.g. https://docs.librenms.org/API/Devices/#get-device -->

**LibreNMS version**
<!-- Which LibreNMS release introduced or includes this endpoint? e.g. 24.12.0 -->

**Which namespace would this belong to?**
<!-- e.g. devices, ports, routing, switching, or a new namespace -->

**Use case**
<!-- Briefly describe why you need this endpoint. -->

**Would you like to contribute this?**
<!-- If you're interested in implementing it yourself, let us know! See CONTRIBUTING.md for the guide on adding a new route. -->

20 changes: 20 additions & 0 deletions .github/ISSUE_TEMPLATE/question.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
name: Question
about: Ask a question about usage or behavior
title: 'Q: [Short question]'
labels: 'question'
assignees: ''

---

**Your question**
<!-- What are you trying to do or understand? -->

**What have you tried?**
<!-- Any code, docs, or approaches you've already looked at. -->

**Environment (if relevant):**
- Python version:
- libreclient version:
- LibreNMS version:

12 changes: 11 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ concurrency:

permissions:
contents: read
security-events: write

jobs:
lint:
Expand Down Expand Up @@ -69,7 +70,16 @@ jobs:
run: uv sync

- name: Run complexipy
run: uv run complexipy .
run: uv run complexipy . --output-format sarif --output complexipy-results.sarif --failed

- name: Upload SARIF results
if: >-
always()
&& hashFiles('complexipy-results.sarif') != ''
&& (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository)
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: complexipy-results.sarif

test:
name: Tests
Expand Down
28 changes: 28 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Documentation
on:
push:
branches:
- main
permissions:
contents: read
pages: write
id-token: write
jobs:
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- uses: actions/configure-pages@v6
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: 3.x
- run: pip install zensical
- run: zensical build --clean
- uses: actions/upload-pages-artifact@v5
with:
path: site
- uses: actions/deploy-pages@v5
id: deployment
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ jobs:
# --- Generate Type Stubs ---
- name: Generate .pyi stubs
if: steps.decide.outputs.skip != 'true'
run: uv run python generate_stubs.py
run: uv run python scripts/generate_stubs.py

# --- Build ---
- name: Build package
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ wheels/
# Virtual environments
.venv

# Auto-generated type stubs (regenerate with: python generate_stubs.py)
# Auto-generated type stubs (regenerate with: python scripts/generate_stubs.py)
src/py_librenms/routes/*.pyi

# Secrets
Expand Down
83 changes: 83 additions & 0 deletions COMMIT_TYPES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Commit Types Reference

This project uses [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/). Every commit message must
follow the format:

```
type(scope)?: description

[optional body]
[optional footer]
```

## Allowed Types

| Type | Description |
|------------|-----------------------------------------------------------------------------|
| `feat` | A new feature or user-facing enhancement |
| `fix` | A bug fix |
| `docs` | Documentation-only changes (README, docstrings, comments) |
| `style` | Code style changes that do not affect logic (formatting, whitespace) |
| `refactor` | Code restructuring that neither fixes a bug nor adds a feature |
| `perf` | Performance improvements |
| `test` | Adding or updating tests (no production code changes) |
| `build` | Changes to the build system or dependencies (pyproject.toml, uv.lock, etc.) |
| `ci` | Changes to CI/CD configuration (GitHub Actions, workflows) |
| `chore` | Routine maintenance tasks that don't modify src or test files |
| `revert` | Reverts a previous commit |
| `bump` | Version bump |

## Examples

```
feat(routing): add OSPFv3 port listing
fix: handle empty response from list_devices
docs: add upstream tracking section to README
test: add functional tests for switching routes
refactor(models): simplify base response inheritance
perf(devices): reduce redundant API calls in list_devices
build: bump pydantic to 2.14.0
ci: add Python 3.13 to test matrix
chore: remove unused test fixtures
style: fix trailing whitespace in routes module
revert: revert "feat(ports): add port graph endpoint"
bump: 0.1.3
```

## Scope (Optional)

The scope provides additional context about what area of the codebase is affected. Common scopes in this project:

| Scope | Usage |
|-----------------|-------------------------------|
| `alerts` | Alert routes or models |
| `arp` | ARP routes or models |
| `bills` | Billing routes or models |
| `devices` | Device routes or models |
| `device_groups` | Device group routes or models |
| `inventory` | Inventory routes or models |
| `locations` | Location routes or models |
| `logs` | Log routes or models |
| `ports` | Port routes or models |
| `port_groups` | Port group routes or models |
| `routing` | Routing routes or models |
| `services` | Service routes or models |
| `switching` | Switching routes or models |
| `system` | System routes or models |
| `models` | Cross-cutting model changes |
| `routes` | Cross-cutting route changes |
| `config` | Configuration changes |
| `client` | Client class changes |

## Validation

Commit messages are validated automatically by a `commit-msg` git hook using
[commitizen](https://commitizen-tools.github.io/commitizen/). If your message doesn't match the format, the commit will
be rejected with an error explaining what went wrong.

**Setup the hook (once per clone):**

```bash
git config core.hooksPath .githooks
```

Loading