katana_public_api_client.domain¶
katana_public_api_client.domain
¶
Pydantic domain models for Katana entities.
This package provides clean, ergonomic Pydantic models representing business entities from the Katana Manufacturing ERP system.
Domain models are separate from the generated API request/response models and are optimized for: - ETL and data processing - Business logic - Data validation - JSON schema generation
Example
from katana_public_api_client import KatanaClient
from katana_public_api_client.domain import KatanaVariant
async with KatanaClient() as client:
# Helpers return domain models
variants = await client.variants.search("fox fork", limit=10)
# Use business methods
for v in variants:
print(f"{v.get_display_name()}: ${v.sales_price}")
# Easy ETL export
csv_rows = [v.to_csv_row() for v in variants]
# JSON schema generation
schema = KatanaVariant.model_json_schema()
Classes¶
KatanaBaseModel
¶
Bases: BaseModel
Base class for all Pydantic domain models.
Provides: - Immutability by default (frozen=True) - Automatic validation - JSON schema generation - Easy serialization for ETL - Common timestamp fields
Example
Functions¶
model_dump_for_etl()
¶
Export to ETL-friendly format.
Removes None values and uses field aliases for cleaner output.
Returns:
Example
Source code in katana_public_api_client/domain/base.py
to_dict_with_computed()
¶
Export including computed fields.
Unlike model_dump(), this includes @computed_field properties.
Returns:
Source code in katana_public_api_client/domain/base.py
to_warehouse_json()
¶
Export as JSON for data warehouse.
Returns:
-
str–JSON string with all non-None fields
Example
Source code in katana_public_api_client/domain/base.py
KatanaMaterial
¶
Bases: KatanaBaseModel
Domain model for a Material.
A Material represents raw materials and components used in manufacturing, including inventory tracking, supplier information, and batch management. This is a Pydantic model optimized for: - ETL and data processing - Business logic - Data validation - JSON schema generation
This model uses composition with the auto-generated Pydantic model, exposing a curated subset of fields with business methods.
Example
material = KatanaMaterial(
id=3201,
name="Stainless Steel Sheet 304",
type="material",
uom="m²",
category_name="Raw Materials",
is_sellable=False,
batch_tracked=True,
)
# Business methods available
print(material.get_display_name()) # "Stainless Steel Sheet 304"
# ETL export
csv_row = material.to_csv_row()
schema = KatanaMaterial.model_json_schema()
Functions¶
from_attrs(attrs_material)
classmethod
¶
Create a KatanaMaterial from an attrs Material model (API response).
This method leverages the generated Pydantic model's from_attrs() method
to handle UNSET sentinel conversion, then creates the domain model.
Parameters:
-
attrs_material(Material) –The attrs Material model from API response.
Returns:
-
KatanaMaterial–A new KatanaMaterial instance with business methods.
Example
Source code in katana_public_api_client/domain/material.py
from_generated(generated)
classmethod
¶
Create a KatanaMaterial from a generated Pydantic Material model.
This method extracts the curated subset of fields from the generated model.
Parameters:
-
generated(Material) –The auto-generated Pydantic Material model.
Returns:
-
KatanaMaterial–A new KatanaMaterial instance with business methods.
Example
Source code in katana_public_api_client/domain/material.py
get_display_name()
¶
Get formatted display name.
Returns:
-
str–Material name, or "Unnamed Material {id}" if no name
Example
Source code in katana_public_api_client/domain/material.py
matches_search(query)
¶
Check if material matches search query.
Searches across: - Material name - Category name
Parameters:
-
query(str) –Search query string (case-insensitive)
Returns:
-
bool–True if material matches query
Example
Source code in katana_public_api_client/domain/material.py
to_csv_row()
¶
Export as CSV-friendly row.
Returns:
Example
Source code in katana_public_api_client/domain/material.py
KatanaProduct
¶
Bases: KatanaBaseModel
Domain model for a Product.
A Product represents a finished good or component that can be sold, manufactured, or purchased, with support for variants and configurations. This is a Pydantic model optimized for: - ETL and data processing - Business logic - Data validation - JSON schema generation
This model uses composition with the auto-generated Pydantic model, exposing a curated subset of fields with business methods.
Example
product = KatanaProduct(
id=1,
name="Standard-hilt lightsaber",
type="product",
uom="pcs",
category_name="lightsaber",
is_sellable=True,
is_producible=True,
is_purchasable=True,
)
# Business methods available
print(product.get_display_name()) # "Standard-hilt lightsaber"
# ETL export
csv_row = product.to_csv_row()
schema = KatanaProduct.model_json_schema()
Functions¶
from_attrs(attrs_product)
classmethod
¶
Create a KatanaProduct from an attrs Product model (API response).
This method leverages the generated Pydantic model's from_attrs() method
to handle UNSET sentinel conversion, then creates the domain model.
Parameters:
-
attrs_product(Product) –The attrs Product model from API response.
Returns:
-
KatanaProduct–A new KatanaProduct instance with business methods.
Example
Source code in katana_public_api_client/domain/product.py
from_generated(generated)
classmethod
¶
Create a KatanaProduct from a generated Pydantic Product model.
This method extracts the curated subset of fields from the generated model.
Parameters:
-
generated(Product) –The auto-generated Pydantic Product model.
Returns:
-
KatanaProduct–A new KatanaProduct instance with business methods.
Example
Source code in katana_public_api_client/domain/product.py
get_display_name()
¶
Get formatted display name.
Returns:
-
str–Product name, or "Unnamed Product {id}" if no name
Example
Source code in katana_public_api_client/domain/product.py
matches_search(query)
¶
Check if product matches search query.
Searches across: - Product name - Category name
Parameters:
-
query(str) –Search query string (case-insensitive)
Returns:
-
bool–True if product matches query
Example
Source code in katana_public_api_client/domain/product.py
to_csv_row()
¶
Export as CSV-friendly row.
Returns:
Example
Source code in katana_public_api_client/domain/product.py
KatanaService
¶
Bases: KatanaBaseModel
Domain model for a Service.
A Service represents an external service that can be used as part of manufacturing operations or business processes. This is a Pydantic model optimized for: - ETL and data processing - Business logic - Data validation - JSON schema generation
This model uses composition with the auto-generated Pydantic model, exposing a curated subset of fields with business methods.
Example
service = KatanaService(
id=1,
name="External Assembly Service",
type="service",
uom="pcs",
category_name="Assembly",
is_sellable=True,
)
# Business methods available
print(service.get_display_name()) # "External Assembly Service"
# ETL export
csv_row = service.to_csv_row()
schema = KatanaService.model_json_schema()
Functions¶
from_attrs(attrs_service)
classmethod
¶
Create a KatanaService from an attrs Service model (API response).
This method leverages the generated Pydantic model's from_attrs() method
to handle UNSET sentinel conversion, then creates the domain model.
Parameters:
-
attrs_service(Service) –The attrs Service model from API response.
Returns:
-
KatanaService–A new KatanaService instance with business methods.
Example
Source code in katana_public_api_client/domain/service.py
from_generated(generated)
classmethod
¶
Create a KatanaService from a generated Pydantic Service model.
This method extracts the curated subset of fields from the generated model.
Parameters:
-
generated(Service) –The auto-generated Pydantic Service model.
Returns:
-
KatanaService–A new KatanaService instance with business methods.
Example
Source code in katana_public_api_client/domain/service.py
get_display_name()
¶
Get formatted display name.
Returns:
-
str–Service name, or "Unnamed Service {id}" if no name
Example
Source code in katana_public_api_client/domain/service.py
matches_search(query)
¶
Check if service matches search query.
Searches across: - Service name - Category name
Parameters:
-
query(str) –Search query string (case-insensitive)
Returns:
-
bool–True if service matches query
Example
Source code in katana_public_api_client/domain/service.py
to_csv_row()
¶
Export as CSV-friendly row.
Returns:
Example
Source code in katana_public_api_client/domain/service.py
KatanaVariant
¶
Bases: KatanaBaseModel
Domain model for a Product or Material Variant.
A Variant represents a specific SKU with unique pricing, configuration, and inventory tracking. This is a Pydantic model optimized for: - ETL and data processing - Business logic - Data validation - JSON schema generation
This model uses composition with the auto-generated Pydantic model, exposing a curated subset of fields with business methods.
Example
Functions¶
from_attrs(attrs_variant, product_or_material_name=None)
classmethod
¶
Create a KatanaVariant from an attrs Variant model (API response).
This method leverages the generated Pydantic model's from_attrs() method
to handle UNSET sentinel conversion, then creates the domain model.
Parameters:
-
attrs_variant(Variant) –The attrs Variant model from API response.
-
product_or_material_name(str | None, default:None) –Optional name of parent product/material (must be provided separately as it comes from extend query).
Returns:
-
KatanaVariant–A new KatanaVariant instance with business methods.
Example
Source code in katana_public_api_client/domain/variant.py
from_generated(generated, product_or_material_name=None)
classmethod
¶
Create a KatanaVariant from a generated Pydantic Variant model.
This method extracts the curated subset of fields from the generated model and converts nested objects (config_attributes, custom_fields) to simple dicts.
Parameters:
-
generated(Variant) –The auto-generated Pydantic Variant model.
-
product_or_material_name(str | None, default:None) –Optional name of parent product/material (must be provided separately as it comes from extend query).
Returns:
-
KatanaVariant–A new KatanaVariant instance with business methods.
Example
Source code in katana_public_api_client/domain/variant.py
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 | |
get_config_value(config_name)
¶
Get value of a configuration attribute by name.
Parameters:
-
config_name(str) –Name of the configuration attribute
Returns:
-
str | None–Config value or None if not found
Example
Source code in katana_public_api_client/domain/variant.py
get_custom_field(field_name)
¶
Get value of a custom field by name.
Parameters:
-
field_name(str) –Name of the custom field
Returns:
-
str | None–Field value or None if not found
Example
Source code in katana_public_api_client/domain/variant.py
get_display_name()
¶
Get formatted display name matching Katana UI format.
Format: "{Product/Material Name} / {Config Value 1} / {Config Value 2} / ..."
Returns:
-
str–Formatted variant name, or SKU if no name available
Example
Source code in katana_public_api_client/domain/variant.py
matches_search(query)
¶
Check if variant matches search query.
Searches across: - SKU - Product/material name - Supplier item codes - Config attribute values
Parameters:
-
query(str) –Search query string (case-insensitive)
Returns:
-
bool–True if variant matches query
Example
Source code in katana_public_api_client/domain/variant.py
to_csv_row()
¶
Export as CSV-friendly row.
Returns:
Example
Source code in katana_public_api_client/domain/variant.py
Functions¶
material_to_katana(material)
¶
Convert attrs Material model to Pydantic KatanaMaterial.
This function delegates to KatanaMaterial.from_attrs(), which uses the auto-generated Pydantic model's from_attrs() for UNSET conversion.
Parameters:
-
material(Material) –attrs Material model from API response
Returns:
-
KatanaMaterial–KatanaMaterial with all fields populated
Example
from katana_public_api_client.api.material import get_material
from katana_public_api_client.utils import unwrap
response = await get_material.asyncio_detailed(client=client, id=123)
material_attrs = unwrap(response)
material_domain = material_to_katana(material_attrs)
# Now use domain model features
print(material_domain.get_display_name())
print(material_domain.to_csv_row())
Source code in katana_public_api_client/domain/converters.py
materials_to_katana(materials)
¶
Convert list of attrs Material models to list of KatanaMaterial.
Parameters:
Returns:
-
list[KatanaMaterial]–List of KatanaMaterial models
Example
from katana_public_api_client.api.material import get_all_materials
from katana_public_api_client.utils import unwrap_data
response = await get_all_materials.asyncio_detailed(client=client)
materials_attrs = unwrap_data(response)
materials_domain = materials_to_katana(materials_attrs)
# Now use domain model features
batch_tracked = [m for m in materials_domain if m.batch_tracked]
Source code in katana_public_api_client/domain/converters.py
product_to_katana(product)
¶
Convert attrs Product model to Pydantic KatanaProduct.
This function delegates to KatanaProduct.from_attrs(), which uses the auto-generated Pydantic model's from_attrs() for UNSET conversion.
Parameters:
-
product(Product) –attrs Product model from API response
Returns:
-
KatanaProduct–KatanaProduct with all fields populated
Example
from katana_public_api_client.api.product import get_product
from katana_public_api_client.utils import unwrap
response = await get_product.asyncio_detailed(client=client, id=123)
product_attrs = unwrap(response)
product_domain = product_to_katana(product_attrs)
# Now use domain model features
print(product_domain.get_display_name())
print(product_domain.to_csv_row())
Source code in katana_public_api_client/domain/converters.py
products_to_katana(products)
¶
Convert list of attrs Product models to list of KatanaProduct.
Parameters:
Returns:
-
list[KatanaProduct]–List of KatanaProduct models
Example
from katana_public_api_client.api.product import get_all_products
from katana_public_api_client.utils import unwrap_data
response = await get_all_products.asyncio_detailed(client=client)
products_attrs = unwrap_data(response)
products_domain = products_to_katana(products_attrs)
# Now use domain model features
sellable = [p for p in products_domain if p.is_sellable]
Source code in katana_public_api_client/domain/converters.py
service_to_katana(service)
¶
Convert attrs Service model to Pydantic KatanaService.
This function delegates to KatanaService.from_attrs(), which uses the auto-generated Pydantic model's from_attrs() for UNSET conversion.
Parameters:
-
service(Service) –attrs Service model from API response
Returns:
-
KatanaService–KatanaService with all fields populated
Example
from katana_public_api_client.api.service import get_service
from katana_public_api_client.utils import unwrap
response = await get_service.asyncio_detailed(client=client, id=123)
service_attrs = unwrap(response)
service_domain = service_to_katana(service_attrs)
# Now use domain model features
print(service_domain.get_display_name())
print(service_domain.to_csv_row())
Source code in katana_public_api_client/domain/converters.py
services_to_katana(services)
¶
Convert list of attrs Service models to list of KatanaService.
Parameters:
Returns:
-
list[KatanaService]–List of KatanaService models
Example
from katana_public_api_client.api.service import get_all_services
from katana_public_api_client.utils import unwrap_data
response = await get_all_services.asyncio_detailed(client=client)
services_attrs = unwrap_data(response)
services_domain = services_to_katana(services_attrs)
# Now use domain model features
sellable = [s for s in services_domain if s.is_sellable]
Source code in katana_public_api_client/domain/converters.py
unwrap_unset(value, default=None)
¶
Unwrap an Unset sentinel value.
Parameters:
-
value(T | Unset) –Value that might be Unset
-
default(T | None, default:None) –Default value to return if Unset
Returns:
-
T | None–The unwrapped value, or default if value is Unset
Example
Source code in katana_public_api_client/domain/converters.py
variant_to_katana(variant)
¶
Convert attrs Variant model to Pydantic KatanaVariant.
This function delegates to KatanaVariant.from_attrs(), which uses the auto-generated Pydantic model's from_attrs() for UNSET conversion.
Parameters:
-
variant(Variant) –attrs Variant model from API response
Returns:
-
KatanaVariant–KatanaVariant with all fields populated
Example
from katana_public_api_client.api.variant import get_variant
from katana_public_api_client.utils import unwrap
response = await get_variant.asyncio_detailed(client=client, id=123)
variant_attrs = unwrap(response)
variant_domain = variant_to_katana(variant_attrs)
# Now use domain model features
print(variant_domain.get_display_name())
Source code in katana_public_api_client/domain/converters.py
variants_to_katana(variants)
¶
Convert list of attrs Variant models to list of KatanaVariant.
Parameters:
Returns:
-
list[KatanaVariant]–List of KatanaVariant models
Example
from katana_public_api_client.api.variant import get_all_variants
from katana_public_api_client.utils import unwrap_data
response = await get_all_variants.asyncio_detailed(client=client)
variants_attrs = unwrap_data(response)
variants_domain = variants_to_katana(variants_attrs)
# Now use domain model features
high_margin = [v for v in variants_domain if v.is_high_margin]