models.Part and PartSet

class PartSet(parts: Iterable[Part])[source]

A set of KE-chain parts.

Adding set-like methods on a list of parts:
  • iterable

  • len()

  • get()

  • iPython notebook support for HTML table

Construct a PartSet from a part iterable.

class Part(json: Dict, **kwargs)[source]

A virtual object representing a KE-chain part.

Variables:
  • id – UUID of the part

  • name – Name of the part

  • ref – Reference of the part (slug of the original name)

  • description – description of the part

  • created_at – the datetime when the object was created if available (otherwise None)

  • updated_at – the datetime when the object was last updated if available (otherwise None)

  • category – The category of the part, either ‘MODEL’ or ‘INSTANCE’ (of pykechain.enums.Category)

  • parent_id – The UUID of the parent of this part

  • properties – The list of Property objects belonging to this part.

  • multiplicity – The multiplicity of the part being one of the following options: ZERO_ONE, ONE, ZERO_MANY, ONE_MANY, (reserved) M_N (of pykechain.enums.Multiplicity)

  • scope_id – scope UUID of the Part

  • properties – the list of properties of this part

Examples

For the category property

>>> bike = project.part('Bike')
>>> bike.category
'INSTANCE'
>>> bike_model = project.model('Bike')
>>> bike_model.category
'MODEL'
>>> bike_model == Category.MODEL
True
>>> bike == Category.INSTANCE
True

For the multiplicity property

>>> bike = project.models('Bike')
>>> bike.multiplicity
ONE_MANY
>>> from pykechain.enums import Multiplicity
>>> bike.multiplicity == Multiplicity.ONE_MANY
True

Construct a part from a KE-chain 2 json response.

Parameters:

json (dict) – the json response to construct the Part from

refresh(json: Dict | None = None, url: str | None = None, extra_params: Dict | None = None)[source]

Refresh the object in place.

property(name: str = None) AnyProperty[source]

Retrieve the property belonging to this part based on its name, ref or uuid.

Parameters:

name – property name, ref or UUID to search for

Returns:

a single Property

Raises:

NotFoundError – if the Property is not part of the Part

:raises MultipleFoundError

Example

>>> part = project.part('Bike')
>>> part.properties
[<pyke Property ...>, ...]
# this returns a list of all properties of this part
>>> gears = part.property('Gears')
>>> gears.value
6
>>> gears = part.property('123e4567-e89b-12d3-a456-426655440000')
>>> gears.value
6
scope() Scope[source]

Scope this Part belongs to.

This property will return a Scope object. It will make an additional call to the KE-chain API.

Returns:

the scope

Return type:

pykechain.models.Scope

Raises:

NotFoundError – if the scope could not be found

parent() Part[source]

Retrieve the parent of this Part.

Returns:

the parent Part of this part

Raises:

APIError – if an Error occurs

Example

>>> part = project.part('Frame')
>>> bike = part.parent()
children(**kwargs) PartSet | List[Part][source]

Retrieve the children of this Part as PartSet.

When you call the Part.children() method without any additional filtering options for the children, the children are cached to help speed up subsequent calls to retrieve the children. The cached children are returned as a list and not as a Partset.

When you do provide additional keyword arguments (kwargs) that act as a specific children filter, the cached children are _not_ used and a separate API call is made to retrieve only those children.

Parameters:

kwargs – Additional search arguments to search for, check pykechain.Client.parts for additional info

Returns:

a set of Parts as a PartSet. Will be empty if no children. Will be a List if the children are retrieved from the cached children.

Raises:

APIError – When an error occurs.

Example

A normal call, which caches all children of the bike. If you call bike.children twice only 1 API call is made.

>>> bike = project.part('Bike')
>>> direct_descendants_of_bike = bike.children()

An example with providing additional part search parameters ‘name__icontains’. Children are retrieved from the API, not the bike’s internal (already cached in previous example) cache.

>>> bike = project.part('Bike')
>>> wheel_children_of_bike = bike.children(name__icontains='wheel')
child(name: str | None = None, pk: str | None = None, **kwargs) Part[source]

Retrieve a child object.

Parameters:
  • name (str) – optional, name of the child

  • pk – optional, UUID of the child

