docs: fix broken examples, fill gaps, and consolidate contributor guides - #603
Open
ffumero2003 wants to merge 12 commits into
Open
docs: fix broken examples, fill gaps, and consolidate contributor guides#603ffumero2003 wants to merge 12 commits into
ffumero2003 wants to merge 12 commits into
Conversation
Corrects overalapping, manullay, "Streams that contains" and "If all candidates fails" in the Advanced usage patterns guide, and replaces the time-relative "developed for 3 years" claim on the overview page. Closes Backblaze#591 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The Installation Guide told readers to check out the repository and then run "pip install b2sdk", which resolves the published package from PyPI and ignores local changes. Use an editable install of the checkout, and point at the Contributors Guide for the full nox/uv setup. Closes Backblaze#590 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The Sphinx contributor guide advertised a "deploy" nox session that does not exist; releases are published by the Continuous Delivery workflow on a version tag. Both contributor guides also claimed a matrix of 8 Python versions, which no longer matches PYTHON_VERSIONS; describe the matrix by reference so it does not drift again. Closes Backblaze#588 Closes Backblaze#589 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The sync example used a nonexistent EncryptionSettings class, passed id= to EncryptionKey instead of key_id=, and gave BasicSyncEncryptionSettingsProvider one mapping where it requires both read and write mappings. Uploads documented file_infos= instead of file_info=. The file-lock examples also handed a FileRetentionSetting to update_file_legal_hold, which takes a LegalHold; those calls now use update_file_retention. Closes Backblaze#584 Closes Backblaze#585 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The prose referred to LocalUploadSource, which is not exported; the surrounding examples already use UploadSourceLocalFile. One example also called planner.create_file, while every other example in the section calls bucket.create_file. Closes Backblaze#586 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
CONTRIBUTING.md and doc/source/contributing.rst duplicated environment setup, nox sessions, testing and documentation commands, and had already drifted apart. Move the guidance that only existed in the Markdown copy (versioning, changelog fragments, dependency management, keyword-filtered tests) into the Sphinx guide, and reduce CONTRIBUTING.md to a short GitHub-facing entry point that links to it. Closes Backblaze#599 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The repository keeps four numbered interfaces working at once, and the unit suite is what enforces that, but nothing explained how the apiver machinery selects tests. A test could therefore be placed where it covers only one interface even though the changed _internal behaviour is shared. Add a decision table for the shared, per-version, v_all and integration locations, document the apiver marker, and add a checklist for _internal changes. Closes Backblaze#592 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The guide was a single instruction to run make_release_commit and follow its output, leaving the boundaries undocumented: that the session builds the changelog but neither commits nor tags, that CI must be green before tagging because a PyPI version cannot be reused, and that CD creates a GitHub release but publishes to PyPI only when the token is present and the tag is not a prerelease. Document those, plus recovery before and after a tag is pushed. Closes Backblaze#593 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The interface policy described which modules are public but said nothing about the versioned namespace itself, which re-exports far more than the public interface - low-level HTTP classes, simulators, constants, and names leaked by star-imports. State that importability is not a promise, and give the rule for telling public, internal and unclassified names apart. The per-name classification that Backblaze#597 also asks for still needs maintainer review, so this does not close the issue. Refs Backblaze#597 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Replication was fully exposed by the SDK but undocumented, discoverable only by guessing at names. Add a task-oriented guide covering setup via ReplicationSetupHelper and by hand, the application-key capabilities each side needs, per-file replication status, monitoring a rule, and how to read and interpret a scan report. Add reference pages for the public replication classes. Documenting ReplicationMonitor also required indenting the continuation lines of its docstring's parameter list, which docutils otherwise rejects. No executable code is changed. ReplicationReport is described in prose rather than generated, because its inherited annotations cannot be resolved from the subclass's module. Fixing that properly belongs in b2sdk/_internal/scan/scan.py. Closes Backblaze#595 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Five of the six todo directives are addressed: the "delete doc/source/b2sdk?" note is obsolete since that directory no longer exists, raw_simulator already has an autodoc page, the "Why use b2sdk?" list is now consistently phrased and links to the features it mentions, and the progress reporters and exception hierarchy have real documentation rather than a note saying they need some. The remaining directive, in advanced.rst, asks for `prioritize` to accept an enum instead of a string. That is an API design change rather than documentation, so it is left in place until an issue exists to link it to. Refs Backblaze#601 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The last todo directive asked for `prioritize` to accept an enum instead of a string, which is an API design change rather than documentation work. It is now tracked as issue Backblaze#602 and the directive links to it, retained in place so that anyone editing that section sees it next to the documented string values. It stays out of published builds, since the todo directive only renders when B2_SPHINX_TODO is set. Closes Backblaze#601 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Documentation-only work across 13 of the issues filed as #584–#601. Twelve are closed here; one is
partially addressed. 30 files changed, +755/−188, in 12 commits.
The only non-documentation file touched is
b2sdk/_internal/replication/monitoring.py, where fivelines of a docstring were reindented. No executable code changes — see Notes for reviewers.
Closed by this PR
Corrections: documented behavior that was wrong
#584 — Quick Start examples did not run.
doc/source/quick_start.rstused a nonexistentEncryptionSettingsclass (the real name isEncryptionSetting), passedid=toEncryptionKeyinstead of
key_id=, gaveBasicSyncEncryptionSettingsProvidera single mapping when its signaturerequires two (
read_bucket_settingsandwrite_bucket_settings), and documentedfile_infos=whereBucket.upload_local_filetakesfile_info=. Anyone copying the first examples in the guide got aNameErrororTypeErrorimmediately. Note the issue mentions oneEncryptionKey(id=...); therewere two, at lines 57 and 197.
#585 — Retention settings passed to the legal-hold method. Three calls handed a
FileRetentionSettingtoB2Api.update_file_legal_hold, whose signature takes aLegalHold. Two ofthem sat in an "equivalent to" block directly beneath correct
update_retentioncalls, so the guidecontradicted itself. Repointed at
update_file_retention.#586 — Stale names in the Advanced guide. The prose referred to
LocalUploadSource, which is notexported; the surrounding examples already used the correct
UploadSourceLocalFile. Separately, oneexample called
planner.create_file(...)while every other example in that section callsbucket.create_file(...), andplanneris never defined in the documented workflow. Scope note: onlythe prose was wrong, not the code samples, so this is narrower than the issue implies.
#588 — A documented command that does not exist.
contributing.rstadvertised adeploynoxsession for publishing to PyPI.
noxfile.pydefines no such session. Publishing is done by.github/workflows/cd.ymlon a pushed version tag, which is now described instead.#589 — Wrong CI matrix. Both contributor guides claimed "a matrix of 8 versions of Python."
PYTHON_VERSIONSinnoxfile.pylists six interpreters (CPython 3.10–3.14 plus PyPy 3.10). Bothfiles also stated the matrix correctly further down, so each contradicted itself. Replaced the
hard-coded count with a reference to
PYTHON_VERSIONSso it cannot drift again, and corrected"Mac OS X" to "macOS".
#590 — Development install ignored the local checkout. The Installation Guide said to check out
the repository and then run
pip install b2sdk, which resolves the published package from PyPI. Adeveloper testing their own changes would silently test a release instead. Now uses
pip install -e .with an explanation of why, and links to the Contributors Guide for the full nox/uv setup.
#591 — Typos and a stale claim. Fixed
overalapping,manullay, "Streams that contains" and"If all candidates fails" in
advanced.rst. Replaced the front-page claim that the SDK "has beendeveloped for 3 years before it version 1.0.0 was released" — a time-relative statement that had gone
stale, plus an it/its error.
New documentation
#592 — Where a new test belongs. The repository keeps
b2sdk.v0throughv3workingsimultaneously, and
nox -s unitruns the suite once per interface version. Nothing explained howtest/unit/conftest.pyselects tests, so a regression test could land in a single version directorywhile the changed
_internalbehavior is shared by all four. Adds a decision table covering theshared topic directories,
test/unit/v0–v3,v_allandtest/integration; documents the--apioption, the
apiver_depsmechanism and theapivermarker withfrom_ver/to_ver; and adds achecklist for
_internalchanges.#593 — Release runbook.
README.release.mdwas three lines: runmake_release_commitand followthe output. Now documents the clean-worktree requirement, the
X.Y.Zversion format, reviewingchangelog.dfragments, and the commit/CI/tag sequence. Three boundaries were undocumented and arenow called out explicitly: that
make_release_commitbuilds the changelog but neither commits nortags despite its name; that CI must be green before tagging because a PyPI version cannot be reused;
and that CD creates a GitHub release but publishes to PyPI only when
B2_PYPI_PASSWORDis presentand the tag is not a prerelease, so a green CD run is not proof that PyPI was updated. Also covers
recovery before and after a tag is pushed, including that
towncrier builddeletes the fragment files.#595 — Replication was entirely undocumented.
b2sdk.v3exports seven replication classes withimplementation and tests in the repository, but there was no guide and no API reference, so the feature
was discoverable only by guessing at names. Adds
doc/source/replication.rstcovering setup viaReplicationSetupHelperand by hand, the application-key capabilities each side requires, the fourReplicationStatusvalues, monitoring a rule, reading a scan report, and interpreting partial results.Adds four API reference pages under
doc/source/api/replication/.#601 — Embedded TODO directives. Six
todo::directives were invisible in published builds(
todo_include_todosis gated behindB2_SPHINX_TODO) and carried no owner or acceptance criteria.Note the issue's own search pattern misses the uppercase
.. TODO::inadvanced.rst. Resolved as:two obsolete and removed (
delete doc/source/b2sdk?— that directory does not exist;describe raw_simulator in detail— it already has a full autodoc page); one done (the "Why use b2sdk?" list isnow consistently phrased, with eight of ten bullets linking to what they describe); two turned into
real documentation (
api/progress.rstandapi/exception.rst, below); and one, an API design request,split out to #602 with the directive retained and linked.
The progress page now distinguishes the two separate mechanisms — per-transfer listeners versus
SyncReportfor sync — and documents two easily-missed contract details:set_total_bytesmay becalled more than once on retry, and
bytes_completedreceives a running total that can decreasewhen a transfer restarts. The exception page documents how to catch, warns against naming parent
classes because the hierarchy may gain intermediate classes in a compatible release, and covers the
retry advice carried on the errors themselves.
Consolidation
#599 — Two contributor guides had drifted.
CONTRIBUTING.mdanddoc/source/contributing.rstindependently duplicated setup, sessions, testing and documentation commands. The Sphinx page carried
the nonexistent
deploysession; the Markdown file carried dependency, lockfile and changelog guidancethe Sphinx page lacked. Following the issue's preference for "a short GitHub-friendly entry point while
keeping the full published contributor guide discoverable," the unique Markdown content (versioning,
changelog fragments, dependency management, keyword-filtered tests) moved into the Sphinx guide, which
is now canonical, and
CONTRIBUTING.mdis reduced to an entry point that links to it. The_contributors_guidelabel is preserved becauseinstall.rstnow references it.Worth noting the alternative in that issue — generating one file from the other — is not available
without adding
myst-parser, which is not in the Sphinx extensions list. So consolidation was the onlydocumentation-only path.
Partially addressed
#597 — Classifying the
b2sdk.v3exports. The inventory in the issue is accurate: 208non-underscored names, 137 of which appear nowhere in the
.rstsources.annotationsis among them,leaked from
from __future__ import annotations— a concrete example of an accidental re-export.This PR delivers the durable half:
api_types.rstnow states explicitly that being importable from aversioned namespace is not a compatibility promise, and gives the rule for telling names apart —
present in Public API, present in Internal API, or in neither and carrying no promise. The mechanism
already existed (
api_reference.rsthas separate Public and Internal toctrees, andRawSimulatorisalready documented as internal), so this completes an existing scheme rather than inventing one.
Not delivered: the per-name classification of the remaining 137. That requires a maintainer to decide
which are intentionally public, and publishing a guess would be worse than publishing nothing.
Committed as
Refs #597, so the issue stays open.Deliberately not addressed
#587 — SSE-B2 encryption defaults. Blocked, and not only on timing. The issue was written against
an
encryption-defaultsbranch and states that omitting encryption yields SSE-B2. In the change aswritten, that appears to hold in
RawSimulator— whose implicit bucket default moves fromNONEtoSSE_B2_AES— while what is enforced client-side is narrower: that plaintext may not be requestedfor a bucket default or a file write. Whether real B2 returns SSE-B2 for an omitted default is server
behavior the SDK cannot guarantee. Documenting it as a promise could commit the SDK to something it
does not control, so this needs confirming with whoever owns the server-side change first.
Concretely,
doc/source/server_side_encryption.rst:12currently says the argument means relying onbucket defaults "for SSE-B2 and for no encryption," and
doc/source/api/encryption/setting.rst:18-20documentsSSE_NONEas the "commonly used" no-encryptionsetting. Both need revising once the behavior is settled. This PR leaves them untouched rather than
guessing.
#594 — v0–v3 migration matrix. The encryption change spans all four interfaces, so a matrix written
now would ship incomplete and need rewriting. Better done once that lands.
#596 — Event Notifications. Documenting a Private Preview feature requires knowing its current
release status and stability expectations, which is a product question that cannot be answered from the
repository.
#598 — Executing documentation examples in CI. Not documentation work.
sphinx.ext.doctestisabsent from
conf.py, and thedocsession runs plainsphinx-build -b html -T -W, which fails onwarnings but never executes a code block. Closing it means changes to
conf.py,noxfile.pyand CIconfiguration. Worth relabeling so it is not waiting on a documentation pass. It would have caught #584.
#600 — Upstream and fork URLs. Needs an ownership decision before any edit, exactly as the issue
says. Note the release tooling already hardcodes
Backblaze/b2-sdk-pythonasUPSTREAM_REPO_URLinnoxfile.py, so the current setup assumes upstream. Also relevant:pyproject.toml:167-168areTowncrier's
title_formatandissue_format, which control the links in every generated CHANGELOGentry, so that part is release infrastructure rather than documentation.
#602 —
prioritizeshould accept an enum (filed from #601). An API design change, notdocumentation.
Notes for reviewers
The one Python file.
b2sdk/_internal/replication/monitoring.pyhas five docstring linesreindented.
ReplicationMonitor's:param:continuation lines were not indented, so docutils reported"Field list ends without a blank line" as soon as the class was added to the API reference, and the
-Wbuild failed. Comparing the parsed AST with docstrings excluded shows the executable code is identical.
That docstring still refers to
b2sdk.v2types throughout; left alone as out of scope.ReplicationReportis described in prose rather than autodoc. It inheritscounter_by_status: Counterandsamples_by_status_*: dict[..., tuple[FileVersion, ...]]fromCountAndSampleScanReportinscan/scan.py, which imports both names, butsphinx-autodoc-typehintsresolves inherited annotations against the subclass's module, andmonitoring.pyimports neither. Adding those imports fixes the docs build but failsruffwith F401,since the module's own code never references them. Rather than adding two
# noqaimports to satisfy adocumentation tool, the class is documented in prose. The clean fix belongs in
scan/scan.pyand wouldmake the autodoc entry possible; happy to file that separately if wanted.
source_folderanddestination_folderare excluded for the same class of reason — their annotations reference aClassVar, not a type.CONTRIBUTING.mdshrinks by 157 lines. Intentional, per #599. Nothing is lost — the content movedinto the Sphinx guide, and the changelog-fragment requirement is repeated in the entry point because it
is a CI gate contributors hit at PR time.
Changelog fragments are included for each closed issue, plus
+interface-boundary.doc.mdfor the#597 work, which is not named after an issue because it does not close one.
Unrelated observation:
nox -s lintrunsruff formatin write mode and reformats a line innoxfile.pythat this PR does not touch, meaningmasteris not currentlyruff format-clean. Keptout of this PR; may deserve its own issue.
Test plan
nox -s doc— builds clean. The only warning is a missing localgraphvizbinary, which ispre-existing and environmental; verified by building with and without
-Wnox -s towncrier_check— all 12 changelog fragments validnox -s lint— passes(
NonExistentBucket,interpret_b2_error,update_file_retention, the replication classes)todo::directivestays out of the published build but appears under
B2_SPHINX_TODO=1Closes #584
Closes #585
Closes #586
Closes #588
Closes #589
Closes #590
Closes #591
Closes #592
Closes #593
Closes #595
Closes #599
Closes #601