Skip to content

docs: add agent-readable documentation and repository metadata - #450

Merged
const-cloudinary merged 3 commits into
masterfrom
docs/agent-readable-documentation
Aug 25, 2026
Merged

docs: add agent-readable documentation and repository metadata#450
const-cloudinary merged 3 commits into
masterfrom
docs/agent-readable-documentation

Conversation

@const-cloudinary

Copy link
Copy Markdown
Member

Brings pycloudinary in line with the agent-readable documentation standard already shipped in cloudinary_npm.

Supersedes #449, which was closed and reopened so review starts from the current state of the branch. All feedback from that review is applied here.

What this adds

  • README.md restructured to the npm section layout (Install, Quick start, Common tasks, When to use this SDK, Status and compatibility, Documentation, For AI coding agents, Support, Security, License).
  • AGENTS.md (6 sections) plus CLAUDE.md@AGENTS.md, matching npm.
  • cloudinary/docs/ — 15 task pages shipped inside the PyPI package, so they are version-matched to the installed release. Wired up via MANIFEST.in and [tool.setuptools.package-data].
  • examples/ — 9 complete runnable scripts, repo-only (excluded from the wheel).
  • SECURITY.md, context7.json, canonical LICENSE at root.

Python-specific deviations from npm

  • Docs live at cloudinary/docs/, not root docs/ — only an in-package directory installs deterministically from a wheel. Maps 1:1 to npm's node_modules/cloudinary/docs/.
  • examples/ is not shipped in the wheel. Loose .py files inside the importable package risk import shadowing. Every doc page carries the complete runnable flow, so the agent read path is intact.
  • One extra page, use-with-django.md, covering CloudinaryField, the form fields, and migrations.

Review feedback applied

Corrections from the #449 review, cross-checked against the equivalent fixes already verified in cloudinary_npm PR #742:

  • Moderation behavior corrected. A pending asset is deliverable by default — the status is metadata to gate on, not an access control. Blocking non-approved assets is configured per product environment by Cloudinary support, not by an upload parameter. Statuses are queued, pending, approved, rejected, aborted (five, not three). This fixed the page intro, the statuses line, a troubleshooting entry that had the behavior inverted, and examples/moderate-upload.py. The add-on table was completed (aws_rek_video, webpurify, duplicate:<threshold>) with pipe-combination semantics.
  • Size limits disentangled. The 100 MB per-request ceiling and the plan-dependent product-environment maximum are separate limits that fail with the same message; chunking clears only the former. Documented with an api.usage()["media_limits"] snippet so readers get real values for their own environment.
  • 423 while processing documented, including a Python-specific caveat: 423 is absent from this SDK's EXCEPTION_CODES map (cloudinary/api_client/execute_request.py), so it raises a plain Exception rather than a cloudinary.exceptions.Error subclass.
  • delivery_ips — IPv4 and IPv6 both accepted; CIDR ranges are not.
  • Platform status page added to "Still stuck".
  • Wording fix on the create_cloud() reference in configure-cloudinary.md.

One suggestion was not applied: nesting the claimable-cloud response under cloud["claim"]["url"]. The API returns claim_url, delivery_ips, and expires_at flat at the top level — confirmed in test/test_provisioning_api.py and examples/provision-claimable-cloud.py. The docs match the actual response shape.

secure=True in the explicit-config example is intentional: this is the v1 SDK, which is not secure by default.

Verification

  • All 9 examples run green against a freshly provisioned test cloud.
  • Every doc snippet executed, not just read — 59 code blocks parse, all cloudinary.* calls resolve against the real SDK, and all arguments bind to actual signatures.
  • Error paths tested explicitly: with no CLOUDINARY_URL all examples print a friendly message and exit 1; with bad credentials all API examples surface the real error and exit 1.
  • Upload and URL parameters verified behaviourally against the SDK whitelists — a param that would be silently dropped fails the check.
  • Packaging proven: all 15 .md files present in both wheel and sdist; examples/ correctly absent.

Notes for review

  • CHANGELOG.md intentionally untouched — the npm reference PRs added no changelog entries for docs work.
  • No linter added and no unrelated files reformatted, per AGENTS.md.
  • Docs contain no version number; the version-matched guarantee comes from shipping inside the package.

🤖 Generated with Claude Code

const-cloudinary and others added 3 commits August 24, 2026 16:56
Bring the repository up to the Cloudinary agent-readable documentation
standard established in cloudinary_npm (PRs #742, #744).

- Restructure README around the standard section order, with a runnable
  quick start and a stated read path for coding agents.
- Add 15 task docs under cloudinary/docs/, shipped inside the published
  package so they install to site-packages/cloudinary/docs/ and are
  version-matched with the code. Includes a Django page, which has no
  equivalent in the Node SDK.
- Add examples/ with 8 complete runnable files, one per "doing" task,
  cross-linked with their task docs.
- Add AGENTS.md, CLAUDE.md, SECURITY.md, and context7.json.
- Replace the three-line LICENSE.txt stub with canonical MIT text at
  LICENSE, preserving the vendored poster attribution. This is what
  GitHub and license scanners need to detect the license.
- Ship docs via MANIFEST.in plus package-data; keep examples/ repo-only.
- Set the PyPI summary to match the README one-liner.
- Correct stale facts in CONTRIBUTING.md (Travis, setup.py test, and the
  supported version matrix).

Every doc snippet and all 8 examples were executed against a live cloud.
Documented behavior that differs from a first reading of the code, and is
now stated in the docs: upload_large defaults to resource_type="raw" and
silently stores a video as an opaque blob; re-uploading to the same
public_id overwrites by default; the upload result exposes a moderation
list rather than a flat moderation_status; undefined structured-metadata
keys are rejected rather than ignored; the dict form of the video poster
option ignores secure=True; Search rejects leading wildcards.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Eitan Peer <eitan.peer@cloudinary.com>
Address review feedback on delivery behavior, and align the shared task
docs with the corrections verified in cloudinary_npm PR #742.

Moderation: a pending asset is deliverable by default — the status is
metadata to gate on, not an access control. Blocking non-approved assets
is configured per product environment by support, not by an upload
parameter. Statuses are queued, pending, approved, rejected, and aborted.
Fixes the intro, the statuses line, the troubleshooting entry (which had
the behavior inverted), and the example. Adds the full add-on table and
pipe-combination semantics.

Size limits: separate the 100 MB per-request ceiling from the
plan-dependent environment maximum, which chunking does not raise, and
show api.usage()["media_limits"] for reading the real values.

Troubleshooting: document 423 while processing, noting it is absent from
this SDK's EXCEPTION_CODES map and so raises a plain Exception rather
than a cloudinary.exceptions.Error subclass. Add the platform status page.

Also note IPv4/IPv6 support for delivery_ips.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@const-cloudinary
const-cloudinary merged commit b10665c into master Aug 25, 2026
16 checks passed
@const-cloudinary
const-cloudinary deleted the docs/agent-readable-documentation branch August 25, 2026 13:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant