pybgpkit-parser 0.6.1__tar.gz → 0.7.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.
- pybgpkit_parser-0.7.0/.github/workflows/release.yml +102 -0
- pybgpkit_parser-0.7.0/.github/workflows/rust.yaml +36 -0
- {pybgpkit_parser-0.6.1 → pybgpkit_parser-0.7.0}/.gitignore +4 -0
- pybgpkit_parser-0.7.0/AGENTS.md +83 -0
- pybgpkit_parser-0.7.0/BUILD.md +66 -0
- pybgpkit_parser-0.7.0/CHANGELOG.md +55 -0
- {pybgpkit_parser-0.6.1 → pybgpkit_parser-0.7.0}/Cargo.lock +805 -807
- {pybgpkit_parser-0.6.1 → pybgpkit_parser-0.7.0}/Cargo.toml +13 -4
- pybgpkit_parser-0.7.0/PKG-INFO +223 -0
- pybgpkit_parser-0.7.0/README.md +205 -0
- pybgpkit_parser-0.7.0/benches/parse_bench.rs +36 -0
- {pybgpkit_parser-0.6.1 → pybgpkit_parser-0.7.0}/examples/filter_count_print.py +3 -2
- pybgpkit_parser-0.7.0/pyproject.toml +22 -0
- pybgpkit_parser-0.7.0/src/lib.rs +1020 -0
- pybgpkit_parser-0.7.0/tests/benchmark.py +153 -0
- pybgpkit_parser-0.7.0/tests/test_api.py +116 -0
- pybgpkit_parser-0.6.1/.github/workflows/release.yml +0 -30
- pybgpkit_parser-0.6.1/.github/workflows/rust.yaml +0 -24
- pybgpkit_parser-0.6.1/BUILD.md +0 -32
- pybgpkit_parser-0.6.1/CHANGELOG.md +0 -25
- pybgpkit_parser-0.6.1/Dockerfile +0 -31
- pybgpkit_parser-0.6.1/PKG-INFO +0 -111
- pybgpkit_parser-0.6.1/README.md +0 -100
- pybgpkit_parser-0.6.1/build.sh +0 -19
- pybgpkit_parser-0.6.1/pyproject.toml +0 -3
- pybgpkit_parser-0.6.1/src/lib.rs +0 -168
- {pybgpkit_parser-0.6.1 → pybgpkit_parser-0.7.0}/LICENSE +0 -0
- {pybgpkit_parser-0.6.1 → pybgpkit_parser-0.7.0}/build.rs +0 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
permissions:
|
|
4
|
+
contents: write
|
|
5
|
+
id-token: write
|
|
6
|
+
|
|
7
|
+
on:
|
|
8
|
+
push:
|
|
9
|
+
tags:
|
|
10
|
+
- "v[0-9]+.[0-9]+.[0-9]+"
|
|
11
|
+
workflow_dispatch:
|
|
12
|
+
inputs:
|
|
13
|
+
publish:
|
|
14
|
+
description: "Publish artifacts to PyPI (manual runs default to build-only)"
|
|
15
|
+
required: true
|
|
16
|
+
type: boolean
|
|
17
|
+
default: false
|
|
18
|
+
|
|
19
|
+
env:
|
|
20
|
+
CARGO_TERM_COLOR: always
|
|
21
|
+
|
|
22
|
+
jobs:
|
|
23
|
+
checks:
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
steps:
|
|
26
|
+
- uses: actions/checkout@v4
|
|
27
|
+
- name: Run format check
|
|
28
|
+
run: cargo fmt --check
|
|
29
|
+
- name: Run clippy
|
|
30
|
+
run: cargo clippy -- -D warnings
|
|
31
|
+
|
|
32
|
+
build-sdist:
|
|
33
|
+
needs: checks
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
steps:
|
|
36
|
+
- uses: actions/checkout@v4
|
|
37
|
+
- uses: PyO3/maturin-action@v1
|
|
38
|
+
with:
|
|
39
|
+
command: sdist
|
|
40
|
+
args: --out dist
|
|
41
|
+
- uses: actions/upload-artifact@v4
|
|
42
|
+
with:
|
|
43
|
+
name: sdist
|
|
44
|
+
path: dist/*.tar.gz
|
|
45
|
+
|
|
46
|
+
build-wheels:
|
|
47
|
+
needs: checks
|
|
48
|
+
runs-on: ${{ matrix.os }}
|
|
49
|
+
strategy:
|
|
50
|
+
fail-fast: false
|
|
51
|
+
matrix:
|
|
52
|
+
include:
|
|
53
|
+
- os: ubuntu-latest
|
|
54
|
+
target: x86_64
|
|
55
|
+
- os: macos-15
|
|
56
|
+
target: x86_64
|
|
57
|
+
- os: macos-latest
|
|
58
|
+
target: aarch64
|
|
59
|
+
- os: windows-latest
|
|
60
|
+
target: x64
|
|
61
|
+
steps:
|
|
62
|
+
- uses: actions/checkout@v4
|
|
63
|
+
- uses: PyO3/maturin-action@v1
|
|
64
|
+
with:
|
|
65
|
+
target: ${{ matrix.target }}
|
|
66
|
+
args: --release --out dist
|
|
67
|
+
- uses: actions/upload-artifact@v4
|
|
68
|
+
with:
|
|
69
|
+
name: wheels-${{ matrix.os }}-${{ matrix.target }}
|
|
70
|
+
path: dist/*.whl
|
|
71
|
+
|
|
72
|
+
publish-pypi:
|
|
73
|
+
needs: [build-sdist, build-wheels]
|
|
74
|
+
runs-on: ubuntu-latest
|
|
75
|
+
if: github.event_name == 'push' || inputs.publish == true
|
|
76
|
+
environment: pypi
|
|
77
|
+
steps:
|
|
78
|
+
- uses: actions/download-artifact@v4
|
|
79
|
+
with:
|
|
80
|
+
path: dist
|
|
81
|
+
merge-multiple: true
|
|
82
|
+
- name: Publish to PyPI
|
|
83
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
84
|
+
with:
|
|
85
|
+
packages-dir: dist
|
|
86
|
+
skip-existing: true
|
|
87
|
+
|
|
88
|
+
create-release:
|
|
89
|
+
needs: [build-sdist, build-wheels, publish-pypi]
|
|
90
|
+
runs-on: ubuntu-latest
|
|
91
|
+
if: github.event_name == 'push'
|
|
92
|
+
steps:
|
|
93
|
+
- uses: actions/checkout@v4
|
|
94
|
+
- uses: actions/download-artifact@v4
|
|
95
|
+
with:
|
|
96
|
+
path: dist
|
|
97
|
+
merge-multiple: true
|
|
98
|
+
- name: Create GitHub Release
|
|
99
|
+
uses: softprops/action-gh-release@v2
|
|
100
|
+
with:
|
|
101
|
+
files: dist/*
|
|
102
|
+
body_path: CHANGELOG.md
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: Rust
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ main ]
|
|
8
|
+
|
|
9
|
+
env:
|
|
10
|
+
CARGO_TERM_COLOR: always
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
rust-checks:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- name: Run format check
|
|
18
|
+
run: cargo fmt --check
|
|
19
|
+
- name: Run clippy
|
|
20
|
+
run: cargo clippy -- -D warnings
|
|
21
|
+
|
|
22
|
+
python-api:
|
|
23
|
+
runs-on: ubuntu-latest
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v4
|
|
26
|
+
- uses: actions/setup-python@v5
|
|
27
|
+
with:
|
|
28
|
+
python-version: "3.11"
|
|
29
|
+
- name: Install test tools
|
|
30
|
+
run: python -m pip install --upgrade pip maturin pytest pytest-benchmark
|
|
31
|
+
- name: Build wheel
|
|
32
|
+
run: maturin build --release --out dist
|
|
33
|
+
- name: Install built wheel
|
|
34
|
+
run: python -m pip install --force-reinstall dist/*.whl
|
|
35
|
+
- name: Run Python API tests (unit)
|
|
36
|
+
run: pytest tests/test_api.py -v
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# PROJECT KNOWLEDGE BASE
|
|
2
|
+
|
|
3
|
+
## OVERVIEW
|
|
4
|
+
|
|
5
|
+
Python binding for `bgpkit-parser` (Rust MRT/BGP parser). Exposes `Parser` (full elems), `RouteParser` (route-level scans), `Filter` helpers, and projected tuple iteration via PyO3, built with maturin.
|
|
6
|
+
|
|
7
|
+
## STRUCTURE
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
├── src/lib.rs # Entire Python extension: Parser/elem/route PyO3 classes
|
|
11
|
+
├── examples/ # Python usage examples
|
|
12
|
+
├── Cargo.toml # Rust crate: pybgpkit-parser, depends on bgpkit-parser
|
|
13
|
+
├── pyproject.toml # Maturin build-system config
|
|
14
|
+
├── build.rs # PyO3 extension module linker setup
|
|
15
|
+
├── benches/ # Rust criterion benchmarks
|
|
16
|
+
├── tests/ # Python API tests and benchmark
|
|
17
|
+
└── .github/workflows/ # Rust fmt/clippy CI + tag-based release
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## WHERE TO LOOK
|
|
21
|
+
|
|
22
|
+
| Task | Location |
|
|
23
|
+
|------|----------|
|
|
24
|
+
| Change exposed Python API | `src/lib.rs` |
|
|
25
|
+
| Update underlying parser logic | `Cargo.toml` → bump `bgpkit-parser` version |
|
|
26
|
+
| Build/test locally | `maturin develop` (see README.md) |
|
|
27
|
+
| Build wheels for release | GitHub Actions `release.yml` (push `v*` tag) |
|
|
28
|
+
| Publish to PyPI | Push `v*` tag; CI publishes via PyPI Trusted Publishing (OIDC) |
|
|
29
|
+
|
|
30
|
+
## CODE MAP
|
|
31
|
+
|
|
32
|
+
- **`Elem`** — PyO3 class wrapping a parsed BGP element. Has `#[pyo3(get, set)]` fields and `to_dict()` / `__str__` / `__getstate__` methods.
|
|
33
|
+
- **`Parser`** — PyO3 class wrapping `bgpkit_parser::BgpkitParser`. Constructor takes `url`, optional `filters` (HashMap), and optional `cache_dir`. Implements `__iter__`/`__next__`, `count`, `iter_batches`, `iter_tuples`, and `iter_tuple_batches`.
|
|
34
|
+
- **`RouteParser`** — PyO3 class wrapping `BgpkitParser::into_route_iter()`. Returns lightweight `RouteElem` values. Same iteration/helper surface as `Parser`.
|
|
35
|
+
- **`Filter`** — PyO3 class wrapping `bgpkit_parser::parser::Filter`. Constructors: `__init__`, `peer_ip`, `peer_ips`, `origin_asn`, `prefix`, `elem_type`.
|
|
36
|
+
- **`TupleIterator` / `TupleBatchIterator`** — High-performance projected tuple iteration for `Parser` and `RouteParser`.
|
|
37
|
+
- **`convert_elem`** — Internal fn mapping `BgpElem` → `Elem` (Rust type → PyO3 type).
|
|
38
|
+
|
|
39
|
+
## CONVENTIONS
|
|
40
|
+
|
|
41
|
+
- Rust fmt/clippy enforced in CI (`cargo fmt --check`, `cargo clippy -- -D warnings`)
|
|
42
|
+
- `PyValueError` used for filter errors propagated to Python
|
|
43
|
+
- Iterator-backed pyclasses use `#[pyclass(unsendable)]`; no `unsafe impl Send/Sync`
|
|
44
|
+
- `#[pyo3(name = "__str__")]` used for JSON string representation of `Elem`
|
|
45
|
+
- `atomic` field returns `"AG"`/`"NAG"` strings (not bool)
|
|
46
|
+
- `elem_type` field returns `"A"` (announce) or `"W"` (withdraw)
|
|
47
|
+
|
|
48
|
+
## ANTI-PATTERNS
|
|
49
|
+
|
|
50
|
+
- **Do NOT** change PyO3/maturin versions without updating both `Cargo.toml` and `build.rs` (`pyo3-build-config` must match)
|
|
51
|
+
- **Do NOT** test release publishing with a beta tag unless the package version is also beta; use `workflow_dispatch` with `publish=false` for build-only checks
|
|
52
|
+
- **Do NOT** add long-lived PyPI API tokens; use PyPI Trusted Publishing with GitHub OIDC (`environment: pypi`)
|
|
53
|
+
- **Do NOT** add `unsafe impl Send/Sync` to `#[pyclass]` types; use `#[pyclass(unsendable)]` instead
|
|
54
|
+
- **Do NOT** use `.unwrap()` on user inputs (URL/filters); already handled in `BgpkitParser::new` but be careful with new additions
|
|
55
|
+
- **Do NOT** make `Elem` fields write-only or remove getters without noting in CHANGELOG as breaking (v0.6.0 was a breaking change)
|
|
56
|
+
|
|
57
|
+
## COMMANDS
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# Local dev build (installs to active venv)
|
|
61
|
+
maturin develop
|
|
62
|
+
|
|
63
|
+
# Build wheel locally
|
|
64
|
+
maturin build --release
|
|
65
|
+
|
|
66
|
+
# Build and publish release via CI
|
|
67
|
+
git tag v0.7.0
|
|
68
|
+
git push origin v0.7.0
|
|
69
|
+
|
|
70
|
+
# Format + lint
|
|
71
|
+
cargo fmt --check
|
|
72
|
+
cargo clippy -- -D warnings
|
|
73
|
+
|
|
74
|
+
# Publish (after building on all platforms)
|
|
75
|
+
twine upload --skip-existing target/wheels/*
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## NOTES
|
|
79
|
+
|
|
80
|
+
- `bgpkit-parser` crate version bump is the primary release trigger (see CHANGELOG for version history)
|
|
81
|
+
- Release workflow: `rust.yaml` runs Rust + Python API checks on PR/push; `release.yml` builds ABI3 wheels and publishes on `v*` tag push via Trusted Publishing
|
|
82
|
+
- Supports Python 3.9+ via ABI3 wheels
|
|
83
|
+
- Python API tests live in `tests/test_api.py`; network smoke coverage is gated by `PYBGPKIT_RUN_NETWORK_TESTS=1`
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Build and Publish Guide
|
|
2
|
+
|
|
3
|
+
## Automated Release (Recommended)
|
|
4
|
+
|
|
5
|
+
Release builds are handled by GitHub Actions via `.github/workflows/release.yml`.
|
|
6
|
+
|
|
7
|
+
Push a version tag to build and publish:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
git tag v0.7.0
|
|
11
|
+
git push origin v0.7.0
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
The release workflow will:
|
|
15
|
+
|
|
16
|
+
1. Run `cargo fmt --check` and `cargo clippy -- -D warnings`
|
|
17
|
+
2. Build the source distribution (`sdist`)
|
|
18
|
+
3. Build ABI3 wheels for:
|
|
19
|
+
- Linux x86_64
|
|
20
|
+
- macOS x86_64
|
|
21
|
+
- macOS arm64
|
|
22
|
+
- Windows x86_64
|
|
23
|
+
4. Publish artifacts to PyPI using PyPI Trusted Publishing (OIDC)
|
|
24
|
+
5. Create a GitHub Release and attach the built artifacts
|
|
25
|
+
|
|
26
|
+
Manual workflow runs (`workflow_dispatch`) are build-only by default. They only publish when the `publish` input is explicitly enabled.
|
|
27
|
+
|
|
28
|
+
## PyPI Trusted Publishing Setup
|
|
29
|
+
|
|
30
|
+
Configure a trusted publisher for the existing `pybgpkit-parser` PyPI project:
|
|
31
|
+
|
|
32
|
+
| Field | Value |
|
|
33
|
+
|------|-------|
|
|
34
|
+
| Owner | `bgpkit` |
|
|
35
|
+
| Repository name | `bgpkit-parser-py` |
|
|
36
|
+
| Workflow name | `release.yml` |
|
|
37
|
+
| Environment name | `pypi` |
|
|
38
|
+
|
|
39
|
+
The workflow uses GitHub Actions OIDC (`id-token: write`) and does not require a long-lived PyPI API token.
|
|
40
|
+
|
|
41
|
+
## Local Development Build
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
maturin develop
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
This builds the extension and installs it into the active Python environment.
|
|
48
|
+
|
|
49
|
+
## Local Wheel Build
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
maturin build --release
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Built wheels are written under `target/wheels/`.
|
|
56
|
+
|
|
57
|
+
## Manual Publish Fallback
|
|
58
|
+
|
|
59
|
+
If CI is unavailable, build locally and upload with `twine`:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
python -m pip install --upgrade maturin twine
|
|
63
|
+
maturin build --release --sdist
|
|
64
|
+
twine upload --skip-existing target/wheels/*
|
|
65
|
+
```
|
|
66
|
+
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## 0.7.0 - 2026-06-09
|
|
6
|
+
|
|
7
|
+
### Highlights
|
|
8
|
+
|
|
9
|
+
* Update `bgpkit-parser` to v0.17.0.
|
|
10
|
+
* Update PyO3 to v0.28 and enable ABI3 wheels for Python 3.9+.
|
|
11
|
+
* Add `peer_bgp_id` and `only_to_customer` fields to `Elem`.
|
|
12
|
+
* Add reusable `Filter` class and `Parser.from_filters(...)` constructor.
|
|
13
|
+
* Add Rust-like `Elem` utility methods: `is_announcement`, `is_withdrawal`, `get_origin_asn`, `get_origin_asns`, `has_as_path`, `as_dict`, `to_json`, `to_psv`, and `get_psv_header`.
|
|
14
|
+
* Add `Elem.origin_asn` property and module constants `ELEM_TYPE_ANNOUNCE`, `ELEM_TYPE_WITHDRAW`, and `PSV_HEADER`.
|
|
15
|
+
* Add Python-native filter helper constructors: `Filter.peer_ip`, `Filter.peer_ips`, `Filter.origin_asn`, `Filter.prefix`, and `Filter.elem_type`.
|
|
16
|
+
* Add stream-consuming `Parser.count()` and `Parser.iter_batches(batch_size)` helpers.
|
|
17
|
+
* Add `RouteElem` and `RouteParser` for upstream route-level parsing (`BgpRouteElem`) and faster route identity scans.
|
|
18
|
+
* Add high-performance projected tuple iteration: `iter_tuples(fields)` and `iter_tuple_batches(fields, batch_size)` for `Parser` and `RouteParser`.
|
|
19
|
+
* Add field presets `BASIC_FIELDS`, `ROUTE_FIELDS`, and `NEXT_HOP_FIELDS`.
|
|
20
|
+
* Optimize `Parser.parse_all()` and batch iteration by parsing while detached from the Python interpreter before converting results into Python objects.
|
|
21
|
+
* Add Rust and Python benchmark scaffolding.
|
|
22
|
+
* Automate wheel builds and PyPI publishing via GitHub Actions.
|
|
23
|
+
|
|
24
|
+
## 0.6.2 - 2025-06-06
|
|
25
|
+
|
|
26
|
+
### Fix regressions
|
|
27
|
+
|
|
28
|
+
* Fix a regression in the `Elem` class that the default string representation was missing
|
|
29
|
+
* Fix a regression that the `Parser` class requires `filters` and `cache_dir` to be passed in the constructor,
|
|
30
|
+
which should be and was optional priority to `v0.6.0`.
|
|
31
|
+
|
|
32
|
+
## 0.6.1 - 2025-06-06
|
|
33
|
+
|
|
34
|
+
### Highlights
|
|
35
|
+
|
|
36
|
+
* Update `bgpkit-parser` to v0.11.1, which includes a fix on parsing for `next_hop` for IPv6 peers.
|
|
37
|
+
|
|
38
|
+
## 0.6.0 - 2025-06-04
|
|
39
|
+
|
|
40
|
+
### Highlights
|
|
41
|
+
|
|
42
|
+
* Update `bgpkit-parser` to v0.11.0, which includes several bug fixes and performance improvements.
|
|
43
|
+
* Add support for Python 3.13.
|
|
44
|
+
|
|
45
|
+
### Breaking changes
|
|
46
|
+
|
|
47
|
+
* The `Elem` class's fields can only be access by their getter methods now. Direct access to fields is no longer
|
|
48
|
+
allowed. This change improves encapsulation and ensures that the internal state of `Elem` is managed correctly.
|
|
49
|
+
|
|
50
|
+
## 0.5.1 - 2024-02-28
|
|
51
|
+
|
|
52
|
+
### Highlights
|
|
53
|
+
|
|
54
|
+
* update `bgpkit-parser` to v0.10.1, which fixes a performance regression introduced in 0.10.0.
|
|
55
|
+
|