pybgpkit-parser 0.6.2__tar.gz → 0.18.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.
@@ -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
@@ -18,4 +18,6 @@ cache
18
18
 
19
19
  .DS_Store
20
20
 
21
- .pypirc
21
+ .pypirc
22
+ __pycache__/
23
+ *.py[cod]
@@ -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,61 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## v0.18.0 - 2026-07-02
6
+
7
+ ### Highlights
8
+
9
+ * Update `bgpkit-parser` to v0.18.0.
10
+
11
+ ## v0.7.0 - 2026-06-09
12
+
13
+ ### Highlights
14
+
15
+ * Update `bgpkit-parser` to v0.17.0.
16
+ * Update PyO3 to v0.28 and enable ABI3 wheels for Python 3.9+.
17
+ * Add `peer_bgp_id` and `only_to_customer` fields to `Elem`.
18
+ * Add reusable `Filter` class and `Parser.from_filters(...)` constructor.
19
+ * 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`.
20
+ * Add `Elem.origin_asn` property and module constants `ELEM_TYPE_ANNOUNCE`, `ELEM_TYPE_WITHDRAW`, and `PSV_HEADER`.
21
+ * Add Python-native filter helper constructors: `Filter.peer_ip`, `Filter.peer_ips`, `Filter.origin_asn`, `Filter.prefix`, and `Filter.elem_type`.
22
+ * Add stream-consuming `Parser.count()` and `Parser.iter_batches(batch_size)` helpers.
23
+ * Add `RouteElem` and `RouteParser` for upstream route-level parsing (`BgpRouteElem`) and faster route identity scans.
24
+ * Add high-performance projected tuple iteration: `iter_tuples(fields)` and `iter_tuple_batches(fields, batch_size)` for `Parser` and `RouteParser`.
25
+ * Add field presets `BASIC_FIELDS`, `ROUTE_FIELDS`, and `NEXT_HOP_FIELDS`.
26
+ * Optimize `Parser.parse_all()` and batch iteration by parsing while detached from the Python interpreter before converting results into Python objects.
27
+ * Add Rust and Python benchmark scaffolding.
28
+ * Automate wheel builds and PyPI publishing via GitHub Actions.
29
+
30
+ ## 0.6.2 - 2025-06-06
31
+
32
+ ### Fix regressions
33
+
34
+ * Fix a regression in the `Elem` class that the default string representation was missing
35
+ * Fix a regression that the `Parser` class requires `filters` and `cache_dir` to be passed in the constructor,
36
+ which should be and was optional priority to `v0.6.0`.
37
+
38
+ ## 0.6.1 - 2025-06-06
39
+
40
+ ### Highlights
41
+
42
+ * Update `bgpkit-parser` to v0.11.1, which includes a fix on parsing for `next_hop` for IPv6 peers.
43
+
44
+ ## 0.6.0 - 2025-06-04
45
+
46
+ ### Highlights
47
+
48
+ * Update `bgpkit-parser` to v0.11.0, which includes several bug fixes and performance improvements.
49
+ * Add support for Python 3.13.
50
+
51
+ ### Breaking changes
52
+
53
+ * The `Elem` class's fields can only be access by their getter methods now. Direct access to fields is no longer
54
+ allowed. This change improves encapsulation and ensures that the internal state of `Elem` is managed correctly.
55
+
56
+ ## 0.5.1 - 2024-02-28
57
+
58
+ ### Highlights
59
+
60
+ * update `bgpkit-parser` to v0.10.1, which fixes a performance regression introduced in 0.10.0.
61
+