-
Notifications
You must be signed in to change notification settings - Fork 64
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #99 from lance132/master
Doccano 1.7 compatibility update
- Loading branch information
Showing
38 changed files
with
1,419 additions
and
112 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
from dataclasses import asdict, dataclass, fields | ||
from typing import Iterable | ||
|
||
from requests import Session | ||
|
||
from ..models import Category, Project | ||
from ..utils.response import verbose_raise_for_status | ||
|
||
|
||
@dataclass | ||
class CategoryController: | ||
"""Wraps a Category.""" | ||
|
||
id: int | ||
category: Category | ||
categories_url: str | ||
client_session: Session | ||
project: Project | ||
|
||
|
||
class CategoriesController: | ||
"""Controls the creation and retrieval of individual annotations for an example.""" | ||
|
||
def __init__(self, example_id: int, project: Project, example_url: str, client_session: Session): | ||
"""Initializes a CategoriesController instance | ||
Args: | ||
example_id: int. The relevant example id to this annotations controller | ||
example_url: str. Url of the parent example | ||
project: Project. The project model of the annotations, which is needed to query | ||
for the type of annotation used by the project. | ||
client_session: requests.session. The current session passed from client to models | ||
""" | ||
self.example_id = example_id | ||
self.project = project | ||
self._example_url = example_url | ||
self.client_session = client_session | ||
|
||
@property | ||
def categories_url(self) -> str: | ||
"""Return an api url for annotations list of a example""" | ||
return f"{self._example_url}/categories" | ||
|
||
def all(self) -> Iterable[CategoryController]: | ||
"""Return a sequence of CategoryControllers. | ||
Yields: | ||
CategoryController: The next category controller. | ||
""" | ||
response = self.client_session.get(self.categories_url) | ||
verbose_raise_for_status(response) | ||
category_dicts = response.json() | ||
category_obj_fields = set(category_field.name for category_field in fields(Category)) | ||
|
||
for category_dict in category_dicts: | ||
# Sanitize category_dict before converting to Example | ||
sanitized_category_dict = { | ||
category_key: category_dict[category_key] for category_key in category_obj_fields | ||
} | ||
|
||
yield CategoryController( | ||
category=Category(**sanitized_category_dict), | ||
project=self.project, | ||
id=category_dict["id"], | ||
categories_url=self.categories_url, | ||
client_session=self.client_session, | ||
) | ||
|
||
def create(self, category: Category) -> CategoryController: | ||
"""Create a new category, return the generated controller | ||
Args: | ||
category: Category. Automatically assigns session variables. | ||
Returns: | ||
CategoryController. The CategoryController now wrapping around the newly created category. | ||
""" | ||
category_json = asdict(category) | ||
|
||
response = self.client_session.post(self.categories_url, json=category_json) | ||
verbose_raise_for_status(response) | ||
response_id = response.json()["id"] | ||
|
||
return CategoryController( | ||
category=category, | ||
project=self.project, | ||
id=response_id, | ||
categories_url=self.categories_url, | ||
client_session=self.client_session, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
from dataclasses import asdict, dataclass, fields | ||
from typing import Iterable | ||
|
||
from requests import Session | ||
|
||
from ..models.category_type import LABEL_COLOR_CYCLE, CategoryType | ||
from ..utils.response import verbose_raise_for_status | ||
|
||
COLOR_CYCLE_RANGE = len(LABEL_COLOR_CYCLE) | ||
|
||
|
||
@dataclass | ||
class CategoryTypeController: | ||
"""Wraps a CategoryType with fields used for interacting directly with Doccano client""" | ||
|
||
category_type: CategoryType | ||
id: int | ||
category_types_url: str | ||
client_session: Session | ||
|
||
@property | ||
def category_type_url(self) -> str: | ||
"""Return an api url for this category_type""" | ||
return f"{self.category_types_url}/{self.id}" | ||
|
||
|
||
class CategoryTypesController: | ||
"""Controls the creation and retrieval of individual CategoryTypeControllers for an assigned project""" | ||
|
||
def __init__(self, project_url: str, client_session: Session) -> None: | ||
"""Initializes a CategoryTypeController instance""" | ||
self._project_url = project_url | ||
self.client_session = client_session | ||
|
||
@property | ||
def category_types_url(self) -> str: | ||
"""Return an api url for category_types list""" | ||
return f"{self._project_url}/category-types" | ||
|
||
def all(self) -> Iterable[CategoryTypeController]: | ||
"""Return a sequence of all category-types for a given controller, which maps to a project | ||
Yields: | ||
CategoryTypeController: The next category type controller. | ||
""" | ||
response = self.client_session.get(self.category_types_url) | ||
verbose_raise_for_status(response) | ||
category_type_dicts = response.json() | ||
category_type_object_fields = set(category_type_field.name for category_type_field in fields(CategoryType)) | ||
|
||
for category_type_dict in category_type_dicts: | ||
# Sanitize category_type_dict before converting to CategoryType | ||
sanitized_category_type_dict = { | ||
category_type_key: category_type_dict[category_type_key] | ||
for category_type_key in category_type_object_fields | ||
} | ||
|
||
yield CategoryTypeController( | ||
category_type=CategoryType(**sanitized_category_type_dict), | ||
id=category_type_dict["id"], | ||
category_types_url=self.category_types_url, | ||
client_session=self.client_session, | ||
) | ||
|
||
def create(self, category_type: CategoryType) -> CategoryTypeController: | ||
"""Create new category_type for Doccano project, assign session variables to category_type, return the id""" | ||
category_type_json = asdict(category_type) | ||
|
||
response = self.client_session.post(self.category_types_url, json=category_type_json) | ||
verbose_raise_for_status(response) | ||
response_id = response.json()["id"] | ||
|
||
return CategoryTypeController( | ||
category_type=category_type, | ||
id=response_id, | ||
category_types_url=self.category_types_url, | ||
client_session=self.client_session, | ||
) | ||
|
||
def update(self, category_type_controllers: Iterable[CategoryTypeController]) -> None: | ||
"""Updates the given category_types in the remote project""" | ||
for category_type_controller in category_type_controllers: | ||
category_type_json = asdict(category_type_controller.category_type) | ||
category_type_json = { | ||
category_type_key: category_type_value | ||
for category_type_key, category_type_value in category_type_json.items() | ||
if category_type_value is not None | ||
} | ||
category_type_json["id"] = category_type_controller.id | ||
|
||
response = self.client_session.put(category_type_controller.category_type_url, json=category_type_json) | ||
verbose_raise_for_status(response) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.