Type:

pk: str

Returns:

Child object

Raises:
populate_descendants(batch: int = 100) None[source]

Retrieve the descendants of a specific part in a list of dicts and populate the Part.children() method.

Each Part has a Part.children() method to retrieve the children on the go. This function prepopulates the children and the children’s children with its children in one call, making the traversal through the parttree blazingly fast.

New in version 2.1.

Changed in version 3.3.2: now populates child parts instead of this part

Parameters:

batch (int (defaults to 100)) – Number of Parts to be retrieved in a batch

Returns:

None

Raises:

APIError – if you cannot create the children tree.

Example

>>> bike = project.part('Bike')
>>> bike.populate_descendants(batch=150)
all_children() List[Part][source]

Retrieve a flat list of all descendants, sorted depth-first. Also populates all descendants.

:returns list of child objects :rtype List

siblings(**kwargs) PartSet | List[Part][source]

Retrieve the siblings of this Part as PartSet.

Siblings are other Parts sharing the same parent of this Part, including the part itself.

Parameters:

kwargs – Additional search arguments to search for, check pykechain.Client.parts for additional info

Returns:

a set of Parts as a PartSet. Will be empty if no siblings.

Raises:

APIError – When an error occurs.

model() Part[source]

Retrieve the model of this Part as Part.

For instance, you can get the part model of a part instance. But trying to get the model of a part that has no model, like a part model, will raise a NotFoundError.

New in version 1.8.

Returns:

the model of this part instance as Part with category MODEL

Raises:

NotFoundError – if no model found

Example

>>> front_fork = project.part('Front Fork')
>>> front_fork_model = front_fork.model()
instances(**kwargs) PartSet | List[Part][source]

Retrieve the instances of this Part as a PartSet.

For instance, if you have a model part, you can get the list of instances that are created based on this moodel. If there are no instances (only possible if the multiplicity is enums.Multiplicity.ZERO_MANY) than a NotFoundError is returned

New in version 1.8.

Returns:

the instances of this part model PartSet with category INSTANCE

Raises:

NotFoundError – if no instances found

Example

>>> wheel_model = project.model('Wheel')
>>> wheel_instance_set = wheel_model.instances()

An example with retrieving the front wheels only using the ‘name__contains’ search argument.

>>> wheel_model = project.model('Wheel')
>>> front_wheel_instances = wheel_model.instances(name__contains='Front')
instance() Part[source]

Retrieve the single (expected) instance of this ‘Part’ (of Category.MODEL) as a ‘Part’.

See Part.instances() method for documentation.

Returns:

Part with category INSTANCE

Raises:
count_instances() int[source]

Retrieve the number of instances of this Part model without the parts themselves.

Returns:

number of Part instances

:rtype

count_children(**kwargs) int[source]

Retrieve the number of child parts using a light-weight request.

Returns:

number of Parts

:rtype int

edit(name: str | ~pykechain.utils.Empty | None = <pykechain.utils.Empty object>, description: str | ~pykechain.utils.Empty | None = <pykechain.utils.Empty object>, **kwargs) None[source]

Edit the details of a part (model or instance).

Setting an input to None will clear out the value (exception being name).

For an instance you can edit the Part instance name and the part instance description. To alter the values of properties use Part.update().

In order to prevent the backend from updating the frontend you may add suppress_kevents=True as additional keyword=value argument to this method. This will improve performance of the backend against a trade-off that someone looking at the frontend won’t notice any changes unless the page is refreshed.

Parameters:
  • name (basestring or None or Empty) – optional name of the part to edit. Cannot be cleared.

  • description (basestring or None or Empty) – (optional) description of the part. Can be cleared.

  • kwargs – (optional) additional kwargs that will be passed in the during the edit/update request

Returns:

None

Raises:

Example

For changing a part:

>>> front_fork = project.part('Front Fork')
>>> front_fork.edit(name='Front Fork - updated')
>>> front_fork.edit(name='Front Fork cruizer',description='With my ragtop down so my hair can blow')

for changing a model:

>>> front_fork = project.model('Front Fork')
>>> front_fork.edit(name='Front Fork basemodel',description='Some description here')

