From 97bf194c3ef01357eb34dabe1cd8bd246cfeb7ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8Dtalo=20Epif=C3=A2nio?= Date: Tue, 12 Jul 2022 13:54:45 -0300 Subject: [PATCH] Update documentation (#27) * Update README.md * Update API doc --- README.md | 71 ++++++++++---------- ipyannotator/base.py | 18 +++++ ipyannotator/docs/api.py | 4 ++ nbs/00_base.ipynb | 20 +++++- nbs/01c_tutorial_bbox.ipynb | 2 +- nbs/01d_tutorial_video_annotator.ipynb | 2 +- nbs/08_tutorial_road_damage.ipynb | 2 +- nbs/20_image_classification_user_story.ipynb | 12 +--- nbs/21_api_doc.ipynb | 68 ++++++++++++++++++- 9 files changed, 147 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index 6c7ca1e..307268e 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,13 @@ ![CI-Badge](https://github.com/palaimon/ipyannotator/workflows/CI/badge.svg) -Ipyannotator is a flexible annotation system. The library contains some pre-defined annotators that can be used out of the box, but it also can be extend and customized according to the users needs. +Ipyannotator is a flexible annotation system. Developed to allow users to hack its features by extending and customizing it. + +The large variety of annotation tasks, data formats and data visualizations is a challenging when dealing with multiple domains of supervised machine learning (ML). The existent tooling is often not flexible enough which imposes limitations to the user. By providing a framework where users can use, customize and create their own annotation tooling this projects aims to solve this problem. + +The library contains some pre-defined annotators that can be used out of the box, but it also can be extend and customized according to the users needs. Check our [tutorials](https://palaimon.github.io/ipyannotator/docs/tutorials.html) for a quickly understanding of it's usage and check our [API](https://palaimon.github.io/ipyannotator/nbs/21_api_doc.html) for quick reference. + +This library has been written in the [literate programming style](https://en.wikipedia.org/wiki/Literate_programming) popularized for jupyter notebooks by [nbdev](https://www.fast.ai/2019/12/02/nbdev/). In addition to our [online documentation](palaimon.github.io/ipyannotator) the jupyter notebooks located at `nbs/` allow an interactive exploration of the inner workings of Ipyannotator. We hope this repository helps you to explore how annotation UI's can be quickly built using only python code and leveraging many awesome libraries ([ipywidgets](https://github.com/jupyter-widgets/ipywidgets), [voila](https://github.com/voila-dashboards/voila), [ipycanvas](https://github.com/martinRenou/ipycanvas), etc.) from the [jupyter Eco-system](https://jupyter.org/). @@ -14,59 +20,52 @@ Please let us know if you find this repository useful. Your feedback will help u ## Install +Ipyannotator is available on Pypi and can be installed using: + `pip install ipyannotator` -**dependencies (should be handled by pip)** +## Running ipyannotator -``` -python = "^3.7" -traitlets = '=4.3.3' -ipycanvas = "^0.5.1" -ipyevents = "^0.8.0" -ipywidgets = "^7.5.1" -``` +Ipyannotator provides a [simple API](https://palaimon.github.io/ipyannotator/nbs/21_api_doc.html) that provides the ability to explore, create and improve annotation datasets by using a pair of input/outputs. All pair of input/output are [listed on Ipyannotator's docs](https://palaimon.github.io/ipyannotator/nbs/22_input_output_doc.html). Check [Ipyannotator tutorials](https://palaimon.github.io/ipyannotator/docs/tutorials.html) for a quickly demonstration of the library. + +### Run ipyannotator tests + +The tests can be executed using `nbdev_test_nbs` on the terminal. + +Ipyannotator notebooks contains the development dependencies: [pytest](https://docs.pytest.org/en/7.1.x/) and [ipytest](https://github.com/chmp/ipytest). Make sure this dependencies are installed to run the tests. + +### Run ipyannotator as stand-alone web app using voila + +Ipyannotator can be executed as a web app using the [voila](https://github.com/voila-dashboards/voila) library. The following sections describe how to run using poetry and pip. -## Run ipyannotator as stand-alone web app using voila +#### Using poetry -Using `poetry`: +On your terminal: -install: ```shell cd {project_root} poetry install --no-dev -poetry run pip install voila ``` -and run simple ipyannotator standalone example: -```shell + +Any jupyter notebook with ipyannotator can be executed as an standalone web application. An example of voila usage it's available in the current repository and can be executed as it follow: + +```shell poetry run voila nbs/09_voila_example.ipynb --enable_nbextensions=True ``` - -Same with `pip`: + +#### Using pip + +The installation and execution process can also be done using pip. ```shell cd {project_root} - pip install . + pip install . pip install voila voila nbs/09_voila_example.ipynb --enable_nbextensions=True ``` -## Documentation - -This library has been written in the [literate programming style](https://en.wikipedia.org/wiki/Literate_programming) popularized for -jupyter notebooks by [nbdev](https://www.fast.ai/2019/12/02/nbdev/). Please explore the jupyter notebooks in `nbs/` to learn more about -the inner working of ipyannotator. - -The notebooks contains the development dependencies: -[pytest](https://docs.pytest.org/en/7.1.x/) and [ipytest](https://github.com/chmp/ipytest), -if you want to run the notebooks remove the tests or install the libraries mentioned. - -Also check out the following notebook for a more high level overview. - -- Tutorial demonstrating how ipyannotator can be seamlessly integrated in your data science workflow. `nbs/08_tutorial_road_damage.ipynb` -- [Recoding of jupytercon 2020](https://www.youtube.com/watch?v=jFAp1s1O8Hg) talk explaining the high level concepts / vision of ipyannotator. - ## Jupyter lab trouble shooting For clean (re)install make sure to have all the lab extencions active: @@ -104,13 +103,15 @@ the [nbdev tutorial](https://nbdev.fast.ai/tutorial.html) and related docs will - [jupytercon 2020 talk](https://cfp.jupytercon.com/2020/schedule/presentation/237/ipyannotator-the-infinitely-hackable-annotation-framework/). -##Acknowledgements +- [Recording of jupytercon 2020](https://www.youtube.com/watch?v=jFAp1s1O8Hg) talk explaining the high level concepts / vision of ipyannotator. + +## Acknowledgements The authors acknowledge the financial support by the Federal Ministry for Digital and Transport of Germany under the program mFUND (project number 19F2160A). ## Copyright -Copyright 2020 onwards, Palaimon GmbH. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this project's files except in compliance with the License. A copy of the License is provided in the LICENSE file in this repository. +Copyright 2022 onwards, Palaimon GmbH. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this project's files except in compliance with the License. A copy of the License is provided in the LICENSE file in this repository. diff --git a/ipyannotator/base.py b/ipyannotator/base.py index 67b9328..e669142 100644 --- a/ipyannotator/base.py +++ b/ipyannotator/base.py @@ -90,6 +90,24 @@ def __init__(self, app_state: AppWidgetState): # Internal Cell class Settings(NamedTuple): + """ + Holds Ipyannotator API settings + + project_path: parent directory of the project_file and image_dir + project_file: json file with annotations + image_dir: directory that stores all images to be explored + label_dir: directory that hold the image labels (if any) + result_dir: directory to store the annotation results + + im_width: size of the images from image_dir + im_height: height of the images from image_dir + label_width: width of the labels from labels_dir + label_height: height of the labels from labels_dir + + n_cols: number of columns displayed at the right menu + n_rows: number of rows displayed at the right menu + """ + project_path: Path = Path('user_project') project_file: Optional[Path] = None image_dir: str = 'images' diff --git a/ipyannotator/docs/api.py b/ipyannotator/docs/api.py index 0ffc028..046041d 100644 --- a/ipyannotator/docs/api.py +++ b/ipyannotator/docs/api.py @@ -5,10 +5,14 @@ # Internal Cell from ..annotator import Annotator from .utils import show_doc +from ..base import Settings # Internal Cell show_doc(Annotator, title_level=3) +# Internal Cell +show_doc(Settings, title_level=4) + # Internal Cell show_doc(Annotator.explore) diff --git a/nbs/00_base.ipynb b/nbs/00_base.ipynb index 1f0784d..50efdc1 100644 --- a/nbs/00_base.ipynb +++ b/nbs/00_base.ipynb @@ -278,6 +278,24 @@ "#exporti\n", "\n", "class Settings(NamedTuple):\n", + " \"\"\"\n", + " Holds Ipyannotator API settings\n", + "\n", + " project_path: parent directory of the project_file and image_dir\n", + " project_file: json file with annotations\n", + " image_dir: directory that stores all images to be explored\n", + " label_dir: directory that hold the image labels (if any)\n", + " result_dir: directory to store the annotation results\n", + "\n", + " im_width: size of the images from image_dir\n", + " im_height: height of the images from image_dir\n", + " label_width: width of the labels from labels_dir\n", + " label_height: height of the labels from labels_dir\n", + "\n", + " n_cols: number of columns displayed at the right menu\n", + " n_rows: number of rows displayed at the right menu\n", + " \"\"\"\n", + "\n", " project_path: Path = Path('user_project')\n", " project_file: Optional[Path] = None\n", " image_dir: str = 'images'\n", @@ -376,7 +394,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" } diff --git a/nbs/01c_tutorial_bbox.ipynb b/nbs/01c_tutorial_bbox.ipynb index 56b2256..4d3232f 100644 --- a/nbs/01c_tutorial_bbox.ipynb +++ b/nbs/01c_tutorial_bbox.ipynb @@ -339,7 +339,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" } diff --git a/nbs/01d_tutorial_video_annotator.ipynb b/nbs/01d_tutorial_video_annotator.ipynb index 6e1b36c..8c9368b 100644 --- a/nbs/01d_tutorial_video_annotator.ipynb +++ b/nbs/01d_tutorial_video_annotator.ipynb @@ -313,7 +313,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" } diff --git a/nbs/08_tutorial_road_damage.ipynb b/nbs/08_tutorial_road_damage.ipynb index 50934a0..a02f15b 100644 --- a/nbs/08_tutorial_road_damage.ipynb +++ b/nbs/08_tutorial_road_damage.ipynb @@ -573,7 +573,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" } diff --git a/nbs/20_image_classification_user_story.ipynb b/nbs/20_image_classification_user_story.ipynb index 8105b72..4befffb 100644 --- a/nbs/20_image_classification_user_story.ipynb +++ b/nbs/20_image_classification_user_story.ipynb @@ -255,7 +255,7 @@ "settings = Settings(\n", " project_path=Path('user_project'),\n", " image_dir='images',\n", - " result_dir='results'\n", + " result_dir='batata'\n", ")" ] }, @@ -337,19 +337,11 @@ "source": [ "anni.create()" ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "48a6c31b", - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" } diff --git a/nbs/21_api_doc.ipynb b/nbs/21_api_doc.ipynb index 57ef95e..a5968cf 100644 --- a/nbs/21_api_doc.ipynb +++ b/nbs/21_api_doc.ipynb @@ -17,7 +17,7 @@ "source": [ "# API Reference\n", "\n", - "Detailed information about Ipyannotator API. To see usage please check Ipyannotator tutorials." + "Detailed information about Ipyannotator API. To see usage please check [Ipyannotator tutorials](https://palaimon.github.io/ipyannotator/nbs/22_input_output_doc.html)." ] }, { @@ -29,7 +29,16 @@ "source": [ "#exporti\n", "from ipyannotator.annotator import Annotator\n", - "from ipyannotator.docs.utils import show_doc" + "from ipyannotator.docs.utils import show_doc\n", + "from ipyannotator.base import Settings" + ] + }, + { + "cell_type": "markdown", + "id": "ab95f6b1", + "metadata": {}, + "source": [ + "To use Ipyannotator API it's necessary to import the `Annotator` class by using `from ipyannotator.annotator import Annotator`. " ] }, { @@ -43,6 +52,51 @@ "show_doc(Annotator, title_level=3)" ] }, + { + "cell_type": "markdown", + "id": "7c6ab67b", + "metadata": {}, + "source": [ + "The pairs of input/output available are listed on the [Input/Output Types](https://palaimon.github.io/ipyannotator/nbs/22_input_output_doc.html) section. \n", + "\n", + "When working with the `Annotator` class the input type is always required, but the output type has a `NoOutput` default option that returns an annotator to explore the input images. `NoOutput` usage can be found on the [Bounding Box Annotator Tutorial](https://palaimon.github.io/ipyannotator/nbs/01c_tutorial_bbox.html#explore).\n", + "\n", + "The final piece of the configuration to access the Ipyannotator API is the `Settings` class that can be imported using `from ipyannotator.base import Settings`. Ipyannotator `Settings` class allow users to customize the folder structure to get the images, read annotations and store results, but also provides a default folder structure:\n", + "\n", + "```\n", + "user_project\n", + "│ annotation.json\n", + "│\n", + "└───images\n", + "│ │ 00001.png\n", + "│ │ 00002.png\n", + "│ │ ... \n", + "│\n", + "└───results\n", + " │ annotations.json\n", + "\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "747d6bc4", + "metadata": {}, + "outputs": [], + "source": [ + "#exporti\n", + "show_doc(Settings, title_level=4)" + ] + }, + { + "cell_type": "markdown", + "id": "6e53ec99", + "metadata": {}, + "source": [ + "## Actions" + ] + }, { "cell_type": "markdown", "id": "8d7d2c09", @@ -95,11 +149,19 @@ "from nbdev.export import notebook2script\n", "notebook2script()" ] + }, + { + "cell_type": "markdown", + "id": "b19da654", + "metadata": {}, + "source": [ + "## Settings" + ] } ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }