{"id":24941910,"url":"https://github.com/ravencentric/rnzb","last_synced_at":"2025-04-10T03:44:05.458Z","repository":{"id":273610266,"uuid":"920281005","full_name":"Ravencentric/rnzb","owner":"Ravencentric","description":"Python bindings to the nzb-rs library - a spec compliant parser for NZB files, written in Rust.","archived":false,"fork":false,"pushed_at":"2025-03-31T10:11:56.000Z","size":195,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-31T11:23:55.780Z","etag":null,"topics":["nzb","parser","python","rust","usenet"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Ravencentric.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-01-21T21:49:47.000Z","updated_at":"2025-03-31T10:11:57.000Z","dependencies_parsed_at":"2025-03-02T19:25:55.245Z","dependency_job_id":"e15a9b58-389f-4f90-92e4-a8032439917c","html_url":"https://github.com/Ravencentric/rnzb","commit_stats":null,"previous_names":["ravencentric/rnzb"],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ravencentric%2Frnzb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ravencentric%2Frnzb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ravencentric%2Frnzb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ravencentric%2Frnzb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Ravencentric","download_url":"https://codeload.github.com/Ravencentric/rnzb/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248154967,"owners_count":21056541,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["nzb","parser","python","rust","usenet"],"created_at":"2025-02-02T18:57:18.096Z","updated_at":"2025-04-10T03:44:05.446Z","avatar_url":"https://github.com/Ravencentric.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# rnzb\n\n[![Tests](https://img.shields.io/github/actions/workflow/status/Ravencentric/rnzb/tests.yml?label=tests)](https://github.com/Ravencentric/rnzb/actions/workflows/tests.yml)\n[![Build](https://img.shields.io/github/actions/workflow/status/Ravencentric/rnzb/release.yml?label=build)](https://github.com/Ravencentric/rnzb/actions/workflows/release.yml)\n![PyPI - Types](https://img.shields.io/pypi/types/rnzb)\n![License](https://img.shields.io/pypi/l/rnzb?color=success)\n\n[![PyPI - Latest Version](https://img.shields.io/pypi/v/rnzb?color=blue)](https://pypi.org/project/rnzb)\n![PyPI - Python Version](https://img.shields.io/pypi/pyversions/rnzb)\n![PyPI - Implementation](https://img.shields.io/pypi/implementation/rnzb)\n\nPython bindings to the [nzb-rs](https://crates.io/crates/nzb-rs) library - a [spec](https://sabnzbd.org/wiki/extra/nzb-spec) compliant parser for [NZB](https://en.wikipedia.org/wiki/NZB) files, written in Rust.\n\n## Table Of Contents\n\n- [About](#about)\n- [Installation](#installation)\n- [Related projects](#related-projects)\n- [Performance](#performance)\n- [Supported platforms](#supported-platforms)\n- [Building from source](#building-from-source)\n- [License](#license)\n- [Contributing](#contributing)\n\n## About\n\n`rnzb.Nzb` is a drop-in replacement for [`nzb.Nzb`](https://nzb.ravencentric.cc/api-reference/parser/#nzb.Nzb).\n\nFor documentation and usage examples, refer to the [`nzb`](https://pypi.org/project/nzb) library's resources:\n\n- [Tutorial](https://nzb.ravencentric.cc/tutorial/)\n- [API Reference](https://nzb.ravencentric.cc/api-reference/parser/)\n\n### Error handling\n\n- `rnzb` uses the same error type (`rnzb.InvalidNzbError`) as `nzb` but it's not a drop-in replacement.\n- Error messages will be largely similar to `nzb`'s, though not guaranteed to be identical in every case.\n- `rnzb.InvalidNzbError` is a simpler exception (See [PyO3/pyo3#295](https://github.com/PyO3/pyo3/issues/295) for why). Its implementation is effectively:\n  \n  ```python\n  class InvalidNzbError(Exception): pass\n  ```\n  \n  This means that it's lacking custom attributes like `.message` found in `nzb`'s version. Code relying on such attributes on `nzb.InvalidNzbError` will require adjustment. Consider using the standard exception message (`str(e)`) to achieve the same result.\n\n- `rnzb` will *only ever* raise explicitly documented errors for each function. Undocumented errors should be reported as bugs.\n\n## Installation\n\n`rnzb` is available on [PyPI](https://pypi.org/project/rnzb/), so you can simply use pip to install it.\n\n```bash\npip install rnzb\n```\n\n## Related projects\n\nConsidering this is the fourth library for parsing a file format that almost nobody cares about and lacks a formal specification, here's an overview to help you decide:\n\n| Project                                                  | Description                 | Parser | Meta Editor |\n| -------------------------------------------------------- | --------------------------- | ------ | ----------- |\n| [`nzb`](https://pypi.org/project/nzb)                    | Original Python Library     | ✅     | ✅          |\n| [`nzb-rs`](https://crates.io/crates/nzb-rs)              | Rust port of `nzb`          | ✅     | ❌          |\n| [`rnzb`](https://pypi.org/project/nzb)                   | Python bindings to `nzb-rs` | ✅     | ❌          |\n| [`nzb-parser`](https://www.npmjs.com/package/nzb-parser) | Javascript port of `nzb`    | ✅     | ❌          |\n\n## Performance\n\nAlthough [`nzb`](https://pypi.org/project/nzb) is already quite fast due to its use of the C-based [expat](https://docs.python.org/3/library/pyexpat.html) parser from Python's standard library, `rnzb` offers even better performance, being approximately 5 times faster than `nzb`.\n\n```console\n$ hyperfine --warmup 1 \"python test_nzb.py\" \"python test_rnzb.py\"\nBenchmark 1: python test_nzb.py\n  Time (mean ± σ):      3.848 s ±  0.023 s    [User: 3.561 s, System: 0.248 s]\n  Range (min … max):    3.816 s …  3.885 s    10 runs\n\nBenchmark 2: python test_rnzb.py\n  Time (mean ± σ):     756.4 ms ±   3.5 ms    [User: 595.3 ms, System: 149.7 ms]\n  Range (min … max):   749.0 ms … 761.8 ms    10 runs\n\nSummary\n  python test_rnzb.py ran\n    5.09 ± 0.04 times faster than python test_nzb.py\n```\n\nThe above benchmark was performed by looping over 10 random NZB files I had lying around, with the following code:\n\n```console\n$ cat test_nzb.py\nfrom pathlib import Path\nfrom nzb import Nzb\n\nfor p in Path.cwd().glob(\"*.nzb\"):\n    Nzb.from_file(p)\n\n$ cat test_rnzb.py\nfrom pathlib import Path\nfrom rnzb import Nzb\n\nfor p in Path.cwd().glob(\"*.nzb\"):\n    Nzb.from_file(p)\n```\n\nThis benchmark isn't super scientific, but it gives a pretty good idea of the performance difference.\n\n## Supported platforms\n\nRefer to the following table for the platforms and Python versions for which `rnzb` publishes prebuilt wheels:\n\n| Platform                            | CPython 3.9-3.13 | CPython 3.13 (t) | PyPy 3.9-3.10 |\n| ----------------------------------- | ---------------- | ---------------- | ------------- |\n| 🐧 Linux (`x86_64`, `glibc\u003e=2.28`)  | ✅               | ✅               | ✅            |\n| 🐧 Linux (`x86_64`, `musl\u003e=1.2`)    | ✅               | ✅               | ✅            |\n| 🐧 Linux (`aarch64`, `glibc\u003e=2.28`) | ✅               | ✅               | ✅            |\n| 🐧 Linux (`aarch64`, `musl\u003e=1.2`)   | ✅               | ✅               | ✅            |\n| 🪟 Windows (`x86_64`)               | ✅               | ✅               | ✅            |\n| 🍏 macOS (`x86_64`)                 | ✅               | ✅               | ✅            |\n| 🍏 macOS (`arm64`)                  | ✅               | ✅               | ✅            |\n\nThe library itself is not inherently tied to any specific platform or Python version. The available wheels are based on what can be (reasonably) built using GitHub Actions.\n\n## Building from source\n\nBuilding from source requires the [Rust toolchain](https://rustup.rs/) and [Python 3.9+](https://www.python.org/downloads/).\n\n- With [`uv`](https://docs.astral.sh/uv/):\n\n  ```bash\n  git clone https://github.com/Ravencentric/rnzb\n  cd rnzb\n  uv build\n  ```\n\n- With [`pypa/build`](https://github.com/pypa/build):\n\n  ```bash\n  git clone https://github.com/Ravencentric/rnzb\n  cd rnzb\n  python -m build\n  ```\n\n## License\n\nLicensed under either of:\n\n- Apache License, Version 2.0 ([LICENSE-APACHE](https://github.com/Ravencentric/rnzb/blob/main/LICENSE-APACHE) or \u003chttps://www.apache.org/licenses/LICENSE-2.0\u003e)\n- MIT license ([LICENSE-MIT](https://github.com/Ravencentric/rnzb/blob/main/LICENSE-MIT) or \u003chttps://opensource.org/licenses/MIT\u003e)\n\nat your option.\n\n## Contributing\n\nContributions are welcome! Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fravencentric%2Frnzb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fravencentric%2Frnzb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fravencentric%2Frnzb/lists"}