qBitrr parity: contributor reference¶
Internal notes for maintainers and contributors comparing Torrentarr to upstream qBitrr. End users: see overview.md instead. Row-level status: full-parity-matrix.md.
Upstream qBitrr baseline¶
Torrentarr parity work is diffed against a pinned upstream ref so behavior does not float with every master commit.
Pinned release¶
| Field | Value |
|---|---|
| Branch | 5.12.3 |
| Role | Default behavioral baseline for policy (arss.py), SortTorrents, Arr catalog views/rollups, UrlBase, subcategory paths, and WebUI/OpenAPI at that line. |
| Commit | 0b4a1119e1c59e664c6bb8654d6e206a81d8db52 (merge of master into 5.12.3, 2026-06-03). Re-verify with git ls-remote https://github.com/Feramance/qBitrr refs/heads/5.12.3 when bumping the pin. |
| Shipped tag baseline | v5.12.2 — use branch tip for unreleased 5.12.3 fixes (Lidarr search timer, UrlBase). |
To move the pin: update this section, re-run the inventories below, and adjust full-parity-matrix.md / tests as needed.
Upstream file inventory (compare surface)¶
| Area | Upstream path (Feramance/qBitrr) |
|---|---|
| Config model | qBitrr/config.py, qBitrr/gen_config.py, qBitrr/config_version.py, qBitrr/env_config.py |
| Durations | qBitrr/duration_config.py |
| DB schema | qBitrr/tables.py, qBitrr/database.py, qBitrr/db_lock.py, qBitrr/db_recovery.py |
| Core loop + policy | qBitrr/arss.py |
| Seeding / trackers | qBitrr/qbit_category_manager.py, qBitrr/arr_tracker_index.py |
| Web + API | qBitrr/webui.py |
| OpenAPI (if present on tag) | qBitrr/openapi.json |
| Config example | config.example.toml |
| Public API doc | docs/webui/api.md |
| Operator scripts | scripts/repair_database.py, scripts/repair_database_targeted.py |
Browse branch: 5.12.3 on GitHub. Raw prefix: https://raw.githubusercontent.com/Feramance/qBitrr/5.12.3/
Torrentarr mapping (where to look)¶
| Upstream | Torrentarr (primary) |
|---|---|
config*.py | ConfigurationLoader.cs, TorrentarrConfig.cs |
arss.py / policy | TorrentPolicyHelper.cs, Host Program.cs, TorrentProcessor.cs |
webui.py | WebUI Program.cs, Host Program.cs, webui/ |
tables.py | TorrentarrDbContext.cs, Database/Models/*.cs |
Release validation checklist¶
- Diff
config.example.toml(upstream) vs Torrentarr’s documented config andConfigurationLoaderfor new keys. - Diff route lists: upstream
docs/webui/api.mdandopenapi.jsonvs docs/assets/openapi.json and docs/webui/api.md — use OpenAPI alignment below. - Run:
dotnet test --filter "Category!=Live",npx vitest runinwebui/.
Intentional differences¶
Parity means compatible config, equivalent external behavior (qBittorrent + Arr + SQLite + HTTP API), and documented exceptions. These are by design; they are not bugs.
| Area | qBitrr (Python) | Torrentarr (C#) | Notes |
|---|---|---|---|
| Process model | Single process | Host orchestrates WebUI + per-Arr workers | WebUI stays up if a worker crashes. |
| Runtime / install | Python, pip, setup.py | .NET 10, releases/Docker | setup.py row in matrix: intentional-divergence. |
| Database filename | qbitrr.db (conventional) | torrentarr.db | Same schema intent; name reflects product. |
| Release major version | 5.x | 6.x (+1 major) | AGENTS.md, index.md |
| Migrations | Peewee / Python | EF Core + ConfigurationLoader | Preserve TOML + DB upgrade stories. |
| Logging | Python logging | Serilog | Parity goal for events; format differs. |
| CI automations | e.g. .github/autofix | See Support scripts and CI | No user feature required to match. |
If you find a difference not listed, open an issue or add a matrix row with status intentional-divergence and evidence.
Targeted database repair¶
Upstream may ship repair_database_targeted.py. Torrentarr does not port that script.
- Stop all processes using the DB.
- Use Host
--repair-databaseandDatabaseHealthService— database troubleshooting. - For isolated bad rows: backup
torrentarr.db, thensqlite3withPRAGMA foreign_key_check;and targetedDELETE/UPDATEas appropriate. PRAGMA integrity_check;, then start Torrentarr.
Matrix: repair_database_targeted.py = intentional-divergence. Tests: DatabaseHealthServiceTests.cs.
Policy engine test matrix¶
Maps upstream concepts to CI tests; live qBittorrent still needed for full ordering proof.
Unit / integration (CI)¶
| Concern | qBitrr | Torrentarr | Tests |
|---|---|---|---|
SortTorrents gating | global_sort_torrents_enabled | TorrentPolicyHelper | TorrentPolicyHelperTests.cs |
| Queue position sort | _torrent_queue_position_sort_key | TorrentQueuePositionSortKey | same |
| Queue seeding for sort | is_queue_seeding_for_sort | IsQueueSeedingForSort | same |
| Monitored policy categories | Union | IsMonitoredPolicyCategory / cache | same |
| Free space gate | + AutoPause + qBit | EnableFreeSpace | same |
| Tracker merge (priority) | merge_global_tracker_tag_to_priority_max | MergeGlobalTrackerTagToPriorityMax | same |
| State machine | _process_single_torrent | TorrentProcessor | TorrentProcessorTests.cs |
| Seeding / HnR | qbit_category_manager | SeedingService | SeedingServiceTrackerMergeTests.cs |
Live (Category=Live) — optional¶
| Scenario | Goal |
|---|---|
SortTorrents on, multiple trackers | Queue / topPrio vs tracker priority — Host Program.cs |
Free space + AutoPauseResume | FreeSpaceService |
Multi qBit-* | Per-instance QBitInstanceName |
dotnet test --filter "Category=Live" with real config.
Web and API field coverage¶
Compare to upstream on the pinned tag for behavior-affecting API/UI only (not layout).
- Routes: WebUI
Program.cs+ Host vswebui.pyand upstream API. - OpenAPI: docs/assets/openapi.json vs upstream
qBitrr/openapi.json— OpenAPI alignment. - React: Config (all TOML keys, including
SortTorrentson trackers), Processes, Logs, Auth — docs/webui/api.md.
Long-tail module mapping¶
| qBitrr | Role | Torrentarr |
|---|---|---|
pyarr_compat.py | Arr API normalization | ApiClients/Arr/ |
ffprobe.py | Media checks | MediaValidationService.cs |
errors.py | Errors | Exception types + HTTP JSON in WebUI |
logger.py | Logging | Serilog in Host/WebUI/Workers |
utils.py | Helpers | Search qBitrr in Infrastructure |
versioning / bundled_data | Version/assets | UpdateService |
home_path.py | Config paths | ConfigurationLoader |
Support scripts and CI¶
| Upstream | Torrentarr |
|---|---|
scripts/repair_database.py | DatabaseHealthService, --repair-database |
repair_database_targeted.py | Targeted database repair — no separate script |
.github/scripts/update_releases.py | Release process + GitHub Actions |
.github/autofix | pre-commit, dotnet format, PR review — no user feature |
setup.py / PyPI | NuGet / releases / Docker — intentional |
OpenAPI alignment¶
Pin: use the Upstream baseline tag when fetching upstream qBitrr/openapi.json.
Torrentarr: docs/assets/openapi.json, Swagger at /swagger. Comparing to upstream is a drift check, not a byte-identical merge.
When changing WebUI DTOs/controllers: diff paths/methods for /web/*, /api/*, auth, health.
Optional diff:
curl -sL "https://raw.githubusercontent.com/Feramance/qBitrr/v5.11.1/qBitrr/openapi.json" -o /tmp/qbitrr-openapi.json
# diff with docs/assets/openapi.json (format JSON first for meaningful output)
Reference: docs/webui/api.md, contract-baseline.md section 4.