Skip to content
This repository has been archived by the owner on Mar 28, 2022. It is now read-only.

Commit

Permalink
Add boolean data type (#71)
Browse files Browse the repository at this point in the history
* Add boolean data type

* Update runway/data_types.py

Co-Authored-By: Anastasis Germanidis <agermanidis@gmail.com>

* Propse version changes
  • Loading branch information
brannondorsey authored Jul 3, 2019
1 parent f6bddb3 commit 693baf5
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 8 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
# Changelog

The Runway Model SDK follows [semantic versioning](https://semver.org/). Be aware that breaking changes may be introduced in minor version updates until a stable 1.0.0 release occurs per [SemVer spec #4](https://semver.org/#spec-item-4).

> 4. Major version zero (0.y.z) is for initial development. Anything may change at any time. The public API should not be considered stable.
Until version 1.0.0, expect that minor version changes may introduce breaking changes. We will take care not to introduce new behavior, features, or breaking changes in patch releases. If you require stability and reproducible behavior you *may* pin to a version or version range of the model SDK like `runway-python>=0.2.0` or `runway-python>=0.2,<0.3`.

## v0.2.0

- Add `boolean` data type.

## v0.1.0

- Add `segmentation` data type.
- Begin strict [semantic versioning](https://semver.org/).

## v0.0.75

Expand Down
2 changes: 1 addition & 1 deletion runway/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.1.0'
__version__ = '0.2.0'
57 changes: 51 additions & 6 deletions runway/data_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -482,12 +482,12 @@ class segmentation(BaseType):
"""A datatype that represents a pixel-level segmentation of an image.
Each pixel is annotated with a label id from 0-255, each corresponding to a
different object class.
When used as an input data type, `segmentation` accepts a 1-channel base64-encoded PNG image,
where each pixel takes the value of one of the ids defined in `pixel_to_id`, or a 3-channel
base64-encoded PNG colormap image, where each pixel takes the value of one of the colors
base64-encoded PNG colormap image, where each pixel takes the value of one of the colors
defined in `pixel_to_color`.
When used as an output data type, it serializes as a 1-channel base64-encoded PNG image,
where each pixel takes the value of one of the ids defined in `pixel_to_id`.
Expand Down Expand Up @@ -531,10 +531,10 @@ def __init__(self, description=None, label_to_id=None, label_to_color=None, defa
raise MissingArgumentError('label_to_id')
if type(label_to_id) is not dict or len(label_to_id.keys()) == 0:
msg = 'label_to_id argument has invalid type'
raise InvalidArgumentError(msg)
raise InvalidArgumentError(self.name or self.type, msg)
if default_label is not None and default_label not in label_to_id.keys():
msg = 'default_label {} is not in label map'.format(default_label)
raise InvalidArgumentError(msg)
raise InvalidArgumentError(self.name or self.type, msg)
self.label_to_id = label_to_id
self.label_to_color = self.complete_colors(label_to_color or {})
self.default_label = default_label or list(self.label_to_id.keys())[0]
Expand Down Expand Up @@ -575,7 +575,7 @@ def deserialize(self, value):
return img
except:
msg = 'unable to parse expected base64-encoded image'
raise InvalidArgumentError(msg)
raise InvalidArgumentError(self.name or self.type, msg)

def serialize(self, value):
if type(value) is np.ndarray:
Expand All @@ -601,3 +601,48 @@ def to_dict(self):
if self.width: ret['width'] = self.width
if self.height: ret['height'] = self.height
return ret

class boolean(BaseType):
"""A basic boolean data type. The only accepted values for this data type are `True`
and `False`.
.. code-block:: python
import runway
from runway.data_types import boolean
@runway.setup(options={ "crop": boolean(default=True) })
def setup(opts):
if opts["crop"]:
print("The user has chosen to crop the image.")
else:
print("The user has chosen not to crop the image.")
:param description: A description of this variable and how it's used in the model,
defaults to None
:type description: string, optional
:param default: A default value for this boolean variable, defaults to False
:type default: bool, optional
"""

def __init__(self, description=None, default=False):
super(boolean, self).__init__('boolean', description=description)
self.default = default

def validate(self, value):
if type(value) != bool:
msg = 'value type {} is not a boolean'.format(type(value))
raise InvalidArgumentError(self.name or self.type, msg)

def deserialize(self, value):
self.validate(value)
return value

def serialize(self, value):
self.validate(value)
return value

def to_dict(self):
ret = super(boolean, self).to_dict()
ret['default'] = self.default
return ret
72 changes: 71 additions & 1 deletion tests/test_data_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ def test_image_serialize_invalid_type():
with pytest.raises(InvalidArgumentError):
image().serialize('data:image/jpeg;base64,')

# SEGMENTATION ------------------------------------------------------------------------
# SEGMENTATION -----------------------------------------------------------------
def test_segmentation_to_dict():
seg = segmentation(label_to_id={"background": 0, "person": 1}, label_to_color={'background': [0, 0, 0]}, width=512, height=512)
obj = seg.to_dict()
Expand Down Expand Up @@ -448,3 +448,73 @@ def test_segmentation_deserialize_invalid_type():

with pytest.raises(InvalidArgumentError):
segmentation(label_to_id={"background": 0, "person": 1}).deserialize('data:image/jpeg;base64,')

# BOOLEAN ----------------------------------------------------------------------
def test_boolean_to_dict():
b = boolean()
obj = b.to_dict()
assert obj['type'] == 'boolean'
assert obj['description'] == None
assert obj['default'] == False

b = boolean(description='This is a boolean used during testing.', default=True)
obj = b.to_dict()
assert obj['type'] == 'boolean'
assert obj['description'] == 'This is a boolean used during testing.'
assert obj['default'] == True

def test_boolean_serialization():
assert True == boolean().serialize(True)
assert False == boolean().serialize(False)

def test_boolean_deserialize():
assert True == boolean().serialize(True)
assert False == boolean().serialize(False)

def test_boolean_serialize_numpy_scalar():
with pytest.raises(InvalidArgumentError):
boolean().serialize('True')
with pytest.raises(InvalidArgumentError):
boolean().serialize('False')
with pytest.raises(InvalidArgumentError):
boolean().serialize('1')
with pytest.raises(InvalidArgumentError):
boolean().serialize('0')
with pytest.raises(InvalidArgumentError):
boolean().serialize(1)
with pytest.raises(InvalidArgumentError):
boolean().serialize(0)
with pytest.raises(InvalidArgumentError):
boolean().serialize(1.1)
with pytest.raises(InvalidArgumentError):
boolean().serialize({})
with pytest.raises(InvalidArgumentError):
boolean().serialize({ 'test': True })
with pytest.raises(InvalidArgumentError):
boolean().serialize([])
with pytest.raises(InvalidArgumentError):
boolean().serialize([1])

def test_boolean_deserialize_invalid_type():
with pytest.raises(InvalidArgumentError) as err:
boolean().deserialize('True')
with pytest.raises(InvalidArgumentError):
boolean().deserialize('False')
with pytest.raises(InvalidArgumentError):
boolean().deserialize('1')
with pytest.raises(InvalidArgumentError):
boolean().deserialize('0')
with pytest.raises(InvalidArgumentError):
boolean().deserialize(1)
with pytest.raises(InvalidArgumentError):
boolean().deserialize(0)
with pytest.raises(InvalidArgumentError):
boolean().deserialize(1.1)
with pytest.raises(InvalidArgumentError):
boolean().deserialize({})
with pytest.raises(InvalidArgumentError):
boolean().deserialize({ 'test': True })
with pytest.raises(InvalidArgumentError):
boolean().deserialize([])
with pytest.raises(InvalidArgumentError):
boolean().deserialize([1])

0 comments on commit 693baf5

Please sign in to comment.