Not mentioning an input parameter in the function will leave it unchanged. Setting a parameter as None will clear its value (where that is possible). The example below will clear the description and edit the name.

>>> front_fork.edit(name="Front spoon",description=None)
proxy_model() Part[source]

Retrieve the proxy model of this proxied Part as a Part.

Allows you to retrieve the model of a proxy. But trying to get the catalog model of a part that has no proxy, will raise an NotFoundError. Only models can have a proxy.

Changed in version 3.0: Added compatibility with KE-chain 3 backend.

Returns:

Part with category MODEL and from which the current part is proxied

Raises:

NotFoundError – When no proxy model is found

Example

>>> proxy_part = project.model('Proxy based on catalog model')
>>> catalog_model_of_proxy_part = proxy_part.proxy_model()
>>> proxied_material_of_the_bolt_model = project.model('Bolt Material')
>>> proxy_basis_for_the_material_model = proxied_material_of_the_bolt_model.proxy_model()
add(model: Part, **kwargs) Part[source]

Add a new child instance, based on a model, to this part.

This can only act on instances. It needs a model from which to create the child instance.

In order to prevent the backend from updating the frontend you may add suppress_kevents=True as additional keyword=value argument to this method. This will improve performance of the backend against a trade-off that someone looking at the frontend won’t notice any changes unless the page is refreshed.

Parameters:
  • model (Part) – Part object with category MODEL.

  • kwargs – (optional) additional keyword=value arguments

Returns:

Part with category INSTANCE.

Raises:

APIError – if unable to add the new child instance

Example

>>> bike = project.part('Bike')
>>> wheel_model = project.model('Wheel')
>>> bike.add(wheel_model)
add_to(parent: Part, **kwargs) Part[source]

Add a new instance of this model to a part.

This works if the current part is a model and an instance of this model is to be added to a part instances in the tree.

In order to prevent the backend from updating the frontend you may add suppress_kevents=True as additional keyword=value argument to this method. This will improve performance of the backend against a trade-off that someone looking at the frontend won’t notice any changes unless the page is refreshed.

Parameters:
  • parent (Part) – part to add the new instance to

  • kwargs – (optional) additional kwargs that will be passed in the during the edit/update request

Returns:

Part with category INSTANCE

Raises:

APIError – if unable to add the new child instance

Example

>>> wheel_model = project.model('wheel')
>>> bike = project.part('Bike')
>>> wheel_model.add_to(bike)
add_model(*args, **kwargs) Part[source]

Add a new child model to this model.

In order to prevent the backend from updating the frontend you may add suppress_kevents=True as additional keyword=value argument to this method. This will improve performance of the backend against a trade-off that someone looking at the frontend won’t notice any changes unless the page is refreshed.

Returns:

a Part of category MODEL

add_proxy_to(parent: Part, name: str, multiplicity: Multiplicity = 'ONE_MANY', **kwargs) Part[source]

Add this model as a proxy to another parent model.

This will add the current model as a proxy model to another parent model. It ensure that it will copy the whole subassembly to the ‘parent’ model.

In order to prevent the backend from updating the frontend you may add suppress_kevents=True as additional keyword=value argument to this method. This will improve performance of the backend against a trade-off that someone looking at the frontend won’t notice any changes unless the page is refreshed.

Parameters:
  • name (basestring) – Name of the new proxy model

  • parent (Part) – parent of the to be proxied model

  • multiplicity (basestring or None) – the multiplicity of the new proxy model (default ONE_MANY)

  • kwargs – (optional) additional kwargs that will be passed in the during the edit/update request

Returns:

the new proxied Part.

Raises:

APIError – in case an Error occurs

Examples

>>> from pykechain.enums import Multiplicity
>>> bike_model = project.model('Bike')
# find the catalog model container, the highest parent to create catalog models under
>>> catalog_model_container = project.model('Catalog container')
>>> new_wheel_model = project.create_model(catalog_model_container, 'Wheel Catalog',
...                                        multiplicity=Multiplicity.ZERO_MANY)
>>> new_wheel_model.add_proxy_to(bike_model, "Wheel", multiplicity=Multiplicity.ONE_MANY)
add_property(*args, **kwargs) AnyProperty[source]

