cqparts.params package¶
Submodules¶
cqparts.params.parameter module¶
-
class
cqparts.params.parameter.
Parameter
(default=None, doc=None)¶ Bases:
object
Used to set parameters of a
ParametricObject
.All instances of this class defined in a class’
__dict__
will be valid input to the object’s constructor.Creating your own Parameter
To create your own parameter type, inherit from this class and override the
type()
method.To demonstrate, let’s create a parameter that takes an integer, and multiplies it by 10.
>>> from cqparts.params import Parameter >>> class Tens(Parameter): ... _doc_type = ":class:`int`" ... def type(self, value): ... return int(value) * 10
Now to use it in a
ParametricObject
>>> from cqparts.params import ParametricObject >>> class Foo(ParametricObject): ... a = Tens(5, doc="a in groups of ten") ... def bar(self): ... print("a = %i" % self.a) >>> f = Foo(a=8) >>> f.bar() a = 80
-
__init__
(default=None, doc=None)¶ Parameters: default – default value, will cast before storing
-
cast
(value)¶ First layer of type casting, used for high-level verification.
If
value
isNone
,type()
is not called to cast the value further.Parameters: value – the value given to the ParametricObject
’s constructorReturns: value
orNone
Raises: ParameterError – if type is invalid
-
classmethod
deserialize
(value)¶ Converts
json
deserialized value to its python equivalent.Parameters: value – json
deserialized valueReturns: python equivalent of value
Important
value
must be deserialized to be a valid input tocast()
More information on this in
serialize()
-
classmethod
new
(default=None)¶ Create new instance of the parameter with a new default
doc
Parameters: default – new parameter instance default value
-
classmethod
serialize
(value)¶ Converts value to something serializable by
json
.Parameters: value – value to convert Returns: json
serializable equivalentBy default, returns
value
, to pass straight tojson
Warning
serialize()
anddeserialize()
are not symmetrical.Example of serializing then deserializing a custom object
Let’s create our own
Color
class we’d like to represent as a parameter.>>> class Color(object): ... def __init__(self, r, g, b): ... self.r = r ... self.g = g ... self.b = b ... ... def __eq__(self, other): ... return ( ... type(self) == type(other) and \ ... self.r == other.r and \ ... self.g == other.g and \ ... self.b == other.b ... ) ... ... def __repr__(self): ... return "<Color: %i, %i, %i>" % (self.r, self.g, self.b) >>> from cqparts.params import Parameter >>> class ColorParam(Parameter): ... _doc_type = ":class:`list`" # for sphinx documentation ... def type(self, value): ... (r, g, b) = value ... return Color(r, g, b) ... ... @classmethod ... def serialize(cls, value): ... # the default serialize will fail, we know this ... # because json.dumps(Color(0,0,0)) raises an exception ... if value is None: # parameter is nullable ... return None ... return [value.r, value.g, value.b] ... ... @classmethod ... def deserialize(cls, value): ... # the de-serialized rgb list is good to pass to type ... return value
Note that
json_deserialize
does not return aColor
instance. Instead, it returns a list to be used as an input tocast()
(which is ultimately passed totype()
)This is because when the values are deserialized, they’re used as the default values for a newly created
ParametricObject
class.So now when we use them in a
ParametricObject
:>>> from cqparts.params import ParametricObject, Float >>> class MyObject(ParametricObject): ... color = ColorParam(default=[127, 127, 127]) # default 50% grey ... height = Float(10) >>> my_object = MyObject(color=[100, 200, 255]) >>> my_object.color # is a Color instance (not a list) <Color: 100, 200, 255>
Now to demonstrate how a parameter goes in and out of being serialized, we’ll create a
test
method that, doesn’t do anything, except that it should not throw any exceptions from its assertions, or the call tojson.dumps()
>>> import json >>> def test(value, obj_class=Color, param_class=ColorParam): ... orig_obj = param_class().cast(value) ... ... # serialize ... if value is None: ... assert orig_obj == None ... else: ... assert isinstance(orig_obj, obj_class) ... serialized = json.dumps(param_class.serialize(orig_obj)) ... ... # show serialized value ... print(serialized) # as a json string ... ... # deserialize ... ds_value = param_class.deserialize(json.loads(serialized)) ... new_obj = param_class().cast(ds_value) ... ... # now orig_obj and new_obj should be identical ... assert orig_obj == new_obj ... print("all good") >>> test([1, 2, 3]) [1, 2, 3] all good >>> test(None) null all good
These are used to serialize and deserialize
ParametricObject
instances, so they may be added to a catalogue, then re-created.To learn more, go to
ParametricObject.serialize()
-
type
(value)¶ Second layer of type casting, usually overridden to change the given
value
into the parameter’s type.Casts given value to the type dictated by this parameter type.
Raise a
ParameterError
on errors.Parameters: value – the value given to the ParametricObject
’s constructorReturns: value
cast to parameter’s typeRaises: ParameterError – if type is invalid
-
cqparts.params.parametric_object module¶
-
class
cqparts.params.parametric_object.
ParametricObject
(**kwargs)¶ Bases:
object
Parametric objects may be defined like so:
>>> from cqparts.params import ( ... ParametricObject, ... PositiveFloat, IntRange, ... ) >>> class Foo(ParametricObject): ... x = PositiveFloat(5) ... i = IntRange(1, 10, 3) # between 1 and 10, defaults to 3 ... blah = 100 >>> a = Foo(i=8) >>> (a.x, a.i) (5.0, 8) >>> a = Foo(i=11) # raises exception ParameterError: value of 11 outside the range {1, 10} >>> a = Foo(z=1) # raises exception ParameterError: <class 'Foo'> does not accept parameter(s): z >>> a = Foo(x='123', i='2') >>> (a.x, a.i) (123.0, 2) >>> a = Foo(blah=200) # raises exception, parameters must be Parameter types ParameterError: <class 'Foo'> does not accept any of the parameters: blah >>> a = Foo(x=None) # a.x is None, a.i=3 >>> (a.x, a.i) (None, 3)
Internally to the object, parameters may be accessed simply with self.x, self.i These will always return the type defined
-
classmethod
class_param_names
(hidden=True)¶ Return the names of all class parameters.
Parameters: hidden ( bool
) – ifFalse
, excludes parameters with a_
prefix.Returns: set of parameter names Return type: set
-
classmethod
class_params
(hidden=True)¶ Gets all class parameters, and their
Parameter
instances.Returns: dict of the form: {<name>: <Parameter instance>, ... }
Return type: dict
Note
The
Parameter
instances returned do not have a value, only a default value.To get a list of an instance’s parameters and values, use
params()
instead.
-
static
deserialize
(data)¶ Create instance from serial data
-
initialize_parameters
()¶ A place to set default parameters more intelligently than just a simple default value (does nothing by default)
Returns: None
Executed just prior to exiting the
__init__()
function.When overriding, strongly consider calling
super()
.
-
params
(hidden=True)¶ Gets all instance parameters, and their cast values.
Returns: dict of the form: {<name>: <value>, ... }
Return type: dict
-
serialize
()¶ Encode a
ParametricObject
instance to an object that can be encoded by thejson
module.Returns: a dict of the format: Return type: dict
{ 'lib': { # library information 'name': 'cqparts', 'version': '0.1.0', }, 'class': { # importable class 'module': 'yourpartslib.submodule', # module containing class 'name': 'AwesomeThing', # class being serialized }, 'params': { # serialized parameters of AwesomeThing 'x': 10, 'y': 20, } }
value of
params
key comes fromserialize_parameters()
Important
Serialize pulls the class name from the classes
__name__
parameter.This must be the same name of the object holding the class data, or the instance cannot be re-instantiated by
deserialize()
.Examples (good / bad)
>>> from cqparts.params import ParametricObject, Int >>> # GOOD Example >>> class A(ParametricObject): ... x = Int(10) >>> A().serialize()['class']['name'] 'A' >>> # BAD Example >>> B = type('Foo', (ParametricObject,), {'x': Int(10)}) >>> B().serialize()['class']['name'] 'Foo'
In the second example, the classes import name is expected to be
B
. But instead, the nameFoo
is recorded. This mismatch will be irreconcilable when attempting todeserialize()
.
-
classmethod
cqparts.params.types module¶
-
class
cqparts.params.types.
Boolean
(default=None, doc=None)¶ Bases:
cqparts.params.parameter.Parameter
Boolean value
-
type
(value)¶
-
-
class
cqparts.params.types.
ComponentRef
(default=None, doc=None)¶ Bases:
cqparts.params.parameter.Parameter
Reference to a Component
Initially introduced as a means to reference a sub-component’s parent
import cadquery from cqparts import Part, Component from cqparts.params import * class Eighth(Part): parent = ComponentRef(doc="part's parent") def make(self): size = self.parent.size / 2. return cadquery.Workplane('XY').box(size, size, size) class Cube(Assembly): size = PositiveFloat(10, doc="cube size") def make_components(self): # create a single cube 1/8 the volume of the whole cube return { 'a': Eighth(parent=self), } def make_constraints(self): return [ Fixed(self.components['a'].mate_origin), ]
-
type
(value)¶
-
-
class
cqparts.params.types.
Float
(default=None, doc=None)¶ Bases:
cqparts.params.parameter.Parameter
Floating point
-
type
(value)¶
-
-
class
cqparts.params.types.
FloatRange
(min, max, default, doc='[no description]')¶ Bases:
cqparts.params.types.Float
Floating point in the given range (inclusive)
-
__init__
(min, max, default, doc='[no description]')¶ {
min
<= value <=max
}Parameters:
-
type
(value)¶
-
-
class
cqparts.params.types.
Int
(default=None, doc=None)¶ Bases:
cqparts.params.parameter.Parameter
Integer value
-
type
(value)¶
-
-
class
cqparts.params.types.
IntRange
(min, max, default, doc='[no description]')¶ Bases:
cqparts.params.types.Int
Integer in the given range (inclusive)
-
__init__
(min, max, default, doc='[no description]')¶ {
min
<= value <=max
}Parameters:
-
type
(value)¶
-
-
class
cqparts.params.types.
LowerCaseString
(default=None, doc=None)¶ Bases:
cqparts.params.types.String
Lower case string
-
type
(value)¶
-
-
class
cqparts.params.types.
NonNullParameter
(default=None, doc=None)¶ Bases:
cqparts.params.parameter.Parameter
Non-nullable parameter
-
cast
(value)¶
-
-
class
cqparts.params.types.
PartsList
(default=None, doc=None)¶ Bases:
cqparts.params.parameter.Parameter
-
type
(value)¶
-
-
class
cqparts.params.types.
PositiveFloat
(default=None, doc=None)¶ Bases:
cqparts.params.types.Float
Floating point >= 0
-
type
(value)¶
-
-
class
cqparts.params.types.
PositiveInt
(default=None, doc=None)¶ Bases:
cqparts.params.types.Int
Integer >= 0
-
type
(value)¶
-
-
class
cqparts.params.types.
String
(default=None, doc=None)¶ Bases:
cqparts.params.parameter.Parameter
String value
-
type
(value)¶
-
-
class
cqparts.params.types.
UpperCaseString
(default=None, doc=None)¶ Bases:
cqparts.params.types.String
Upper case string
-
type
(value)¶
-
cqparts.params.utils module¶
-
cqparts.params.utils.
as_parameter
(nullable=True, strict=True)¶ Decorate a container class as a functional
Parameter
class for aParametricObject
.Parameters: nullable ( bool
) – if set, parameter’s value may be Null>>> from cqparts.params import as_parameter, ParametricObject >>> @as_parameter(nullable=True) ... class Stuff(object): ... def __init__(self, a=1, b=2, c=3): ... self.a = a ... self.b = b ... self.c = c ... @property ... def abc(self): ... return (self.a, self.b, self.c) >>> class Thing(ParametricObject): ... foo = Stuff({'a': 10, 'b': 100}, doc="controls stuff") >>> thing = Thing(foo={'a': 20}) >>> thing.foo.a 20 >>> thing.foo.abc (20, 2, 3)
Module contents¶
-
class
cqparts.params.
Parameter
(default=None, doc=None)¶ Bases:
object
Used to set parameters of a
ParametricObject
.All instances of this class defined in a class’
__dict__
will be valid input to the object’s constructor.Creating your own Parameter
To create your own parameter type, inherit from this class and override the
type()
method.To demonstrate, let’s create a parameter that takes an integer, and multiplies it by 10.
>>> from cqparts.params import Parameter >>> class Tens(Parameter): ... _doc_type = ":class:`int`" ... def type(self, value): ... return int(value) * 10
Now to use it in a
ParametricObject
>>> from cqparts.params import ParametricObject >>> class Foo(ParametricObject): ... a = Tens(5, doc="a in groups of ten") ... def bar(self): ... print("a = %i" % self.a) >>> f = Foo(a=8) >>> f.bar() a = 80
-
__init__
(default=None, doc=None)¶ Parameters: default – default value, will cast before storing
-
cast
(value)¶ First layer of type casting, used for high-level verification.
If
value
isNone
,type()
is not called to cast the value further.Parameters: value – the value given to the ParametricObject
’s constructorReturns: value
orNone
Raises: ParameterError – if type is invalid
-
classmethod
deserialize
(value)¶ Converts
json
deserialized value to its python equivalent.Parameters: value – json
deserialized valueReturns: python equivalent of value
Important
value
must be deserialized to be a valid input tocast()
More information on this in
serialize()
-
classmethod
new
(default=None)¶ Create new instance of the parameter with a new default
doc
Parameters: default – new parameter instance default value
-
classmethod
serialize
(value)¶ Converts value to something serializable by
json
.Parameters: value – value to convert Returns: json
serializable equivalentBy default, returns
value
, to pass straight tojson
Warning
serialize()
anddeserialize()
are not symmetrical.Example of serializing then deserializing a custom object
Let’s create our own
Color
class we’d like to represent as a parameter.>>> class Color(object): ... def __init__(self, r, g, b): ... self.r = r ... self.g = g ... self.b = b ... ... def __eq__(self, other): ... return ( ... type(self) == type(other) and \ ... self.r == other.r and \ ... self.g == other.g and \ ... self.b == other.b ... ) ... ... def __repr__(self): ... return "<Color: %i, %i, %i>" % (self.r, self.g, self.b) >>> from cqparts.params import Parameter >>> class ColorParam(Parameter): ... _doc_type = ":class:`list`" # for sphinx documentation ... def type(self, value): ... (r, g, b) = value ... return Color(r, g, b) ... ... @classmethod ... def serialize(cls, value): ... # the default serialize will fail, we know this ... # because json.dumps(Color(0,0,0)) raises an exception ... if value is None: # parameter is nullable ... return None ... return [value.r, value.g, value.b] ... ... @classmethod ... def deserialize(cls, value): ... # the de-serialized rgb list is good to pass to type ... return value
Note that
json_deserialize
does not return aColor
instance. Instead, it returns a list to be used as an input tocast()
(which is ultimately passed totype()
)This is because when the values are deserialized, they’re used as the default values for a newly created
ParametricObject
class.So now when we use them in a
ParametricObject
:>>> from cqparts.params import ParametricObject, Float >>> class MyObject(ParametricObject): ... color = ColorParam(default=[127, 127, 127]) # default 50% grey ... height = Float(10) >>> my_object = MyObject(color=[100, 200, 255]) >>> my_object.color # is a Color instance (not a list) <Color: 100, 200, 255>
Now to demonstrate how a parameter goes in and out of being serialized, we’ll create a
test
method that, doesn’t do anything, except that it should not throw any exceptions from its assertions, or the call tojson.dumps()
>>> import json >>> def test(value, obj_class=Color, param_class=ColorParam): ... orig_obj = param_class().cast(value) ... ... # serialize ... if value is None: ... assert orig_obj == None ... else: ... assert isinstance(orig_obj, obj_class) ... serialized = json.dumps(param_class.serialize(orig_obj)) ... ... # show serialized value ... print(serialized) # as a json string ... ... # deserialize ... ds_value = param_class.deserialize(json.loads(serialized)) ... new_obj = param_class().cast(ds_value) ... ... # now orig_obj and new_obj should be identical ... assert orig_obj == new_obj ... print("all good") >>> test([1, 2, 3]) [1, 2, 3] all good >>> test(None) null all good
These are used to serialize and deserialize
ParametricObject
instances, so they may be added to a catalogue, then re-created.To learn more, go to
ParametricObject.serialize()
-
type
(value)¶ Second layer of type casting, usually overridden to change the given
value
into the parameter’s type.Casts given value to the type dictated by this parameter type.
Raise a
ParameterError
on errors.Parameters: value – the value given to the ParametricObject
’s constructorReturns: value
cast to parameter’s typeRaises: ParameterError – if type is invalid
-
-
class
cqparts.params.
ParametricObject
(**kwargs)¶ Bases:
object
Parametric objects may be defined like so:
>>> from cqparts.params import ( ... ParametricObject, ... PositiveFloat, IntRange, ... ) >>> class Foo(ParametricObject): ... x = PositiveFloat(5) ... i = IntRange(1, 10, 3) # between 1 and 10, defaults to 3 ... blah = 100 >>> a = Foo(i=8) >>> (a.x, a.i) (5.0, 8) >>> a = Foo(i=11) # raises exception ParameterError: value of 11 outside the range {1, 10} >>> a = Foo(z=1) # raises exception ParameterError: <class 'Foo'> does not accept parameter(s): z >>> a = Foo(x='123', i='2') >>> (a.x, a.i) (123.0, 2) >>> a = Foo(blah=200) # raises exception, parameters must be Parameter types ParameterError: <class 'Foo'> does not accept any of the parameters: blah >>> a = Foo(x=None) # a.x is None, a.i=3 >>> (a.x, a.i) (None, 3)
Internally to the object, parameters may be accessed simply with self.x, self.i These will always return the type defined
-
classmethod
class_param_names
(hidden=True)¶ Return the names of all class parameters.
Parameters: hidden ( bool
) – ifFalse
, excludes parameters with a_
prefix.Returns: set of parameter names Return type: set
-
classmethod
class_params
(hidden=True)¶ Gets all class parameters, and their
Parameter
instances.Returns: dict of the form: {<name>: <Parameter instance>, ... }
Return type: dict
-
static
deserialize
(data)¶ Create instance from serial data
-
initialize_parameters
()¶ A place to set default parameters more intelligently than just a simple default value (does nothing by default)
Returns: None
Executed just prior to exiting the
__init__()
function.When overriding, strongly consider calling
super()
.
-
params
(hidden=True)¶ Gets all instance parameters, and their cast values.
Returns: dict of the form: {<name>: <value>, ... }
Return type: dict
-
serialize
()¶ Encode a
ParametricObject
instance to an object that can be encoded by thejson
module.Returns: a dict of the format: Return type: dict
{ 'lib': { # library information 'name': 'cqparts', 'version': '0.1.0', }, 'class': { # importable class 'module': 'yourpartslib.submodule', # module containing class 'name': 'AwesomeThing', # class being serialized }, 'params': { # serialized parameters of AwesomeThing 'x': 10, 'y': 20, } }
value of
params
key comes fromserialize_parameters()
Important
Serialize pulls the class name from the classes
__name__
parameter.This must be the same name of the object holding the class data, or the instance cannot be re-instantiated by
deserialize()
.Examples (good / bad)
>>> from cqparts.params import ParametricObject, Int >>> # GOOD Example >>> class A(ParametricObject): ... x = Int(10) >>> A().serialize()['class']['name'] 'A' >>> # BAD Example >>> B = type('Foo', (ParametricObject,), {'x': Int(10)}) >>> B().serialize()['class']['name'] 'Foo'
In the second example, the classes import name is expected to be
B
. But instead, the nameFoo
is recorded. This mismatch will be irreconcilable when attempting todeserialize()
.
-
serialize_parameters
()¶ Get the parameter data in its serialized form.
Data is serialized by each parameter’s
Parameter.serialize()
implementation.Returns: serialized parameter data in the form: {<name>: <serial data>, ...}
Return type: dict
-
classmethod
-
class
cqparts.params.
Boolean
(default=None, doc=None)¶ Bases:
cqparts.params.parameter.Parameter
Boolean value
-
type
(value)¶
-
-
class
cqparts.params.
ComponentRef
(default=None, doc=None)¶ Bases:
cqparts.params.parameter.Parameter
Reference to a Component
Initially introduced as a means to reference a sub-component’s parent
import cadquery from cqparts import Part, Component from cqparts.params import * class Eighth(Part): parent = ComponentRef(doc="part's parent") def make(self): size = self.parent.size / 2. return cadquery.Workplane('XY').box(size, size, size) class Cube(Assembly): size = PositiveFloat(10, doc="cube size") def make_components(self): # create a single cube 1/8 the volume of the whole cube return { 'a': Eighth(parent=self), } def make_constraints(self): return [ Fixed(self.components['a'].mate_origin), ]
-
type
(value)¶
-
-
class
cqparts.params.
Float
(default=None, doc=None)¶ Bases:
cqparts.params.parameter.Parameter
Floating point
-
type
(value)¶
-
-
class
cqparts.params.
FloatRange
(min, max, default, doc='[no description]')¶ Bases:
cqparts.params.types.Float
Floating point in the given range (inclusive)
-
__init__
(min, max, default, doc='[no description]')¶ {
min
<= value <=max
}Parameters:
-
type
(value)¶
-
-
class
cqparts.params.
Int
(default=None, doc=None)¶ Bases:
cqparts.params.parameter.Parameter
Integer value
-
type
(value)¶
-
-
class
cqparts.params.
IntRange
(min, max, default, doc='[no description]')¶ Bases:
cqparts.params.types.Int
Integer in the given range (inclusive)
-
__init__
(min, max, default, doc='[no description]')¶ {
min
<= value <=max
}Parameters:
-
type
(value)¶
-
-
class
cqparts.params.
LowerCaseString
(default=None, doc=None)¶ Bases:
cqparts.params.types.String
Lower case string
-
type
(value)¶
-
-
class
cqparts.params.
NonNullParameter
(default=None, doc=None)¶ Bases:
cqparts.params.parameter.Parameter
Non-nullable parameter
-
cast
(value)¶
-
-
class
cqparts.params.
PartsList
(default=None, doc=None)¶ Bases:
cqparts.params.parameter.Parameter
-
type
(value)¶
-
-
class
cqparts.params.
PositiveFloat
(default=None, doc=None)¶ Bases:
cqparts.params.types.Float
Floating point >= 0
-
type
(value)¶
-
-
class
cqparts.params.
PositiveInt
(default=None, doc=None)¶ Bases:
cqparts.params.types.Int
Integer >= 0
-
type
(value)¶
-
-
class
cqparts.params.
String
(default=None, doc=None)¶ Bases:
cqparts.params.parameter.Parameter
String value
-
type
(value)¶
-
-
class
cqparts.params.
UpperCaseString
(default=None, doc=None)¶ Bases:
cqparts.params.types.String
Upper case string
-
type
(value)¶
-
-
cqparts.params.
as_parameter
(nullable=True, strict=True)¶ Decorate a container class as a functional
Parameter
class for aParametricObject
.Parameters: nullable ( bool
) – if set, parameter’s value may be Null>>> from cqparts.params import as_parameter, ParametricObject >>> @as_parameter(nullable=True) ... class Stuff(object): ... def __init__(self, a=1, b=2, c=3): ... self.a = a ... self.b = b ... self.c = c ... @property ... def abc(self): ... return (self.a, self.b, self.c) >>> class Thing(ParametricObject): ... foo = Stuff({'a': 10, 'b': 100}, doc="controls stuff") >>> thing = Thing(foo={'a': 20}) >>> thing.foo.a 20 >>> thing.foo.abc (20, 2, 3)