---
title: "Custom Python Types"
description: "Python integrations can subclass openpit.Order and openpit.ExecutionReport to carry application-owned fields through the engine. The original subclass."
---

# Custom Python Types

Python integrations can subclass `openpit.Order` and
`openpit.ExecutionReport` to carry application-owned fields through the engine.
The original subclass instance reaches custom policy callbacks unchanged, while
the inherited OpenPit model continues to provide the validated engine fields.

## When to Use

Use Python model subclasses when:

- an order carries a strategy tag, desk identifier, or other host metadata;
- an execution report carries a venue execution id or reconciliation metadata;
- a custom policy must read those fields without maintaining a side channel.

If the standard models already contain every field the policy needs, use
`openpit.Order` and `openpit.ExecutionReport` directly.

## Contract

- A custom order inherits from `openpit.Order`; a custom report inherits from
  `openpit.ExecutionReport`.
- The standard constructor fields remain validated by the OpenPit boundary.
- Custom attributes remain application-owned and are visible only to custom
  policy code.
- Policy method annotations use the public base types. Use `typing.cast` inside
  a callback after registering the policy with the matching submission path.
- Callbacks run synchronously. Do not retain a submitted model beyond the call
  unless the application owns that lifetime independently.

## Complete Example

The complete runnable example lives in
[Policy API - Python Custom Models](Policy-API.md#python-custom-models). Keeping
the code in the all-language policy reference gives the example one canonical
source while this page focuses on Python-specific guidance.

## Threading

The model object is borrowed for a synchronous engine call. A custom policy
that owns mutable state must protect it according to the engine sync mode. Under
full synchronization, callbacks for the same account may still interleave; a
storage lock protects an individual access, not a complete multi-step policy
operation. See [Threading Contract](Threading-Contract.md).

## Related Pages

- [Policy API](Policy-API.md): complete Python callback contracts and rollback
  patterns
- [Getting Started](Getting-Started.md): engine construction and request lifecycle
- [Custom Go Types](Custom-Go-Types.md): typed Go client payloads
- [Custom JS Types](Custom-JS-Types.md): typed JavaScript policy payloads
- [Custom Cpp Types](Custom-Cpp-Types.md): C++ polymorphic client payloads
- [Custom Rust Types](Custom-Rust-Types.md): Rust capability-trait composition