Add a new property to this model.

See pykechain.Client.create_property for available parameters.

Returns:

Property

Raises:

APIError – in case an Error occurs

add_with_properties(model: Part, name: str | None = None, update_dict: Dict | None = None, properties_fvalues: List[Dict] | None = None, **kwargs) Part[source]

Add a new part instance of a model as a child of this part instance and update its properties in one go.

In order to prevent the backend from updating the frontend you may add suppress_kevents=True as additional keyword=value argument to this method. This will improve performance of the backend against a trade-off that someone looking at the frontend won’t notice any changes unless the page is refreshed.

With KE-chain 3 backends you may now provide a whole set of properties to update using a properties_fvalues list of dicts. This will be merged with the update_dict optionally provided. The properties_fvalues list is a list of dicts containing at least the id and a value, but other keys may provided as well in the single update eg. value_options. Example:

`properties_fvalues = [ {"id":<uuid of prop>, "value":<new_prop_value>}, {...}, ...]`

Changed in version 3.0: Added compatibility with KE-chain 3 backend. You may provide properties_fvalues as kwarg. Bulk option removed.

Changed in version 3.3: The ‘refresh’ flag is pending deprecation in version 3.4.. This flag had an effect of refreshing the list of children of the current part and was default set to True. This resulted in large processing times int he API as every add_with_properties() the children of the parent where all retrieved. The default is now ‘False’. The part just created is however to the internal list of children once these children are retrieved earlier.

Parameters:
  • model (Part) – model of the part which to add a new instance, should follow the model tree in KE-chain

  • name (basestring or None) – (optional) name provided for the new instance as string otherwise use the name of the model

  • update_dict (dict or None) – dictionary with keys being property names (str) or property_id (from the property models) and values being property values

  • properties_fvalues (list of dict or None) – (optional) keyword argument with raw list of properties update dicts

  • kwargs – (optional) additional keyword arguments that will be passed inside the update request

Returns:

the newly created Part

Raises:

Examples

>>> bike = project.part('Bike')
>>> wheel_model = project.model('Wheel')
>>> bike.add_with_properties(wheel_model, 'Wooden Wheel', {'Spokes': 11, 'Material': 'Wood'})
clone(**kwargs) Part[source]

Clone a part.

An optional name of the cloned part may be provided. If not provided the name will be set to “CLONE - <part name>”. (available for KE-chain 3 backends only) An optional multiplicity, may be added as paremeter for the cloning of models. If not provided the multiplicity of the part will be used. (available for KE-chain 3 backends only)

New in version 2.3.

Changed in version 3.0: Added optional paramenters the name and multiplicity for KE-chain 3 backends.

Parameters:

kwargs – (optional) additional keyword=value arguments

Returns:

cloned models.Part

Raises:

APIError – if the Part could not be cloned

Example

>>> bike = project.model('Bike')
>>> bike2 = bike.clone()

For KE-chain 3 backends

>>> bike = project.model('Bike')
>>> bike2 = bike.clone(name='Trike', multiplicity=Multiplicity.ZERO_MANY)
copy(target_parent: Part, name: str | None = None, include_children: bool = True, include_instances: bool = True) Part[source]

Copy the Part to target parent, both of them having the same category.

New in version 2.3.

Parameters:
  • target_parent (Part) – Part object under which the desired Part is copied

  • name (basestring) – how the copied top-level Part should be called

  • include_children (bool) – True to copy also the descendants of Part.

  • include_instances (bool) – True to copy also the instances of Part to ALL the instances of target_parent.

Returns:

copied Part model.

Raises:

Example

>>> model_to_copy = project.model(name='Model to be copied')
>>> bike = project.model('Bike')
>>> model_to_copy.copy(target_parent=bike, name='Copied model',
>>>                    include_children=True,
>>>                    include_instances=True)
move(target_parent: Part, name: str | None = None, include_children: bool = True, include_instances: bool = True) Part[source]

Move the Part to target parent, both of them the same category.

New in version 2.3.

