Skip to content

fix(#213): resilient json2 introspection fallback behind a WAF#216

Merged
bosd merged 2 commits into
masterfrom
docs/issue-213-json2s-cloudflare
Jul 17, 2026
Merged

fix(#213): resilient json2 introspection fallback behind a WAF#216
bosd merged 2 commits into
masterfrom
docs/issue-213-json2s-cloudflare

Conversation

@bosd

@bosd bosd commented Jul 17, 2026

Copy link
Copy Markdown
Member

What

Fixes #213: a Cloudflare-fronted Odoo behind json2s breaks positional-argument RPC because the json2 connector introspects each model via GET /doc-bearer/<model>.json, which the WAF challenges (HTTP 403 "Just a moment…") even though the RPC POST is allowed.

Fix — transparent fallback

rpc_transport already swaps json2's module-level httpx for a pooled shim. This wraps json2's JsonModel._introspect so that when the /doc-bearer/ GET fails, it falls back to the built-in Odoo 19 ORM signatures, and positional calls to the standard methods (search, search_read, read, write, create, fields_get, unlink, …) keep working with no code change. A one-line warning is logged the first time. A positional call to a custom method with no built-in signature raises a clear, actionable error (use keyword args) instead of a bare KeyError.

json2/json2s exist only on Odoo 19+, so the Odoo 19 signatures are the only ones needed. They were verified against a live Odoo 19 server and mirror exactly what odoo/addons/api_doc's /doc-bearer/ endpoint produces (ordered param names, self stripped, var-keyword included, @api.model set).

Also

  • odoo_lib.get_odoo_version → keyword args (runs on every connection).
  • Docs: the Cloudflare/WAF caveat now describes the automatic fallback.
  • pydoclint-baseline.txt refresh — the committed baseline was stale vs the pydoclint 0.6.6 pinned in uv.lock, so the pydoclint pre-commit hook was rewriting it and failing on every PR. Regenerated so pre-commit is green.

Tests

New tests/test_rpc_transport.py cases: fallback population when the GET is blocked, positional model-method and record-method arg mapping, and the unknown-method guidance error. Full unit suite: 1435 passed. mypy + full pre-commit clean.

Closes #213.

The Odoo 19 ``json2`` connector maps positional method args to parameter names by
first fetching the model schema over a separate ``GET /doc-bearer/<model>.json``.
Some WAF configs (Cloudflare) challenge that GET path even when the RPC POST is
allowed, so positional-arg calls fail before reaching Odoo while keyword calls go
straight through (#213).

- docs/guides/configuration.md: document the introspection gotcha and the
  keyword-argument workaround under the existing Cloudflare/WAF caveat.
- odoo_lib.get_odoo_version: pass domain/fields as keywords. Version detection
  runs on every connection, so keeping it kwargs-only avoids the blocked GET on
  json2s behind a WAF.

Note: the import/export hot path still makes positional RPC calls; a complete fix
(resilient introspection fallback or full kwargs conversion) needs a live json2s
test environment and is left as follow-up.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the get_odoo_version function in src/fluvo/lib/odoo_lib.py to use keyword arguments instead of positional arguments when calling search_read. This change prevents potential WAF/Cloudflare challenge issues associated with the GET /doc-bearer/ request used for positional argument introspection in the json2 connector. Additionally, the documentation in docs/guides/configuration.md has been updated to explain this behavior and recommend keyword arguments. There are no review comments, and I have no feedback to provide.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@bosd bosd changed the title docs(#213): json2s introspection gotcha behind Cloudflare + kwargs fix(#213): resilient json2 introspection fallback behind a WAF Jul 17, 2026
The Odoo 19 json2 connector maps positional method args to parameter names by
first fetching the model schema over GET /doc-bearer/<model>.json. A WAF
(Cloudflare) commonly challenges that GET even when the RPC POST is allowed, so
every positional call failed before reaching Odoo (#213).

Make it transparent: wrap json2's JsonModel._introspect so that when the
/doc-bearer/ GET fails, it falls back to the built-in Odoo 19 ORM signatures and
positional calls to the standard methods (search, search_read, read, write,
create, fields_get, ...) keep working with no code change. A positional call to a
custom method with no built-in signature raises a clear, actionable error instead
of a bare KeyError. json2/json2s exist only on Odoo 19+, so the Odoo 19 signatures
(verified against a live server, matching odoo/addons/api_doc's /doc-bearer/
output exactly) are the only ones the fallback needs.

- rpc_transport: fallback signature table + @api.model method set, resilient
  _introspect wrapper wired into install() (idempotent, sentinel-guarded). The new
  helpers use concise one-line docstrings so they add no pydoclint-baseline churn.
- tests: cover fallback population, positional model- and record-method arg
  mapping, and the unknown-method guidance error.
- docs: update the Cloudflare/WAF caveat to describe the automatic fallback.

Also update two pydoclint baseline yield-type renderings ('batch',
'odoo_endpoint') that drifted with the resolved toolchain (Any -> list[Any],
(str, object) -> dict[str, object]), which was failing the pydoclint pre-commit
hook on every PR.
@bosd
bosd force-pushed the docs/issue-213-json2s-cloudflare branch from 7695877 to 6d808e7 Compare July 17, 2026 09:10
@bosd
bosd merged commit 9dd7105 into master Jul 17, 2026
25 checks passed
@bosd
bosd deleted the docs/issue-213-json2s-cloudflare branch July 17, 2026 09:19
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.

json2s: Cloudflare-fronted Odoo blocks model introspection (GET /doc-bearer), breaking positional-arg RPC

1 participant