Skip to main content

pyodoo-rpc-client (Odoo RPC)

Python client for the Odoo legacy RPC API (XML-RPC object/common services), intended for Odoo v19 and below.

For the Odoo JSON 2 API (v19+ compliant), use pyodoo-client.

Features

  • XML-RPC common + object service support.
  • ORM-like model accessor (client.model("res.partner")).
  • with_context support on model instances.
  • OdooRpcEntity convenience wrapper with save, delete, refresh.
  • Runtime debug behavior — debug=False suppresses errors and returns safe fallbacks; debug=True raises.

Installation

pip install pyodoo-rpc-client

Quick Start

from pyodoo_rpc_client import OdooRpcClient

odoo = OdooRpcClient(
    url="https://mycompany.example.com",
    db="mycompany",
    username="api-user@example.com",
    password="secret",   # or use key= for an API key
    debug=True,
)

partners = odoo.model("res.partner").search_read(
    [["is_company", "=", True]],
    fields=["name", "email"],
)

for p in partners:
    print(p.id, p.name)

Authentication

# Username + password
odoo = OdooRpcClient(url=..., db=..., username=..., password="secret")

# Username + API key
odoo = OdooRpcClient(url=..., db=..., username=..., key="your-api-key")

After construction, odoo.logged_in is True when authentication succeeded.

OdooRpcClient

OdooRpcClient(
    url,           # Odoo base URL, e.g. "http://localhost:8069"
    db,            # database name
    username,      # login username
    password=None, # password (use password or key, not both)
    key=None,      # API key (takes priority over password)
    debug=False,   # True → raises OdooRpcError on failure
    allow_none=True,
)

Attributes

Attribute Description
logged_in True when authenticated successfully
uid Authenticated user ID
error Last error, or None
debug Current debug flag

Methods

Method Description
model(model_name) Returns an OdooRpcModel for the given Odoo model
set_debug(bool) Toggle debug mode
execute_kw(model, method, args, kwargs) Raw XML-RPC call

OdooRpcModel

Obtained via odoo.model("res.partner").

Common methods

All domain arguments are standard Odoo domain lists, e.g. [["field", "operator", value]]. Additional Odoo keyword arguments (fields, limit, offset, order, context) are passed as keyword arguments.

model = odoo.model("res.partner")

# Search — returns list of IDs
ids = model.search([["is_company", "=", True]], limit=10)

# Read — returns list of dicts
records = model.read([1, 2, 3], fields=["name", "email"])

# Search + read in one call — returns list of OdooRpcEntity
partners = model.search_read(
    [["is_company", "=", True]],
    fields=["name", "email"],
    limit=50,
    order="name asc",
)

# Create — returns new record ID
new_id = model.create({"name": "ACME", "is_company": True})

# Write — returns True on success
model.write([new_id], {"name": "ACME Corp"})

# Unlink (delete) — returns True on success
model.unlink([new_id])

# Fields metadata
meta = model.fields_get([], attributes=["string", "type", "required"])

Context

# Attach context to all calls made on this model instance
model_fr = odoo.model("res.partner").with_context({"lang": "fr_FR"})
partners = model_fr.search_read([["is_company", "=", True]], fields=["name"])

# Or pass context per-call
partners = odoo.model("res.partner").search_read(
    [["is_company", "=", True]],
    fields=["name"],
    context={"lang": "fr_FR"},
)

Arbitrary methods

Any Odoo model method can be called directly:

result = odoo.model("account.move").action_post(ids=[42])

OdooRpcEntity

search_read returns a list of OdooRpcEntity objects. Field values are accessible as attributes.

partners = odoo.model("res.partner").search_read(
    [["is_company", "=", True]],
    fields=["name", "email"],
)

for p in partners:
    print(p.id, p.name, p.email)

# Load a single entity by ID
partner = odoo.model("res.partner").get(1)

# Refresh from the server
partner.refresh()

# Modify and save
partner.name = "Updated Name"
partner.save()  # calls write() for existing records, create() for new ones

# Delete
partner.delete()

# Check if entity has an ID
partner.exists()  # True / False

# Get field data as a dict
data = partner.get_data(["name", "email"])
changed = partner.get_changed_data()  # only fields changed since load

Error Handling

# debug=False (default): safe fallback returned, error stored on client/model
odoo = OdooRpcClient(..., debug=False)
result = odoo.model("res.partner").search_read([["id", "=", -1]])
# result → []
# odoo.model(...).error or odoo.error holds the exception

# debug=True: raises OdooRpcError immediately
from pyodoo_rpc_client.exceptions import OdooRpcError

odoo = OdooRpcClient(..., debug=True)
try:
    result = odoo.model("res.partner").search_read([["bad_field", "=", 1]])
except OdooRpcError as e:
    print(e)

Compatibility Notes

  • Targets the Odoo XML-RPC API (/xmlrpc/2/common, /xmlrpc/2/object), available in Odoo v8–v19.
  • For the Odoo JSON 2 API (v19+), use pyodoo-client instead.

Contributing

  • Open Issues for bugs and concrete feature requests.
  • Open Pull Requests for code/docs improvements.
  • For open-ended questions and ideas, use GitHub Discussions.
  • See CONTRIBUTING.md for workflow and expectations.

Development

# Install locally in editable mode (changes take effect immediately)
pip install -e .

# Build a distribution
pip install build twine
python -m build
python -m twine check dist/*

Metadata

Release files for pyodoo-rpc-client 18.0.6

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pyodoo-rpc-client 18.0.6
File Size Uploaded Provenance
pyodoo_rpc_client-18.0.6.tar.gz 10.3 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for pyodoo-rpc-client 18.0.6
File Interpreter ABI Platform
pyodoo_rpc_client-18.0.6-py3-none-any.whl Python 3 none any Details

Total release size: 19.0 kB

Release files / pyodoo_rpc_client-18.0.6.tar.gz

Download URL pyodoo_rpc_client-18.0.6.tar.gz
Size 10.3 kB
Tags Source
SHA-256 checksum
How to use checksums
09b922326a52276727d2ef5998febc6de78521d24003478190b1d1a9a28d913a
BLAKE2b-256 checksum
How to use checksums
c1ab18a9b7ae5fd4d18032f1b529c3335c78204c1f4561772d63cd89d8342ca9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.12

Release files / pyodoo_rpc_client-18.0.6-py3-none-any.whl

Download URL pyodoo_rpc_client-18.0.6-py3-none-any.whl
Size 8.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
44b11488d0d9e034c1fee37bc8aafcb17fa6d613b8a41fe398ce6df1df49e40c
BLAKE2b-256 checksum
How to use checksums
09f43f6ce6bfd96d07fda9c9c3a78eceafcbb1d4210bee2c94dfc0b6a9d968ed
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.12

Security for pyodoo-rpc-client 18.0.6

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page