Parameters:
  • target_parent (Part) – Part object under which the desired Part is moved

  • name (basestring) – how the moved top-level Part should be called

  • include_children (bool) – True to move also the descendants of Part. If False, the children will be lost.

  • include_instances (bool) – True to move also the instances of Part to ALL the instances of target_parent.

Returns:

moved Part model.

Raises:

Example

>>> model_to_move = project.model(name='Model to be moved')
>>> bike = project.model('Bike')
>>> model_to_move.move(target_parent=bike, name='Moved model',
>>>                    include_children=True,
>>>                    include_instances=True)
update(name: str | None = None, update_dict: Dict | None = None, properties_fvalues: List[Dict] | None = None, **kwargs) None[source]

Edit part name and property values in one go.

In order to prevent the backend from updating the frontend you may add suppress_kevents=True as additional keyword=value argument to this method. This will improve performance of the backend against a trade-off that someone looking at the frontend won’t notice any changes unless the page is refreshed.

With KE-chain 3 backends you may now provide a whole set of properties to update using a properties_fvalues list of dicts. This will be merged with the update_dict optionally provided. The properties_fvalues list is a list of dicts containing at least the id and a value, but other keys may provided as well in the single update eg. value_options. Example:

`properties_fvalues = [ {"id":<uuid of prop>, "value":<new_prop_value>}, {...}, ...]`

Changed in version 3.0: Added compatibility with KE-chain 3 backend. You may provide properties_fvalues as kwarg. Bulk option removed.

Parameters:
  • name (basestring or None) – new part name (defined as a string)

  • update_dict (dict or None) – dictionary with keys being property names (str) or property ids (uuid) and values being property values

  • properties_fvalues (list of dict or None) – (optional) keyword argument with raw list of properties update dicts

  • kwargs – additional keyword-value arguments that will be passed into the part update request.

Returns:

the updated Part

Raises:

Example

>>> bike = project.part('Bike')
>>> bike.update(name='Good name', update_dict={'Gears': 11, 'Total Height': 56.3})

Example with properties_fvalues: <pyke Part ‘Copied model under Bike’ id 95d35be6>

>>> bike = project.part('Bike')
>>> bike.update(name='Good name',
...             properties_fvalues=[{'id': '95d35be6...', 'value': 11},
...                                 {'id': '7893cba4...', 'value': 56.3, 'value_options': {...}})
delete() None[source]

Delete this part.

Returns:

None

Raises:

APIError – in case an Error occurs

order_properties(property_list: List[AnyProperty | str] | None = None) None[source]

Order the properties of a part model using a list of property objects or property names or property id’s.

For KE-chain 3 backends, the order can also directly provided as a unique integer for each property in the Part.update() function if you provide the properties_fvalues list of dicts yourself. For more information please refer to the Part.update() documentation.

Changed in version 3.0: For KE-chain 3 backend the Part.update() method is used with a properties_fvalues list of dicts.

Parameters:

property_list (list(basestring)) – ordered list of property names (basestring) or property id’s (uuid) or a Property object.

Returns:

the Part with the reordered list of properties

Raises:

Examples

>>> front_fork = project.model('Front Fork')
>>> front_fork.order_properties(['Material', 'Height (mm)', 'Color'])
>>> front_fork = project.model('Front Fork')
>>> material = front_fork.property('Material')
>>> height = front_fork.property('Height (mm)')
>>> color = front_fork.property('Color')
>>> front_fork.order_properties([material, height, color])

Alternatively you may use the Part.update() function to directly alter the order of the properties and eventually even more (defaut) model values.

>>> front_fork.update(properties_fvalues= [{'id': material.id, 'order':10},
...                                        {'id': height.id, 'order': 20, 'value':13.37}
...                                        {'id': color.id, 'order':  30, 'name': 'Colour'}])
as_dict() Dict[source]

Retrieve the properties of a part inside a dict in this structure: {property_name: property_value}.

New in version 1.9.

Returns:

the values of the properties as a dict

Return type:

dict

Example

>>> front_wheel = project.part('Front Wheel')
>>> front_wheel_properties = front_wheel.as_dict()
{'Diameter': 60.8,
 'Spokes': 24,
 'Rim Material': 'Aluminium',
 'Tire Thickness': 4.2}