Skip to content

Commit

Permalink
Merge pull request #276 from juliamcclellan/create_category
Browse files Browse the repository at this point in the history
Category spec
  • Loading branch information
pcattori committed Aug 16, 2019
2 parents 347fe5b + 65fa78a commit bceeedd
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- [#225](https://github.com/Datatamer/unify-client-python/issues/225) Attribute configuration spec to update an existing attribute configuration
- [#223](https://github.com/Datatamer/unify-client-python/issues/223) Update an attribute with an attribute spec
- [#224](https://github.com/Datatamer/unify-client-python/issues/224) Project spec to update a project
- [#275](https://github.com/Datatamer/unify-client-python/issues/275) Create a category with a category spec

**BUG FIXES**
- [#235](https://github.com/Datatamer/unify-client-python/issues/235) Making `AttributeCollection` retrieve attributes directly instead of by streaming
Expand Down
6 changes: 6 additions & 0 deletions docs/developer-interface.rst
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ Category
.. autoclass:: tamr_unify_client.categorization.category.resource.Category
:members:

Category Spec
"""""""""""""

.. autoclass:: tamr_unify_client.categorization.category.resource.CategorySpec
:members:

Category Collection
"""""""""""""""""""

Expand Down
98 changes: 97 additions & 1 deletion tamr_unify_client/categorization/category/resource.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from copy import deepcopy

from tamr_unify_client.base_resource import BaseResource


Expand All @@ -21,7 +23,7 @@ def description(self):
@property
def path(self):
""":type: list[str]"""
return self._data.get("path")
return self._data.get("path")[:]

def parent(self):
"""Gets the parent Category of this one, or None if it is a tier 1 category
Expand All @@ -37,6 +39,14 @@ def parent(self):
else:
return None

def spec(self):
"""Returns this category's spec.
:return: The spec for the category.
:rtype: :class:`~tamr_unify_client.categorization.category.resource.CategorySpec`
"""
return CategorySpec.of(self)

def __repr__(self):
return (
f"{self.__class__.__module__}."
Expand All @@ -46,3 +56,89 @@ def __repr__(self):
f"path={'/'.join(self.path)!r},"
f"description={self.description!r})"
)


class CategorySpec:
"""A representation of the server view of a category."""

def __init__(self, client, data, api_path):
self.client = client
self._data = data
self.api_path = api_path

@staticmethod
def of(resource):
"""Creates a category spec from a category.
:param resource: The existing category.
:type resource: :class:`~tamr_unify_client.categorization.category.resource.Category`
:return: The corresponding category spec.
:rtype: :class:`~tamr_unify_client.categorization.category.resource.CategorySpec`
"""
return CategorySpec(
resource.client, deepcopy(resource._data), resource.api_path
)

@staticmethod
def new():
"""Creates a blank spec that could be used to construct a new category.
:return: The empty spec.
:rtype: :class:`~tamr_unify_client.categorization.category.resource.CategorySpec`
"""
return CategorySpec(None, {}, None)

def from_data(self, data):
"""Creates a spec with the same client and API path as this one, but new data.
:param data: The data for the new spec.
:type data: dict
:return: The new spec.
:rtype: :class:`~tamr_unify_client.categorization.category.resource.CategorySpec`
"""
return CategorySpec(self.client, data, self.api_path)

def to_dict(self):
"""Returns a version of this spec that conforms to the API representation.
:returns: The spec's dict.
:rtype: dict
"""
return deepcopy(self._data)

def with_name(self, new_name):
"""Creates a new spec with the same properties, updating name.
:param new_name: The new name.
:type new_name: str
:return: The new spec.
:rtype: :class:`~tamr_unify_client.categorization.category.resource.CategorySpec`
"""
return self.from_data({**self._data, "name": new_name})

def with_description(self, new_description):
"""Creates a new spec with the same properties, updating description.
:param new_description: The new description.
:type new_description: str
:return: The new spec.
:rtype: :class:`~tamr_unify_client.categorization.category.resource.CategorySpec`
"""
return self.from_data({**self._data, "description": new_description})

def with_path(self, new_path):
"""Creates a new spec with the same properties, updating path.
:param new_path: The new path.
:type new_path: list[str]
:return: The new spec.
:rtype: :class:`~tamr_unify_client.categorization.category.resource.CategorySpec`
"""
return self.from_data({**self._data, "path": new_path})

def __repr__(self):
return (
f"{self.__class__.__module__}."
f"{self.__class__.__qualname__}("
f"dict={self._data})"
)
32 changes: 31 additions & 1 deletion tests/unit/test_taxonomy.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from tamr_unify_client import Client
from tamr_unify_client.auth import UsernamePasswordAuth
from tamr_unify_client.categorization.category.collection import CategoryCollection
from tamr_unify_client.categorization.category.resource import Category
from tamr_unify_client.categorization.category.resource import Category, CategorySpec
from tamr_unify_client.categorization.taxonomy import Taxonomy
from tamr_unify_client.project.resource import Project

Expand Down Expand Up @@ -65,6 +65,36 @@ def test_create(self):
c = coll.create(creation_spec)
self.assertEqual(alias + "/1", c.relative_id)

@responses.activate
def test_create_from_spec(self):
def create_callback(request, snoop):
snoop["payload"] = json.loads(request.body)
return 201, {}, json.dumps(self._categories_json[0])

post_url = (
"http://localhost:9100/api/versioned/v1/projects/1/taxonomy/categories"
)
snoop_dict = {}
responses.add_callback(
responses.POST, post_url, partial(create_callback, snoop=snoop_dict)
)

alias = "projects/1/taxonomy/categories"
coll = CategoryCollection(self.tamr, alias)

json_spec = {
"name": self._categories_json[0]["name"],
"path": self._categories_json[0]["path"],
}
spec = (
CategorySpec.new()
.with_name(self._categories_json[0]["name"])
.with_path(self._categories_json[0]["path"])
)
coll.create(spec.to_dict())

self.assertEqual(snoop_dict["payload"], json_spec)

@responses.activate
def test_bulk_create(self):
def create_callback(request, snoop):
Expand Down

0 comments on commit bceeedd

Please sign in to comment.