From cc57b761fc989055dcd1b3c21d3f1a8909ab9035 Mon Sep 17 00:00:00 2001 From: Amresh Venugopal Date: Fri, 9 Apr 2021 01:07:33 +0530 Subject: [PATCH 01/30] add: dependency sphinx --- poetry.lock | 196 ++++++++++++++++++++++++++++++++++++++++++++++++- pyproject.toml | 1 + 2 files changed, 196 insertions(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index c1fead73..f8dcd0c7 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,3 +1,11 @@ +[[package]] +category = "dev" +description = "A configurable sidebar-enabled Sphinx theme" +name = "alabaster" +optional = false +python-versions = "*" +version = "0.7.12" + [[package]] category = "dev" description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." @@ -42,6 +50,17 @@ docs = ["furo", "sphinx", "zope.interface"] tests = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] tests_no_zope = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"] +[[package]] +category = "dev" +description = "Internationalization utilities" +name = "babel" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "2.9.0" + +[package.dependencies] +pytz = ">=2015.7" + [[package]] category = "dev" description = "Security oriented static analyser for python code." @@ -166,6 +185,14 @@ optional = false python-versions = "*" version = "0.6.2" +[[package]] +category = "dev" +description = "Docutils -- Python Documentation Utilities" +name = "docutils" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "0.17" + [[package]] category = "dev" description = "Git Object Database" @@ -215,6 +242,14 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" version = "2.10" +[[package]] +category = "dev" +description = "Getting image size from png/jpeg/jpeg2000/gif file" +name = "imagesize" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "1.2.0" + [[package]] category = "dev" description = "iniconfig: brain-dead simple config-ini parsing" @@ -620,6 +655,117 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" version = "3.0.4" +[[package]] +category = "dev" +description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." +name = "snowballstemmer" +optional = false +python-versions = "*" +version = "2.1.0" + +[[package]] +category = "dev" +description = "Python documentation generator" +name = "sphinx" +optional = false +python-versions = ">=3.5" +version = "3.5.3" + +[package.dependencies] +Jinja2 = ">=2.3" +Pygments = ">=2.0" +alabaster = ">=0.7,<0.8" +babel = ">=1.3" +colorama = ">=0.3.5" +docutils = ">=0.12" +imagesize = "*" +packaging = "*" +requests = ">=2.5.0" +setuptools = "*" +snowballstemmer = ">=1.1" +sphinxcontrib-applehelp = "*" +sphinxcontrib-devhelp = "*" +sphinxcontrib-htmlhelp = "*" +sphinxcontrib-jsmath = "*" +sphinxcontrib-qthelp = "*" +sphinxcontrib-serializinghtml = "*" + +[package.extras] +docs = ["sphinxcontrib-websupport"] +lint = ["flake8 (>=3.5.0)", "isort", "mypy (>=0.800)", "docutils-stubs"] +test = ["pytest", "pytest-cov", "html5lib", "cython", "typed-ast"] + +[[package]] +category = "dev" +description = "sphinxcontrib-applehelp is a sphinx extension which outputs Apple help books" +name = "sphinxcontrib-applehelp" +optional = false +python-versions = ">=3.5" +version = "1.0.2" + +[package.extras] +lint = ["flake8", "mypy", "docutils-stubs"] +test = ["pytest"] + +[[package]] +category = "dev" +description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document." +name = "sphinxcontrib-devhelp" +optional = false +python-versions = ">=3.5" +version = "1.0.2" + +[package.extras] +lint = ["flake8", "mypy", "docutils-stubs"] +test = ["pytest"] + +[[package]] +category = "dev" +description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" +name = "sphinxcontrib-htmlhelp" +optional = false +python-versions = ">=3.5" +version = "1.0.3" + +[package.extras] +lint = ["flake8", "mypy", "docutils-stubs"] +test = ["pytest", "html5lib"] + +[[package]] +category = "dev" +description = "A sphinx extension which renders display math in HTML via JavaScript" +name = "sphinxcontrib-jsmath" +optional = false +python-versions = ">=3.5" +version = "1.0.1" + +[package.extras] +test = ["pytest", "flake8", "mypy"] + +[[package]] +category = "dev" +description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document." +name = "sphinxcontrib-qthelp" +optional = false +python-versions = ">=3.5" +version = "1.0.3" + +[package.extras] +lint = ["flake8", "mypy", "docutils-stubs"] +test = ["pytest"] + +[[package]] +category = "dev" +description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." +name = "sphinxcontrib-serializinghtml" +optional = false +python-versions = ">=3.5" +version = "1.1.4" + +[package.extras] +lint = ["flake8", "mypy", "docutils-stubs"] +test = ["pytest"] + [[package]] category = "dev" description = "Manage dynamic plugins for Python applications" @@ -688,11 +834,15 @@ python-versions = "*" version = "1.12.1" [metadata] -content-hash = "6e0567de679edbdabe1ba1daa82f8f37836a1145b60d778f65b510d2763e7c1f" +content-hash = "021a715dc2c2e9d500096c8f3a1b93668e4cb5ae3c6fc2fd47a1be7538fb6fad" lock-version = "1.0" python-versions = "^3.8" [metadata.files] +alabaster = [ + {file = "alabaster-0.7.12-py2.py3-none-any.whl", hash = "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359"}, + {file = "alabaster-0.7.12.tar.gz", hash = "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"}, +] appdirs = [ {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, @@ -709,6 +859,10 @@ attrs = [ {file = "attrs-20.3.0-py2.py3-none-any.whl", hash = "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6"}, {file = "attrs-20.3.0.tar.gz", hash = "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700"}, ] +babel = [ + {file = "Babel-2.9.0-py2.py3-none-any.whl", hash = "sha256:9d35c22fcc79893c3ecc85ac4a56cde1ecf3f19c540bba0922308a6c06ca6fa5"}, + {file = "Babel-2.9.0.tar.gz", hash = "sha256:da031ab54472314f210b0adcff1588ee5d1d1d0ba4dbd07b94dba82bde791e05"}, +] bandit = [ {file = "bandit-1.7.0-py3-none-any.whl", hash = "sha256:216be4d044209fa06cf2a3e51b319769a51be8318140659719aa7a115c35ed07"}, {file = "bandit-1.7.0.tar.gz", hash = "sha256:8a4c7415254d75df8ff3c3b15cfe9042ecee628a1e40b44c15a98890fbfc2608"}, @@ -794,6 +948,10 @@ coverage = [ docopt = [ {file = "docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"}, ] +docutils = [ + {file = "docutils-0.17-py2.py3-none-any.whl", hash = "sha256:a71042bb7207c03d5647f280427f14bfbd1a65c9eb84f4b341d85fafb6bb4bdf"}, + {file = "docutils-0.17.tar.gz", hash = "sha256:e2ffeea817964356ba4470efba7c2f42b6b0de0b04e66378507e3e2504bbff4c"}, +] gitdb = [ {file = "gitdb-4.0.5-py3-none-any.whl", hash = "sha256:91f36bfb1ab7949b3b40e23736db18231bf7593edada2ba5c3a174a7b23657ac"}, {file = "gitdb-4.0.5.tar.gz", hash = "sha256:c9e1f2d0db7ddb9a704c2a0217be31214e91a4fe1dea1efad19ae42ba0c285c9"}, @@ -813,6 +971,10 @@ idna = [ {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, {file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"}, ] +imagesize = [ + {file = "imagesize-1.2.0-py2.py3-none-any.whl", hash = "sha256:6965f19a6a2039c7d48bca7dba2473069ff854c36ae6f19d2cde309d998228a1"}, + {file = "imagesize-1.2.0.tar.gz", hash = "sha256:b1f6b5a4eab1f73479a50fb79fcf729514a900c341d8503d62a62dbc4127a2b1"}, +] iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, @@ -1119,6 +1281,38 @@ smmap = [ {file = "smmap-3.0.4-py2.py3-none-any.whl", hash = "sha256:54c44c197c819d5ef1991799a7e30b662d1e520f2ac75c9efbeb54a742214cf4"}, {file = "smmap-3.0.4.tar.gz", hash = "sha256:9c98bbd1f9786d22f14b3d4126894d56befb835ec90cef151af566c7e19b5d24"}, ] +snowballstemmer = [ + {file = "snowballstemmer-2.1.0-py2.py3-none-any.whl", hash = "sha256:b51b447bea85f9968c13b650126a888aabd4cb4463fca868ec596826325dedc2"}, + {file = "snowballstemmer-2.1.0.tar.gz", hash = "sha256:e997baa4f2e9139951b6f4c631bad912dfd3c792467e2f03d7239464af90e914"}, +] +sphinx = [ + {file = "Sphinx-3.5.3-py3-none-any.whl", hash = "sha256:3f01732296465648da43dec8fb40dc451ba79eb3e2cc5c6d79005fd98197107d"}, + {file = "Sphinx-3.5.3.tar.gz", hash = "sha256:ce9c228456131bab09a3d7d10ae58474de562a6f79abb3dc811ae401cf8c1abc"}, +] +sphinxcontrib-applehelp = [ + {file = "sphinxcontrib-applehelp-1.0.2.tar.gz", hash = "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"}, + {file = "sphinxcontrib_applehelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a"}, +] +sphinxcontrib-devhelp = [ + {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"}, + {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"}, +] +sphinxcontrib-htmlhelp = [ + {file = "sphinxcontrib-htmlhelp-1.0.3.tar.gz", hash = "sha256:e8f5bb7e31b2dbb25b9cc435c8ab7a79787ebf7f906155729338f3156d93659b"}, + {file = "sphinxcontrib_htmlhelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:3c0bc24a2c41e340ac37c85ced6dafc879ab485c095b1d65d2461ac2f7cca86f"}, +] +sphinxcontrib-jsmath = [ + {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, + {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, +] +sphinxcontrib-qthelp = [ + {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"}, + {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"}, +] +sphinxcontrib-serializinghtml = [ + {file = "sphinxcontrib-serializinghtml-1.1.4.tar.gz", hash = "sha256:eaa0eccc86e982a9b939b2b82d12cc5d013385ba5eadcc7e4fed23f4405f77bc"}, + {file = "sphinxcontrib_serializinghtml-1.1.4-py2.py3-none-any.whl", hash = "sha256:f242a81d423f59617a8e5cf16f5d4d74e28ee9a66f9e5b637a18082991db5a9a"}, +] stevedore = [ {file = "stevedore-3.3.0-py3-none-any.whl", hash = "sha256:50d7b78fbaf0d04cd62411188fa7eedcb03eb7f4c4b37005615ceebe582aa82a"}, {file = "stevedore-3.3.0.tar.gz", hash = "sha256:3a5bbd0652bf552748871eaa73a4a8dc2899786bc497a2aa1fcb4dcdb0debeee"}, diff --git a/pyproject.toml b/pyproject.toml index a5cb6ace..c31d6114 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,6 +28,7 @@ pylint = "^2.6.0" pycco = "^0.6.0" watchdog = "^1.0.2" isort = "^5.7.0" +sphinx = "^3.5.3" [tool.poetry.scripts] dialogy = "dialogy.cli:main" From 582985f9d61fd41d21a890d3057264ca5c971dc6 Mon Sep 17 00:00:00 2001 From: Amresh Venugopal Date: Fri, 9 Apr 2021 05:43:40 +0530 Subject: [PATCH 02/30] docs: remove tests from docs. --- docs/tests/__init__.html | 30 - docs/tests/parser/__init__.html | 30 - docs/tests/parser/text/__init__.html | 30 - docs/tests/parser/text/entity/__init__.html | 30 - docs/tests/parser/text/entity/config.html | 153 --- .../text/entity/test_duckling_parser.html | 893 ------------------ docs/tests/plugin/__init__.html | 30 - docs/tests/plugin/test_arbitrary_plugin.html | 416 -------- docs/tests/plugin/test_plugins.html | 425 --------- docs/tests/postprocess/__init__.html | 30 - docs/tests/postprocess/text/__init__.html | 30 - .../text/slot_filler/__init__.html | 30 - .../slot_filler/test_rule_slot_filler.html | 796 ---------------- .../postprocess/text/voting/__init__.html | 30 - .../postprocess/text/voting/test_intent.html | 291 ------ .../text/voting/test_intent_voting.html | 291 ------ docs/tests/postprocessors/__init__.html | 30 - docs/tests/postprocessors/text/__init__.html | 30 - .../text/slot_filler/__init__.html | 30 - .../slot_filler/test_rule_slot_filler.html | 149 --- docs/tests/preprocess/__init__.html | 30 - .../preprocess/test_merge_asr_output.html | 122 --- docs/tests/preprocess/text/__init__.html | 30 - .../text/test_merge_asr_output.html | 158 ---- .../text/test_normalize_utterance.html | 92 -- docs/tests/preprocessors/__init__.html | 30 - .../preprocessors/test_merge_asr_output.html | 122 --- docs/tests/types/__init__.html | 30 - docs/tests/types/entities/__init__.html | 30 - docs/tests/types/entities/test_entities.html | 344 ------- docs/tests/types/entities/test_utils.html | 105 -- docs/tests/types/entity/__init__.html | 30 - docs/tests/types/entity/test_entities.html | 539 ----------- docs/tests/types/entity/test_utils.html | 106 --- docs/tests/types/intents/__init__.html | 30 - docs/tests/types/intents/test_intents.html | 203 ---- docs/tests/types/slots/__init__.html | 30 - docs/tests/types/slots/test_slot.html | 31 - docs/tests/workflow/__init__.html | 30 - docs/tests/workflow/test_workflow.html | 437 --------- 40 files changed, 6303 deletions(-) delete mode 100644 docs/tests/__init__.html delete mode 100644 docs/tests/parser/__init__.html delete mode 100644 docs/tests/parser/text/__init__.html delete mode 100644 docs/tests/parser/text/entity/__init__.html delete mode 100644 docs/tests/parser/text/entity/config.html delete mode 100644 docs/tests/parser/text/entity/test_duckling_parser.html delete mode 100644 docs/tests/plugin/__init__.html delete mode 100644 docs/tests/plugin/test_arbitrary_plugin.html delete mode 100644 docs/tests/plugin/test_plugins.html delete mode 100644 docs/tests/postprocess/__init__.html delete mode 100644 docs/tests/postprocess/text/__init__.html delete mode 100644 docs/tests/postprocess/text/slot_filler/__init__.html delete mode 100644 docs/tests/postprocess/text/slot_filler/test_rule_slot_filler.html delete mode 100644 docs/tests/postprocess/text/voting/__init__.html delete mode 100644 docs/tests/postprocess/text/voting/test_intent.html delete mode 100644 docs/tests/postprocess/text/voting/test_intent_voting.html delete mode 100644 docs/tests/postprocessors/__init__.html delete mode 100644 docs/tests/postprocessors/text/__init__.html delete mode 100644 docs/tests/postprocessors/text/slot_filler/__init__.html delete mode 100644 docs/tests/postprocessors/text/slot_filler/test_rule_slot_filler.html delete mode 100644 docs/tests/preprocess/__init__.html delete mode 100644 docs/tests/preprocess/test_merge_asr_output.html delete mode 100644 docs/tests/preprocess/text/__init__.html delete mode 100644 docs/tests/preprocess/text/test_merge_asr_output.html delete mode 100644 docs/tests/preprocess/text/test_normalize_utterance.html delete mode 100644 docs/tests/preprocessors/__init__.html delete mode 100644 docs/tests/preprocessors/test_merge_asr_output.html delete mode 100644 docs/tests/types/__init__.html delete mode 100644 docs/tests/types/entities/__init__.html delete mode 100644 docs/tests/types/entities/test_entities.html delete mode 100644 docs/tests/types/entities/test_utils.html delete mode 100644 docs/tests/types/entity/__init__.html delete mode 100644 docs/tests/types/entity/test_entities.html delete mode 100644 docs/tests/types/entity/test_utils.html delete mode 100644 docs/tests/types/intents/__init__.html delete mode 100644 docs/tests/types/intents/test_intents.html delete mode 100644 docs/tests/types/slots/__init__.html delete mode 100644 docs/tests/types/slots/test_slot.html delete mode 100644 docs/tests/workflow/__init__.html delete mode 100644 docs/tests/workflow/test_workflow.html diff --git a/docs/tests/__init__.html b/docs/tests/__init__.html deleted file mode 100644 index 62dcb268..00000000 --- a/docs/tests/__init__.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - __init__.py - - - -
-
-
-

__init__.py

-
-
-
-
-
- # -
- -
-
-

-
-
-
-
-
-
- diff --git a/docs/tests/parser/__init__.html b/docs/tests/parser/__init__.html deleted file mode 100644 index 282d6589..00000000 --- a/docs/tests/parser/__init__.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - __init__.py - - - -
-
-
-

__init__.py

-
-
-
-
-
- # -
- -
-
-

-
-
-
-
-
-
- diff --git a/docs/tests/parser/text/__init__.html b/docs/tests/parser/text/__init__.html deleted file mode 100644 index 2f36ff57..00000000 --- a/docs/tests/parser/text/__init__.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - __init__.py - - - -
-
-
-

__init__.py

-
-
-
-
-
- # -
- -
-
-

-
-
-
-
-
-
- diff --git a/docs/tests/parser/text/entity/__init__.html b/docs/tests/parser/text/entity/__init__.html deleted file mode 100644 index 80a67825..00000000 --- a/docs/tests/parser/text/entity/__init__.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - __init__.py - - - -
-
-
-

__init__.py

-
-
-
-
-
- # -
- -
-
-

-
-
-
-
-
-
- diff --git a/docs/tests/parser/text/entity/config.html b/docs/tests/parser/text/entity/config.html deleted file mode 100644 index c2537f2c..00000000 --- a/docs/tests/parser/text/entity/config.html +++ /dev/null @@ -1,153 +0,0 @@ - - - - - config.py - - - -
-
-
-

config.py

-
-
-
-
-
- # -
- -
-
-
mock_number_entity = {
-    "body": "four",
-    "start": 7,
-    "value": {"value": 4, "type": "value"},
-    "end": 11,
-    "dim": "number",
-    "latent": False,
-}
-
-mock_date_entity = {
-    "body": "on 27th next month",
-    "start": 21,
-    "value": {
-        "values": [
-            {
-                "value": "2021-01-27T00:00:00.000-08:00",
-                "grain": "day",
-                "type": "value",
-            }
-        ],
-        "value": "2021-01-27T00:00:00.000-08:00",
-        "grain": "day",
-        "type": "value",
-    },
-    "end": 39,
-    "dim": "time",
-    "latent": False,
-}
-
-mock_time_entity = {
-    "body": "at 5 am",
-    "start": 55,
-    "value": {
-        "values": [
-            {
-                "value": "2020-12-24T05:00:00.000-08:00",
-                "grain": "hour",
-                "type": "value",
-            },
-            {
-                "value": "2020-12-25T05:00:00.000-08:00",
-                "grain": "hour",
-                "type": "value",
-            },
-            {
-                "value": "2020-12-26T05:00:00.000-08:00",
-                "grain": "hour",
-                "type": "value",
-            },
-        ],
-        "value": "2020-12-24T05:00:00.000-08:00",
-        "grain": "hour",
-        "type": "value",
-    },
-    "end": 62,
-    "dim": "time",
-    "latent": False,
-}
-
-mock_interval_entity = {
-    "body": "between 2 to 4 am",
-    "start": 0,
-    "value": {
-        "values": [
-            {
-                "to": {
-                    "value": "2021-01-22T05:00:00.000+05:30",
-                    "grain": "hour",
-                },
-                "from": {
-                    "value": "2021-01-22T02:00:00.000+05:30",
-                    "grain": "hour",
-                },
-                "type": "interval",
-            },
-            {
-                "to": {
-                    "value": "2021-01-23T05:00:00.000+05:30",
-                    "grain": "hour",
-                },
-                "from": {
-                    "value": "2021-01-23T02:00:00.000+05:30",
-                    "grain": "hour",
-                },
-                "type": "interval",
-            },
-            {
-                "to": {
-                    "value": "2021-01-24T05:00:00.000+05:30",
-                    "grain": "hour",
-                },
-                "from": {
-                    "value": "2021-01-24T02:00:00.000+05:30",
-                    "grain": "hour",
-                },
-                "type": "interval",
-            },
-        ],
-        "to": {"value": "2021-01-22T05:00:00.000+05:30", "grain": "hour"},
-        "from": {"value": "2021-01-22T02:00:00.000+05:30", "grain": "hour"},
-        "type": "interval",
-    },
-    "end": 17,
-    "dim": "time",
-    "latent": False,
-}
-
-mock_people_entity = {
-    "body": "3 people",
-    "start": 67,
-    "value": {"value": 3, "type": "value", "unit": "person"},
-    "end": 75,
-    "dim": "people",
-    "latent": False,
-}
-
-mock_unknown_entity = {
-    "body": "3 foobars",
-    "start": 67,
-    "value": {"value": 3, "type": "foobar", "unit": "person"},
-    "end": 75,
-    "dim": "number",
-    "latent": False,
-}
-
-
-
-
-
-
- diff --git a/docs/tests/parser/text/entity/test_duckling_parser.html b/docs/tests/parser/text/entity/test_duckling_parser.html deleted file mode 100644 index 00189fbf..00000000 --- a/docs/tests/parser/text/entity/test_duckling_parser.html +++ /dev/null @@ -1,893 +0,0 @@ - - - - - test_duckling_parser.py - - - -
-
-
-

test_duckling_parser.py

-
-
-
-
-
- # -
- -
-
-
import json
-from typing import Any, Callable, List
-
-import httpretty
-import pytest
-import pytz
-
-from dialogy.parser.text.entity import DucklingParser
-from dialogy.types.entity import (
-    NumericalEntity,
-    PeopleEntity,
-    TimeEntity,
-    TimeIntervalEntity,
-)
-from dialogy.workflow import Workflow
-from tests.parser.text.entity import config
-
-
-
-
-
-
- # -
- -
-
-
def request_builder(
-    expected_response, response_code=200
-) -> Callable[[Any, Any, Any], List[Any]]:
-    header = "application/x-www-form-urlencoded; charset=UTF-8"
-
-
-
-
-
-
- # -
- -
-
-
    def request_callback(request, _, response_headers) -> List[Any]:
-        content_type = request.headers.get("Content-Type")
-        assert (
-            content_type == header
-        ), f"expected {header} but received Content-Type: {content_type}"
-        return [response_code, response_headers, json.dumps(expected_response)]
-
-    return request_callback
-
-
-
-
-
-
- # -
-

Test successful api call

-
-
-
@httpretty.activate
-def test_duckling_api_success() -> None:
-
-
-
-
-
-
- # -
-

Initialize DucklingParser and .get_entities.

-

This test-case bypasses duckling API calls via httpretty. The expected response -was originally generated using:

-

-export month_q="I need four of those on 27th next month."
-export time_q="Can I have it at 5 am""&dims="[date"]"
-export text="$month_q $time_q"
-curl -XPOST http://0.0.0.0:8000/parse --data 'locale=en_US&text=$text'
-
-
-
-
    body = "I need four of those on 27th next month. Can I have it at 5 am"
-
-    expected_response = [
-        config.mock_number_entity,
-        config.mock_date_entity,
-        config.mock_time_entity,
-    ]
-
-    request_callback = request_builder(expected_response)
-    httpretty.register_uri(
-        httpretty.POST, "http://0.0.0.0:8000/parse", body=request_callback
-    )
-
-    parser = DucklingParser(locale="en_IN")
-
-    response = parser.get_entities(body)
-    assert response == expected_response
-
-
-
-
-
-
- # -
-

Test duckling api returning 500

-
-
-
@httpretty.activate
-def test_duckling_api_failure() -> None:
-
-
-
-
-
-
- # -
-

Simulate Duckling returning 500.

-
-
-
    body = "27th next month"
-    expected_response = [config.mock_date_entity]
-
-    request_callback = request_builder(expected_response, response_code=500)
-
-    httpretty.register_uri(
-        httpretty.POST, "http://0.0.0.0:8000/parse", body=request_callback
-    )
-
-    parser = DucklingParser(dimensions=["time"], locale="en_IN")
-
-    with pytest.raises(ValueError):
-        parser.get_entities(body)
-
-
-
-
-
-
- # -
-

Test duckling with timezone info

-
-
-
@httpretty.activate
-def test_duckling_with_tz() -> None:
-
-
-
-
-
-
- # -
-

Using DucklingParser with timezone.

-
-
-
    body = "i need it at 5 am"
-    expected_response = [config.mock_time_entity]
-
-    request_callback = request_builder(expected_response)
-    httpretty.register_uri(
-        httpretty.POST, "http://0.0.0.0:8000/parse", body=request_callback
-    )
-
-    parser = DucklingParser(locale="en_IN", timezone="Asia/Kolkata")
-
-    response = parser.get_entities(body)
-    assert response == expected_response
-
-
-
-
-
-
- # -
-

Test duckling with incorrect timezone

-
-
-
def test_duckling_wrong_tz() -> None:
-
-
-
-
-
-
- # -
-

In case the timezone is incorrect or exceptions need to be handled.

-
-
-
    body = "i need it at 5 am"
-
-    request_callback = request_builder({})
-    httpretty.register_uri(
-        httpretty.POST, "http://0.0.0.0:8000/parse", body=request_callback
-    )
-
-    parser = DucklingParser(locale="en_IN", timezone="Earth/Someplace")
-
-    with pytest.raises(pytz.UnknownTimeZoneError):
-        _ = parser.get_entities(body)
-
-
-
-
-
-
- # -
-

Test entity structure modifications for numerical entities

-
-
-
def test_entity_mutation_dict() -> None:
-
-
-
-
-
-
- # -
-

This piece of code is run by DucklingParser when the Duckling API -returns a set of entities. There are a few keys added/removed. -We are making sure of those for numerical entities here.

-
-
-
    entities_json = config.mock_number_entity
-    parser = DucklingParser(locale="en_IN")
-    entity = parser.mutate_entity(entities_json)
-
-    assert "range" in entity
-    assert "start" in entity["range"]
-    assert "end" in entity["range"]
-    assert "values" in entity
-    assert entity["values"][0]["value"] == 4
-
-
-
-
-
-
- # -
-

Test entity structure modifications for time entities

-
-
-
def test_entity_mutation_list() -> None:
-
-
-
-
-
-
- # -
-

This piece of code is run by DucklingParser when the Duckling API -returns a set of entities. There are a few keys added/removed. -We are making sure of those for time entities here.

-
-
-
    entity_json = {
-        "body": "at 5 am",
-        "start": 55,
-        "value": {
-            "values": [
-                {
-                    "value": "2021-01-21T05:00:00.000+05:30",
-                    "grain": "hour",
-                    "type": "value",
-                },
-                {
-                    "value": "2021-01-22T05:00:00.000+05:30",
-                    "grain": "hour",
-                    "type": "value",
-                },
-                {
-                    "value": "2021-01-23T05:00:00.000+05:30",
-                    "grain": "hour",
-                    "type": "value",
-                },
-            ],
-            "value": "2021-01-21T05:00:00.000+05:30",
-            "grain": "hour",
-            "type": "value",
-        },
-        "end": 62,
-        "dim": "time",
-        "latent": False,
-    }
-
-    parser = DucklingParser(locale="en_IN")
-    entity = parser.mutate_entity(entity_json)
-
-    assert "range" in entity
-    assert "start" in entity["range"]
-    assert "end" in entity["range"]
-    assert "values" in entity
-    assert "value" not in entity
-    assert entity["values"][0]["value"] == "2021-01-21T05:00:00.000+05:30"
-
-
-
-
-
-
- # -
-

Test transformation of entity-json to TimeEntity

-
-
-
def test_entity_json_to_object_time_entity() -> None:
-
-
-
-
-
-
- # -
-

Reshape converts json response from Duckling APIs -to dialogy’s BaseEntity.

-

We are checking for TimeEntity here.

-
-
-
    parser = DucklingParser(locale="en_IN")
-    entities_json = [config.mock_time_entity]
-
-    entities = parser.reshape(entities_json)
-    assert isinstance(entities[0], TimeEntity)
-
-
-
-
-
-
- # -
-

Test transformation of entity-json to TimeIntervalEntity

-
-
-
def test_entity_json_to_object_time_interval_entity():
-
-
-
-
-
-
- # -
-

Reshape converts json response from Duckling APIs -to dialogy’s BaseEntity.

-

We are checking for TimeIntervalEntity here.

-
-
-
    parser = DucklingParser(locale="en_IN")
-    entities_json = [config.mock_interval_entity]
-
-    entities = parser.reshape(entities_json)
-    assert isinstance(entities[0], TimeIntervalEntity)
-
-
-
-
-
-
- # -
-

Test transformation of entity-json to NumericalEntity

-
-
-
def test_entity_json_to_object_numerical_entity() -> None:
-
-
-
-
-
-
- # -
-

Reshape converts json response from Duckling APIs -to dialogy’s BaseEntity.

-

We are checking for NumericalEntity here.

-
-
-
    entities_json = [
-        {
-            "body": "four",
-            "start": 7,
-            "value": {"value": 4, "type": "value"},
-            "end": 11,
-            "dim": "number",
-            "latent": False,
-        }
-    ]
-    parser = DucklingParser(locale="en_IN")
-    entities = parser.reshape(entities_json)
-    assert isinstance(entities[0], NumericalEntity)
-
-
-
-
-
-
- # -
-

Test transformation of entity-json to PeopleEntity

-
-
-
def test_entity_json_to_object_people_entity() -> None:
-
-
-
-
-
-
- # -
-

Reshape converts json response from Duckling APIs -to dialogy’s BaseEntity.

-

We are checking for PeopleEntity here.

-
-
-
    entities_json = [config.mock_people_entity]
-    parser = DucklingParser(locale="en_IN")
-    entities = parser.reshape(entities_json)
-    assert isinstance(entities[0], PeopleEntity)
-
-
-
-
-
-
- # -
-

Test transformation of unknown entity type

-
-
-
def test_entity_object_not_implemented() -> None:
-
-
-
-
-
-
- # -
-

Reshape converts json response from Duckling APIs -to dialogy’s BaseEntity.

-

We are checking for an unknown entity type here. -This would lead to a NotImplementedError.

-
-
-
    entities_json = [config.mock_unknown_entity]
-    parser = DucklingParser(locale="en_IN")
-
-    with pytest.raises(NotImplementedError):
-        parser.reshape(entities_json)
-
-
-
-
-
-
- # -
-

Test transormation of entity-json with missing value.

-
-
-
def test_entity_object_error_on_missing_value() -> None:
-
-
-
-
-
-
- # -
-

This json has missing value key. We can see that we will get a -KeyError raised, this happens during the validation phase.

-
-
-
    entities_json = [
-        {
-            "body": "3 people",
-            "start": 67,
-            "end": 75,
-            "dim": "people",
-            "latent": False,
-        }
-    ]
-    parser = DucklingParser(locale="en_IN")
-
-    with pytest.raises(KeyError):
-        parser.reshape(entities_json)
-
-
-
-
-
-
- # -
-

Test missing i/o

-
-
-
def test_plugin_io_missing() -> None:
-
-
-
-
-
-
- # -
-

Here we are chcking if the plugin has access to workflow. -Since we haven’t provided access, mutate to DucklingParser -we will receive a TypeError.

-
-
-
    parser = DucklingParser(locale="en_IN")
-    plugin = parser()
-
-    workflow = Workflow(preprocessors=[plugin], postprocessors=[])
-    with pytest.raises(TypeError):
-        workflow.run("")
-
-
-
-
-
-
- # -
-

Test invalid i/o

-
-
-
@pytest.mark.parametrize(
-    "access,mutate",
-    [
-        (1, 1),
-        (lambda x: x, 1),
-        (1, lambda x: x),
-    ],
-)
-def test_plugin_io_type_mismatch(access, mutate) -> None:
-
-
-
-
-
-
- # -
-

Here we are chcking if the plugin has access to workflow. -Since we have provided access, mutate of incorrect types to DucklingParser -we will receive a TypeError.

-
-
-
    parser = DucklingParser(access=access, mutate=mutate, locale="en_IN")
-    plugin = parser()
-
-    workflow = Workflow(preprocessors=[plugin], postprocessors=[])
-    with pytest.raises(TypeError):
-        workflow.run("")
-
-
-
-
-
-
- # -
-

Test plugin usage with Worfklow

-
-
-
@pytest.mark.parametrize(
-    "body,expected",
-    [
-        (
-            "I need it for 3 people.",
-            [
-                {
-                    "body": "4 people",
-                    "start": 14,
-                    "value": {"value": 4, "type": "value", "unit": "person"},
-                    "end": 22,
-                    "dim": "people",
-                    "latent": False,
-                }
-            ],
-        ),
-        (
-            ["I need it for 3 people."],
-            [
-                {
-                    "body": "4 people",
-                    "start": 14,
-                    "value": {"value": 4, "type": "value", "unit": "person"},
-                    "end": 22,
-                    "dim": "people",
-                    "latent": False,
-                }
-            ],
-        ),
-    ],
-)
-@httpretty.activate
-def test_plugin(body, expected) -> None:
-
-
-
-
-
-
- # -
-

An end-to-end example showing how to use DucklingParser with a Worflow.

-
-
-
-
-
-
-
-
-
- # -
- -
-
-
    def access(workflow):
-        return workflow.input, None
-
-
-
-
-
-
- # -
- -
-
-
    def mutate(workflow, entities):
-        workflow.output = {"entities": entities}
-
-    parser = DucklingParser(
-        access=access, mutate=mutate, dimensions=["people"], locale="en_IN"
-    )
-
-    request_callback = request_builder(expected)
-    httpretty.register_uri(
-        httpretty.POST, "http://0.0.0.0:8000/parse", body=request_callback
-    )
-
-    workflow = Workflow(preprocessors=[parser()], postprocessors=[])
-    workflow.run(body)
-    assert isinstance(workflow.output["entities"][0], PeopleEntity)
-
-
-
-
-
-
- # -
-

Test plugin with no possible entity from input.

-
-
-
@httpretty.activate
-def test_plugin_no_entities() -> None:
-
-
-
-
-
-
- # -
-

An end-to-end example showing how DucklingParser works in case -the input has no entities.

-
-
-
    body = "i need it"
-    expected = []
-
-
-
-
-
-
- # -
- -
-
-
    def access(workflow):
-        return workflow.input, None
-
-
-
-
-
-
- # -
- -
-
-
    def mutate(workflow, entities):
-        workflow.output = {"entities": entities}
-
-    parser = DucklingParser(
-        access=access, mutate=mutate, dimensions=["people"], locale="en_IN"
-    )
-
-    request_callback = request_builder(expected)
-    httpretty.register_uri(
-        httpretty.POST, "http://0.0.0.0:8000/parse", body=request_callback
-    )
-
-    workflow = Workflow(preprocessors=[parser()], postprocessors=[])
-    workflow.run(body)
-    assert workflow.output["entities"] == []
-
-
-
-
-
-
- # -
-

An end-to-end example showing how DucklingParser works in case -the input is invalid.

-
-
-
@pytest.mark.parametrize(
-    "body",
-    [42, None, {"key", 42}, [12]],
-)
-@httpretty.activate
-def test_plugin_type_errors(body) -> None:
-
-
-
-
-
-
- # -
- -
-
-
-
-
-
-
-
-
- # -
- -
-
-
    def access(workflow):
-        return workflow.input, None
-
-
-
-
-
-
- # -
- -
-
-
    def mutate(workflow, entities):
-        workflow.output = {"entities": entities}
-
-    parser = DucklingParser(
-        access=access, mutate=mutate, dimensions=["people"], locale="en_IN"
-    )
-
-    request_callback = request_builder([])
-    httpretty.register_uri(
-        httpretty.POST, "http://0.0.0.0:8000/parse", body=request_callback
-    )
-
-    with pytest.raises(TypeError):
-        workflow = Workflow(preprocessors=[parser()], postprocessors=[])
-        workflow.run(body)
-
-
-
-
-
-
- # -
-

An end-to-end example showing how DucklingParser works in case -the input is invalid.

-
-
-
@httpretty.activate
-def test_plugin_value_errors() -> None:
-
-
-
-
-
-
- # -
- -
-
-
-
-
-
-
-
-
- # -
- -
-
-
    def access(workflow):
-        return workflow.input, None
-
-
-
-
-
-
- # -
- -
-
-
    def mutate(workflow, entities):
-        workflow.output = {"entities": entities}
-
-    parser = DucklingParser(
-        access=access, mutate=mutate, dimensions=["people"], locale="en_IN"
-    )
-
-    request_callback = request_builder([], response_code=500)
-    httpretty.register_uri(
-        httpretty.POST, "http://0.0.0.0:8000/parse", body=request_callback
-    )
-
-    with pytest.raises(ValueError):
-        workflow = Workflow(preprocessors=[parser()], postprocessors=[])
-        workflow.run("")
-
-
-
-
-
-
- diff --git a/docs/tests/plugin/__init__.html b/docs/tests/plugin/__init__.html deleted file mode 100644 index 282d6589..00000000 --- a/docs/tests/plugin/__init__.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - __init__.py - - - -
-
-
-

__init__.py

-
-
-
-
-
- # -
- -
-
-

-
-
-
-
-
-
- diff --git a/docs/tests/plugin/test_arbitrary_plugin.html b/docs/tests/plugin/test_arbitrary_plugin.html deleted file mode 100644 index 8bd7aeb5..00000000 --- a/docs/tests/plugin/test_arbitrary_plugin.html +++ /dev/null @@ -1,416 +0,0 @@ - - - - - test_arbitrary_plugin.py - - - -
-
-
-

test_arbitrary_plugin.py

-
-
-
-
-
- # -
-

This is a tutorial on creating Plugins.

-
-
-
import re
-from typing import Optional, Any
-
-import attr
-
-from dialogy.plugin import Plugin
-from dialogy.workflow import Workflow
-from dialogy.types.plugin import PluginFn
-
-
-
-
-
-
- # -
-

tokenizer_plugin

-
-
-
def tokenizer_plugin(
-    pattern: str = r" ",
-    maxsplit: int = 0,
-    flags: int = re.I | re.U,
-    access: Optional[PluginFn] = None,
-    mutate: Optional[PluginFn] = None,
-) -> PluginFn:
-
-
-
-
-
-
- # -
-

Expects a string from the access(workflow) and tokenizes the string. -Example: “an apple” -> [“an”, “apple”]

-

Args: - pattern (str, optional): The string to be tokenized, probably a sentence or document. Defaults to r” “. - maxsplit (int, optional): Number of splits for a given pattern, with 0 being an exception, 0 splits for every pattern match. Defaults to 0. - flags ([type], optional): Pattern matching would be case-insensitive and applicable on unicode. Defaults to re.I|re.U.

-

Raises: - TypeError: If there is no input string. - ValueError: If the string is empty (0 length).

-

Returns: - PluginFn: Tokenizer

-

Always compile strings before using them in loops.

-
-
-
    compiled_pattern = re.compile(pattern, flags=flags)
-
-
-
-
-
-
- # -
- -
-
-
    def plugin(workflow: Workflow) -> Any:
-        if access and mutate:
-
-
-
-
-
-
- # -
-

assuming consumers would have workflow.input as str.

-
-
-
            text = access(workflow)
-            if not isinstance(text, str):
-                raise TypeError(f"Expected str found {type(text)}.")
-            if not text:
-                raise ValueError("Expected str of non-zero length.")
-
-
-
-
-
-
- # -
-

assuming the previously held value is of no relevance.

-
-
-
            mutate(workflow, compiled_pattern.split(text, maxsplit=maxsplit))
-        else:
-            raise TypeError("access and mutate should be of type PluginFn.")
-
-    return plugin
-
-
-
-
-
-
- # -
-

ArbitraryPlugin

-
-
-
@attr.s
-class ArbitraryPlugin(Plugin):
-
-
-
-
-
-
- # -
-

A Plugin class example.

-

We can create Plugins using python classes. If we extend from -the Plugin class, we get the access and mutate -attributes.

-

The access and mutate values are set to None because there are cases where you may -only need to perform computation. Say metric plugins, which could be a set of post-processing -plugins that evaluate the workflow but have nothing to insert into it.

-

These utilities would be forced to hack a value around to satisfy the type-checking, this -can be avoided by expecting either of the functions to be of type NoneType or PluginFn.

-
-
-
    access: Optional[PluginFn] = attr.ib(default=None)
-    mutate: Optional[PluginFn] = attr.ib(default=None)
-
-
-
-
-
-
- # -
-

plugin

-
-
-
    def plugin(self, workflow: Workflow) -> None:
-
-
-
-
-
-
- # -
-

Expects a tuple from access(workflow) that contains numbers and words.

-

Where

-
    -
  • numbers: A list of numbers.
  • -
  • words: A list of strings.
  • -
-

This plugin will:

-
    -
  • Increase each number in numbers by 2.
  • -
  • Concatenate ” world” after each word in words.
  • -
-

The plugin method is the place for implementing -plugin logic.

-
    -
  • If values need to be persisted? store them in class attributes.
  • -
  • If A set of validation, API calls etc are dependencies to run the implementation? -create separate methods and call them here.
  • -
-

Args: - workflow (Workflow): The workflow we possibly want to modify.

-
-
-
        if self.access and self.mutate:
-
-
-
-
-
-
- # -
-

We are expecting numbers and words from the workflow. -The owner of the workflow defines the access and mutate methods, so -as a plugin author, you can document the input and output types and -expect things to work.

-
-
-
            numbers, words = self.access(workflow)
-
-
-
-
-
-
- # -
-

Trivial data manipulation. A serious example would have been canonicalization -of sentences to replace tokens with classes they represent for improving -performance in a classification task.

-
-
-
            numbers = [number + 2 for number in numbers]
-            words = [word + " world" for word in words]
-            self.mutate(workflow, (numbers, words))
-        else:
-            raise TypeError("access and mutate should be of type PluginFn.")
-
-
-
-
-
-
- # -
-

call

-
-
-
    def __call__(self) -> PluginFn:
-
-
-
-
-
-
- # -
-

this is required only for code-coverage.

-
-
-
        super().__call__()
-
-
-
-
-
-
- # -
-

return the plugin method.

-
-
-
        return self.plugin
-
-
-
-
-
-
- # -
-

access

-
-
-
def access(workflow: Workflow) -> Any:
-
-
-
-
-
-
- # -
-

This functions would be provided by the -workflow implementer.

-
-
-
    return workflow.input
-
-
-
-
-
-
- # -
-

mutate

-
-
-
def mutate(workflow: Workflow, value: Any) -> Any:
-
-
-
-
-
-
- # -
-

This functions would be provided by the -workflow implementer.

-
-
-
    workflow.output = value
-
-
-
-
-
-
- # -
-

Plugin with Workflow

-
-
-
def test_arbitrary_plugin() -> None:
-
-
-
-
-
-
- # -
-

We will test how an arbitrary-class-based plugin works with a workflow.

-

create an instance of ArbitraryPlugin.

-
-
-
    arbitrary_plugin = ArbitraryPlugin(access=access, mutate=mutate)
-
-
-
-
-
-
- # -
-

create an instance of a Workflow. -we are calling the arbitrary_plugin to get the plugin de method.

-
-
-
    workflow = Workflow(preprocessors=[arbitrary_plugin()], postprocessors=[])
-
-
-
-
-
-
- # -
-

This runs all the preprocessors and postprocessors provided previously. -we can expect our arbitrary_plugin will also be used.

-
-
-
    workflow.run(([2, 5], ["hello", "hi"]))
-
-    numbers, words = workflow.output  # pylint: disable=unpacking-non-sequence
-
-
-
-
-
-
- # -
-

This test would pass only if our plugin works correctly!

-
-
-
    assert numbers == [4, 7]
-    assert words == ["hello world", "hi world"]
-
-
-
-
-
-
- # -
-

We will test the tokenizer plugin.

-
-
-
def test_tokenizer_plugin() -> None:
-
-
-
-
-
-
- # -
-

create an instance of a Workflow. -we are calling the arbitrary_plugin to get the plugin de method.

-
-
-
    workflow = Workflow(
-        preprocessors=[tokenizer_plugin(access=access, mutate=mutate)],
-        postprocessors=[],
-    )
-    workflow.run("Mary had a little lambda")
-
-    assert workflow.output == ["Mary", "had", "a", "little", "lambda"]
-
-
-
-
-
-
- diff --git a/docs/tests/plugin/test_plugins.html b/docs/tests/plugin/test_plugins.html deleted file mode 100644 index a629650f..00000000 --- a/docs/tests/plugin/test_plugins.html +++ /dev/null @@ -1,425 +0,0 @@ - - - - - test_plugins.py - - - -
-
-
-

test_plugins.py

-
-
-
-
-
- # -
-

This is a tutorial on creating and using Plugins with Workflows.

-
-
-
import re
-from typing import Any, Optional
-
-import attr
-
-from dialogy.plugin import Plugin
-from dialogy.types.plugin import PluginFn
-from dialogy.workflow import Workflow
-
-
-
-
-
-
- # -
-

This function would be provided by the -workflow implementer.

-
-
-
def access(workflow: Workflow) -> Any:
-
-
-
-
-
-
- # -
- -
-
-
    return workflow.input
-
-
-
-
-
-
- # -
-

This function would be provided by the -workflow implementer.

-
-
-
def mutate(workflow: Workflow, value: Any) -> Any:
-
-
-
-
-
-
- # -
- -
-
-
    workflow.output = value
-
-
-
-
-
-
- # -
-

tokenizer_plugin

-
-
-
def tokenizer_plugin(
-    pattern: str = r" ",
-    maxsplit: int = 0,
-    flags: int = re.I | re.U,
-    access: Optional[PluginFn] = None,
-    mutate: Optional[PluginFn] = None,
-) -> PluginFn:
-
-
-
-
-
-
- # -
-

Expects a string from the access(workflow) and tokenizes the string. -Example: “an apple” -> [“an”, “apple”]

-

Args:

-
    -
  • pattern (str, optional): The string to be tokenized, probably a sentence or document. Defaults to r” “.
  • -
  • maxsplit (int, optional): Number of splits for a given pattern, with 0 being an exception, 0 splits for every pattern match. Defaults to 0.
  • -
  • flags ([type], optional): Pattern matching would be case-insensitive and applicable on unicode. Defaults to re.I|re.U.
  • -
-

Raises:

-
    -
  • TypeError: If there is no input string.
  • -
  • ValueError: If the string is empty (0 length).
  • -
-

Returns:

-
    -
  • PluginFn: Tokenizer
  • -
-

Always compile strings before using them in loops.

-
-
-
    compiled_pattern = re.compile(pattern, flags=flags)
-
-
-
-
-
-
- # -
- -
-
-
    def plugin(workflow: Workflow) -> Any:
-        if access and mutate:
-
-
-
-
-
-
- # -
-

assuming consumers would have workflow.input as str.

-
-
-
            text = access(workflow)
-            if not isinstance(text, str):
-                raise TypeError(f"Expected str found {type(text)}.")
-            if not text:
-                raise ValueError("Expected str of non-zero length.")
-
-
-
-
-
-
- # -
-

assuming the previously held value is of no relevance.

-
-
-
            mutate(workflow, compiled_pattern.split(text, maxsplit=maxsplit))
-        else:
-            raise TypeError("access and mutate should be of type PluginFn.")
-
-    return plugin
-
-
-
-
-
-
- # -
-

Plugin as a function with workflow

-
-
-
def test_tokenizer_plugin() -> None:
-
-
-
-
-
-
- # -
-

We will test the tokenizer plugin.

-

create an instance of a Workflow. -we are calling the arbitrary_plugin to get the plugin de method.

-
-
-
    workflow = Workflow(
-        preprocessors=[tokenizer_plugin(access=access, mutate=mutate)],
-        postprocessors=[],
-    )
-    workflow.run("Mary had a little lambda")
-
-    assert workflow.output == ["Mary", "had", "a", "little", "lambda"]
-
-
-
-
-
-
- # -
-

ArbitraryPlugin

-
-
-
@attr.s
-class ArbitraryPlugin(Plugin):
-
-
-
-
-
-
- # -
-

A Plugin class example.

-

We can create Plugins using python classes. If we extend from -the Plugin class, we get the access and mutate -attributes.

-

The access and mutate values are set to None because there are cases where you may -only need to perform computation. Say metric plugins, which could be a set of post-processing -plugins that evaluate the workflow but have nothing to insert into it.

-

These utilities would be forced to hack a value around to satisfy the type-checking, this -can be avoided by expecting either of the functions to be of type NoneType or PluginFn.

-
-
-
    access: Optional[PluginFn] = attr.ib(default=None)
-    mutate: Optional[PluginFn] = attr.ib(default=None)
-
-
-
-
-
-
- # -
-

plugin

-
-
-
    def plugin(self, workflow: Workflow) -> None:
-
-
-
-
-
-
- # -
-

Expects a tuple from access(workflow) that contains numbers and words.

-

Where

-
    -
  • numbers: A list of numbers.
  • -
  • words: A list of strings.
  • -
-

This plugin will:

-
    -
  • Increase each number in numbers by 2.
  • -
  • Concatenate ” world” after each word in words.
  • -
-

The plugin method is the place for implementing -plugin logic.

-
    -
  • If values need to be persisted? store them in class attributes.
  • -
  • If A set of validation, API calls etc are dependencies to run the implementation? -create separate methods and call them here.
  • -
-

Args:

-
    -
  • workflow (Workflow): The workflow we possibly want to modify.
  • -
-
-
-
        if self.access and self.mutate:
-
-
-
-
-
-
- # -
-

We are expecting numbers and words from the workflow. -The owner of the workflow defines the access and mutate methods, so -as a plugin author, you can document the input and output types and -expect things to work.

-
-
-
            numbers, words = self.access(workflow)
-
-
-
-
-
-
- # -
-

Trivial data manipulation. A serious example would have been canonicalization -of sentences to replace tokens with classes they represent for improving -performance in a classification task.

-
-
-
            numbers = [number + 2 for number in numbers]
-            words = [word + " world" for word in words]
-            self.mutate(workflow, (numbers, words))
-        else:
-            raise TypeError("access and mutate should be of type PluginFn.")
-
-
-
-
-
-
- # -
-

call

-
-
-
    def __call__(self) -> PluginFn:
-
-
-
-
-
-
- # -
-

this is required only for code-coverage.

-
-
-
        super().__call__()
-
-
-
-
-
-
- # -
-

return the plugin method.

-
-
-
        return self.plugin
-
-
-
-
-
-
- # -
-

Plugin as a class with workflow

-
-
-
def test_arbitrary_plugin() -> None:
-
-
-
-
-
-
- # -
-

We will test how an arbitrary-class-based plugin works with a workflow.

-

create an instance of ArbitraryPlugin.

-
-
-
    arbitrary_plugin = ArbitraryPlugin(access=access, mutate=mutate)
-
-
-
-
-
-
- # -
-

create an instance of a Workflow. -we are calling the arbitrary_plugin to get the plugin de method.

-
-
-
    workflow = Workflow(preprocessors=[arbitrary_plugin()], postprocessors=[])
-
-
-
-
-
-
- # -
-

This runs all the preprocessors and postprocessors provided previously. -we can expect our arbitrary_plugin will also be used.

-
-
-
    workflow.run(([2, 5], ["hello", "hi"]))
-
-    numbers, words = workflow.output  # pylint: disable=unpacking-non-sequence
-
-
-
-
-
-
- # -
-

This test would pass only if our plugin works correctly!

-
-
-
    assert numbers == [4, 7]
-    assert words == ["hello world", "hi world"]
-
-
-
-
-
-
- diff --git a/docs/tests/postprocess/__init__.html b/docs/tests/postprocess/__init__.html deleted file mode 100644 index 282d6589..00000000 --- a/docs/tests/postprocess/__init__.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - __init__.py - - - -
-
-
-

__init__.py

-
-
-
-
-
- # -
- -
-
-

-
-
-
-
-
-
- diff --git a/docs/tests/postprocess/text/__init__.html b/docs/tests/postprocess/text/__init__.html deleted file mode 100644 index 2f36ff57..00000000 --- a/docs/tests/postprocess/text/__init__.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - __init__.py - - - -
-
-
-

__init__.py

-
-
-
-
-
- # -
- -
-
-

-
-
-
-
-
-
- diff --git a/docs/tests/postprocess/text/slot_filler/__init__.html b/docs/tests/postprocess/text/slot_filler/__init__.html deleted file mode 100644 index 80a67825..00000000 --- a/docs/tests/postprocess/text/slot_filler/__init__.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - __init__.py - - - -
-
-
-

__init__.py

-
-
-
-
-
- # -
- -
-
-

-
-
-
-
-
-
- diff --git a/docs/tests/postprocess/text/slot_filler/test_rule_slot_filler.html b/docs/tests/postprocess/text/slot_filler/test_rule_slot_filler.html deleted file mode 100644 index 8c29b542..00000000 --- a/docs/tests/postprocess/text/slot_filler/test_rule_slot_filler.html +++ /dev/null @@ -1,796 +0,0 @@ - - - - - test_rule_slot_filler.py - - - -
-
-
-

test_rule_slot_filler.py

-
-
-
-
-
- # -
-

This is a tutorial for understanding the use of RuleBasedSlotFillerPlugin.

-
-
-
from typing import Any
-
-import pytest
-
-from dialogy.postprocess.text.slot_filler.rule_slot_filler import (
-    RuleBasedSlotFillerPlugin,
-)
-from dialogy.types.entity import BaseEntity
-from dialogy.types.intent import Intent
-from dialogy.workflow import Workflow
-
-
-
-
-
-
- # -
-

This tutorial would be centered around these rules:

-
-
-
rules = {
-    "intent_1": {
-        "entity_1_slot": "entity_1"
-
-
-
-
-
-
- # -
-

This means, entity_1 will reside in a slot named entity_1_slot for intent_1.

-
-
-
    },
-    "intent_2": {
-        "entity_1_slot": "entity_1",
-        "entity_2_slot": "entity_2",
-    },
-}
-
-
-
-
-
-
- # -
-

This test case covers a trivial usage of a slot-filler. -We have rules that demonstrate association of intents with entities and their respective slot-configuration.

-
-
-
def test_slot_filling() -> None:
-
-
-
-
-
-
- # -
- -
-
-
-
-
-
-
-
-
- # -
- -
-
-
    def access(workflow: Workflow) -> Any:
-        return workflow.output
-
-    intent_name = "intent_1"
-
-
-
-
-
-
- # -
-

Setting up the slot-filler, both instantiation and plugin is created. (notice two calls).

-
-
-
    slot_filler = RuleBasedSlotFillerPlugin(rules=rules, access=access)()
-
-
-
-
-
-
- # -
-

Create a mock workflow

-
-
-
    workflow = Workflow(preprocessors=[], postprocessors=[slot_filler])
-
-
-
-
-
-
- # -
-

… a mock Intent

-
-
-
    intent = Intent(name=intent_name, score=0.8)
-
-
-
-
-
-
- # -
-

and a mock Entity.

-
-
-
    body = "12th december"
-    entity = BaseEntity(
-        range={"from": 0, "to": len(body)},
-        body=body,
-        dim="default",
-        type="entity_1",
-        values=[{"key": "value"}],
-        slot_names=["entity_1_slot"],
-    )
-
-
-
-
-
-
- # -
-

The RuleBasedSlotFillerPlugin specifies that it expects Tuple[Intent, List[Entity]) on access(workflow).

-
-
-
    workflow.output = (intent, [entity])
-    workflow.run(body)
-
-
-
-
-
-
- # -
-

workflow.output[0] is the Intent we created. -so we are checking if the entity_1_slot is filled by our mock entity.

-
-
-
    assert workflow.output[0].slots["entity_1_slot"].values[0] == entity
-
-
-
-
-
-
- # -
-

Here, we will see that an entity will not fill an intent unless the intent has a slot for it. -intent_1 doesn’t have a slot for an entity of type entity_2.

-
-
-
def test_slot_no_fill() -> None:
-
-
-
-
-
-
- # -
- -
-
-
-
-
-
-
-
-
- # -
- -
-
-
    def access(workflow: Workflow) -> Any:
-        return workflow.output
-
-    intent_name = "intent_1"
-
-
-
-
-
-
- # -
-

Setting up the slot-filler, both instantiation and plugin is created. (notice two calls).

-
-
-
    slot_filler = RuleBasedSlotFillerPlugin(rules=rules, access=access)()
-
-
-
-
-
-
- # -
-

Create a mock workflow

-
-
-
    workflow = Workflow(preprocessors=[], postprocessors=[slot_filler])
-
-
-
-
-
-
- # -
-

… a mock Intent

-
-
-
    intent = Intent(name=intent_name, score=0.8)
-
-
-
-
-
-
- # -
-

and a mock Entity.

-
-
-
    body = "12th december"
-    entity = BaseEntity(
-        range={"from": 0, "to": len(body)},
-        body=body,
-        dim="default",
-        type="entity_2",
-        values=[{"key": "value"}],
-        slot_names=["entity_2_slot"],
-    )
-
-
-
-
-
-
- # -
-

The RuleBasedSlotFillerPlugin specifies that it expects Tuple[Intent, List[Entity]) on access(workflow).

-
-
-
    workflow.output = (intent, [entity])
-    workflow.run(body)
-
-
-
-
-
-
- # -
-

workflow.output[0] is the Intent we created. -we can see that the entity_2_slot is not filled by our mock entity.

-
-
-
    assert "entity_1_slot" not in workflow.output[0].slots
-
-
-
-
-
-
- # -
-

Let’s try filling both the slots this time! -intent_2 supports both entity_1 and entity_2.

-
-
-
def test_slot_dual_fill() -> None:
-
-
-
-
-
-
- # -
- -
-
-
-
-
-
-
-
-
- # -
- -
-
-
    def access(workflow: Workflow) -> Any:
-        return workflow.output
-
-    intent_name = "intent_2"
-
-
-
-
-
-
- # -
-

Setting up the slot-filler, both instantiation and plugin is created. (notice two calls).

-
-
-
    slot_filler = RuleBasedSlotFillerPlugin(rules=rules, access=access)()
-
-
-
-
-
-
- # -
-

Create a mock workflow

-
-
-
    workflow = Workflow(preprocessors=[], postprocessors=[slot_filler])
-
-
-
-
-
-
- # -
-

… a mock Intent

-
-
-
    intent = Intent(name=intent_name, score=0.8)
-
-
-
-
-
-
- # -
-

and mock Entity-ies.

-
-
-
    body = "12th december"
-    entity_1 = BaseEntity(
-        range={"from": 0, "to": len(body)},
-        body=body,
-        dim="default",
-        type="entity_1",
-        values=[{"key": "value"}],
-        slot_names=["entity_1_slot"],
-    )
-
-    entity_2 = BaseEntity(
-        range={"from": 0, "to": len(body)},
-        body=body,
-        dim="default",
-        type="entity_2",
-        values=[{"key": "value"}],
-        slot_names=["entity_2_slot"],
-    )
-
-
-
-
-
-
- # -
-

The RuleBasedSlotFillerPlugin specifies that it expects Tuple[Intent, List[Entity]) on access(workflow).

-
-
-
    workflow.output = (intent, [entity_1, entity_2])
-    workflow.run(body)
-
-
-
-
-
-
- # -
-

workflow.output[0] is the Intent we created. -The entity_1_slot and entity_2_slot are filled.

-
-
-
    assert workflow.output[0].slots["entity_1_slot"].values == [entity_1]
-    assert workflow.output[0].slots["entity_2_slot"].values == [entity_2]
-
-
-
-
-
-
- # -
-

Let’s try filling both the slots this time with fill_multiple=True! -intent_2 supports both entity_1 and entity_2.

-
-
-
def test_slot_filling_multiple() -> None:
-
-
-
-
-
-
- # -
- -
-
-
-
-
-
-
-
-
- # -
- -
-
-
    def access(workflow: Workflow) -> Any:
-        return workflow.output
-
-    intent_name = "intent_2"
-
-
-
-
-
-
- # -
-

Setting up the slot-filler, both instantiation and plugin is created. (notice two calls).

-
-
-
    slot_filler = RuleBasedSlotFillerPlugin(
-        rules=rules, access=access, fill_multiple=True
-    )()
-
-
-
-
-
-
- # -
-

Create a mock workflow

-
-
-
    workflow = Workflow(preprocessors=[], postprocessors=[slot_filler])
-
-
-
-
-
-
- # -
-

… a mock Intent

-
-
-
    intent = Intent(name=intent_name, score=0.8)
-
-
-
-
-
-
- # -
-

and mock Entity-ies.

-
-
-
    body = "12th december"
-    entity_1 = BaseEntity(
-        range={"from": 0, "to": len(body)},
-        body=body,
-        dim="default",
-        type="entity_1",
-        values=[{"key": "value"}],
-        slot_names=["entity_1_slot"],
-    )
-
-    entity_2 = BaseEntity(
-        range={"from": 0, "to": len(body)},
-        body=body,
-        dim="default",
-        type="entity_2",
-        values=[{"key": "value"}],
-        slot_names=["entity_2_slot"],
-    )
-
-
-
-
-
-
- # -
-

The RuleBasedSlotFillerPlugin specifies that it expects Tuple[Intent, List[Entity]) on access(workflow).

-
-
-
    workflow.output = (intent, [entity_1, entity_2])
-    workflow.run(body)
-
-
-
-
-
-
- # -
-

workflow.output[0] is the Intent we created. -The entity_1_slot and entity_2_slot are filled.

-
-
-
    assert workflow.output[0].slots["entity_1_slot"].values == [entity_1]
-    assert workflow.output[0].slots["entity_2_slot"].values == [entity_2]
-
-
-
-
-
-
- # -
-

What happens when we have two entities of the same type but different value?

-
-
-
def test_slot_competition() -> None:
-
-
-
-
-
-
- # -
- -
-
-
-
-
-
-
-
-
- # -
- -
-
-
    def access(workflow: Workflow) -> Any:
-        return workflow.output
-
-    intent_name = "intent_1"
-
-
-
-
-
-
- # -
-

Setting up the slot-filler, both instantiation and plugin is created. (notice two calls).

-
-
-
    slot_filler = RuleBasedSlotFillerPlugin(rules=rules, access=access)()
-
-
-
-
-
-
- # -
-

Create a mock workflow

-
-
-
    workflow = Workflow(preprocessors=[], postprocessors=[slot_filler])
-
-
-
-
-
-
- # -
-

… a mock Intent

-
-
-
    intent = Intent(name=intent_name, score=0.8)
-
-
-
-
-
-
- # -
-

Here we have two entities which compete for the same slot but have different values.

-
-
-
    body = "12th december"
-    entity_1 = BaseEntity(
-        range={"from": 0, "to": len(body)},
-        body=body,
-        dim="default",
-        type="entity_1",
-        values=[{"key": "value_1"}],
-        slot_names=["entity_1_slot"],
-    )
-
-    entity_2 = BaseEntity(
-        range={"from": 0, "to": len(body)},
-        body=body,
-        dim="default",
-        type="entity_1",
-        values=[{"key": "value_2"}],
-        slot_names=["entity_1_slot"],
-    )
-
-
-
-
-
-
- # -
-

The RuleBasedSlotFillerPlugin specifies that it expects Tuple[Intent, List[Entity]) on access(workflow).

-
-
-
    workflow.output = (intent, [entity_1, entity_2])
-    workflow.run(body)
-
-
-
-
-
-
- # -
-

workflow.output[0] is the Intent we created. -The entity_1_slot and entity_2_slot are filled.

-
-
-
    assert "entity_1_slot" not in workflow.output[0].slots
-
-
-
-
-
-
- # -
-

This test shows that the plugin needs access function to be a PluginFn, -or else it throws a TypeError.

-
-
-
def test_incorrect_access_fn() -> None:
-
-
-
-
-
-
- # -
- -
-
-
    rules = {"basic": {"slot_name": "basic_slot", "entity_type": "basic"}}
-    access = 5
-
-    slot_filler = RuleBasedSlotFillerPlugin(rules=rules, access=access)()
-    workflow = Workflow(preprocessors=[], postprocessors=[slot_filler])
-    intent = Intent(name="intent", score=0.8)
-
-    body = "12th december"
-    entity = BaseEntity(
-        range={"from": 0, "to": len(body)},
-        body=body,
-        dim="default",
-        type="basic",
-        values=[{"key": "value"}],
-        slot_names=["basic_slot"],
-    )
-
-    workflow.output = (intent, [entity])
-
-    with pytest.raises(TypeError):
-        workflow.run("")
-
-
-
-
-
-
- # -
-

This test shows that the plugin needs an access provided or else it raises a type error.

-
-
-
def test_missing_access_fn() -> None:
-
-
-
-
-
-
- # -
- -
-
-
    slot_filler = RuleBasedSlotFillerPlugin(rules=rules)()
-    workflow = Workflow(preprocessors=[], postprocessors=[slot_filler])
-    intent = Intent(name="intent", score=0.8)
-
-    body = "12th december"
-    entity = BaseEntity(
-        range={"from": 0, "to": len(body)},
-        body=body,
-        dim="default",
-        type="basic",
-        values=[{"key": "value"}],
-        slot_names=["basic_slot"],
-    )
-
-    workflow.output = (intent, [entity])
-
-    with pytest.raises(TypeError):
-        workflow.run("")
-
-
-
-
-
-
- diff --git a/docs/tests/postprocess/text/voting/__init__.html b/docs/tests/postprocess/text/voting/__init__.html deleted file mode 100644 index 80a67825..00000000 --- a/docs/tests/postprocess/text/voting/__init__.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - __init__.py - - - -
-
-
-

__init__.py

-
-
-
-
-
- # -
- -
-
-

-
-
-
-
-
-
- diff --git a/docs/tests/postprocess/text/voting/test_intent.html b/docs/tests/postprocess/text/voting/test_intent.html deleted file mode 100644 index d572864b..00000000 --- a/docs/tests/postprocess/text/voting/test_intent.html +++ /dev/null @@ -1,291 +0,0 @@ - - - - - test_intent.py - - - -
-
-
-

test_intent.py

-
-
-
-
-
- # -
-

This is a tutorial for understanding the use of VotePlugin.

-
-
-
from typing import Any, List
-
-import pytest
-
-from dialogy import constants as const
-from dialogy.postprocess.text.voting.intent import VotePlugin
-from dialogy.types.intent import Intent
-from dialogy.workflow import Workflow
-
-
-
-
-
-
- # -
- -
-
-
def update_intent(workflow, value):
-    _, entities = workflow.output
-    workflow.output = (value, entities)
-
-
-
-
-
-
- # -
-

The code uses division. So its always good to -have a test to see if it takes care of division 0.

-
-
-
def test_voting_0_intents():
-
-
-
-
-
-
- # -
- -
-
-
    intents: List[Intent] = []
-    vote_plugin = VotePlugin(access=lambda w: (w.output[0], 0), mutate=update_intent)()
-    workflow = Workflow(preprocessors=[], postprocessors=[vote_plugin])
-    workflow.output = intents, []
-    intent, _ = workflow.run(input_="")
-    assert intent.name == const.S_INTENT_OOS
-
-
-
-
-
-
- # -
-

Testing the usual case.

-
-
-
def test_voting_n_intents():
-
-
-
-
-
-
- # -
- -
-
-
    intents = [
-        Intent(name="a", score=1),
-        Intent(name="a", score=1),
-        Intent(name="b", score=0.13),
-        Intent(name="a", score=1),
-    ]
-    vote_plugin = VotePlugin(
-        debug=True, access=lambda w: (w.output[0], len(intents)), mutate=update_intent
-    )()
-    workflow = Workflow(preprocessors=[], postprocessors=[vote_plugin])
-    workflow.output = intents, []
-    intent, _ = workflow.run(input_="")
-    assert intent.name == "a"
-
-
-
-
-
-
- # -
-

Testing the case with conflicts.

-
-
-
def test_voting_on_conflicts():
-
-
-
-
-
-
- # -
- -
-
-
    intents = [
-        Intent(name="a", score=1),
-        Intent(name="a", score=1),
-        Intent(name="b", score=1),
-        Intent(name="b", score=1),
-    ]
-    vote_plugin = VotePlugin(
-        access=lambda w: (w.output[0], len(intents)), mutate=update_intent
-    )()
-    workflow = Workflow(preprocessors=[], postprocessors=[vote_plugin])
-    workflow.output = intents, []
-    intent, _ = workflow.run(input_="")
-    assert intent.name == "_oos_"
-
-
-
-
-
-
- # -
-

Testing all weak intents.

-
-
-
def test_voting_on_weak_signals():
-
-
-
-
-
-
- # -
- -
-
-
    intents = [
-        Intent(name="a", score=0.3),
-        Intent(name="a", score=0.2),
-        Intent(name="b", score=0.1),
-        Intent(name="b", score=0.1),
-    ]
-    vote_plugin = VotePlugin(
-        access=lambda w: (w.output[0], len(intents)), mutate=update_intent
-    )()
-    workflow = Workflow(preprocessors=[], postprocessors=[vote_plugin])
-    workflow.output = intents, []
-    intent, _ = workflow.run(input_="")
-    assert intent.name == "_oos_"
-
-
-
-
-
-
- # -
- -
-
-
def test_missing_access():
-    intents = [
-        Intent(name="a", score=0.3),
-        Intent(name="a", score=0.2),
-        Intent(name="b", score=0.1),
-        Intent(name="b", score=0.1),
-    ]
-
-    vote_plugin = VotePlugin(mutate=update_intent)()
-    workflow = Workflow(preprocessors=[], postprocessors=[vote_plugin])
-    workflow.output = intents, []
-    with pytest.raises(TypeError):
-        intent, _ = workflow.run(input_="")
-
-
-
-
-
-
- # -
- -
-
-
def test_missing_mutate():
-    intents = [
-        Intent(name="a", score=0.3),
-        Intent(name="a", score=0.2),
-        Intent(name="b", score=0.1),
-        Intent(name="b", score=0.1),
-    ]
-
-    vote_plugin = VotePlugin(access=lambda w: w.output[0])()
-    workflow = Workflow(preprocessors=[], postprocessors=[vote_plugin])
-    workflow.output = intents, []
-    with pytest.raises(TypeError):
-        intent, _ = workflow.run(input_="")
-
-
-
-
-
-
- # -
- -
-
-
def test_representation_oos():
-    intents = [
-        Intent(name="a", score=0.99),
-        Intent(name="b", score=0.1),
-        Intent(name="c", score=0.31),
-        Intent(name="d", score=0.44),
-    ]
-
-    vote_plugin = VotePlugin(
-        access=lambda w: (w.output[0], len(intents)), mutate=update_intent
-    )()
-    workflow = Workflow(preprocessors=[], postprocessors=[vote_plugin])
-    workflow.output = intents, []
-    intent, _ = workflow.run(input_="")
-    assert intent.name == "_oos_"
-
-
-
-
-
-
- # -
- -
-
-
def test_representation_intent():
-    intents = [
-        Intent(name="a", score=0.99),
-        Intent(name="a", score=0.99),
-        Intent(name="a", score=0.91),
-        Intent(name="b", score=0.1),
-        Intent(name="c", score=0.31),
-        Intent(name="d", score=0.44),
-    ]
-
-    vote_plugin = VotePlugin(
-        access=lambda w: (w.output[0], len(intents)), mutate=update_intent
-    )()
-    workflow = Workflow(preprocessors=[], postprocessors=[vote_plugin])
-    workflow.output = intents, []
-    intent, _ = workflow.run(input_="")
-    assert intent.name == "a"
-
-
-
-
-
-
- diff --git a/docs/tests/postprocess/text/voting/test_intent_voting.html b/docs/tests/postprocess/text/voting/test_intent_voting.html deleted file mode 100644 index 4541c2bc..00000000 --- a/docs/tests/postprocess/text/voting/test_intent_voting.html +++ /dev/null @@ -1,291 +0,0 @@ - - - - - test_intent_voting.py - - - -
-
-
-

test_intent_voting.py

-
-
-
-
-
- # -
-

This is a tutorial for understanding the use of VotePlugin.

-
-
-
from typing import Any, List
-
-import pytest
-
-from dialogy import constants as const
-from dialogy.postprocess.text.voting.intent import VotePlugin
-from dialogy.types.intent import Intent
-from dialogy.workflow import Workflow
-
-
-
-
-
-
- # -
- -
-
-
def update_intent(workflow, value):
-    _, entities = workflow.output
-    workflow.output = (value, entities)
-
-
-
-
-
-
- # -
-

The code uses division. So its always good to -have a test to see if it takes care of division 0.

-
-
-
def test_voting_0_intents():
-
-
-
-
-
-
- # -
- -
-
-
    intents: List[Intent] = []
-    vote_plugin = VotePlugin(access=lambda w: (w.output[0], 0), mutate=update_intent)()
-    workflow = Workflow(preprocessors=[], postprocessors=[vote_plugin])
-    workflow.output = intents, []
-    intent, _ = workflow.run(input_="")
-    assert intent.name == const.S_INTENT_OOS
-
-
-
-
-
-
- # -
-

Testing the usual case.

-
-
-
def test_voting_n_intents():
-
-
-
-
-
-
- # -
- -
-
-
    intents = [
-        Intent(name="a", score=1),
-        Intent(name="a", score=1),
-        Intent(name="b", score=0.13),
-        Intent(name="a", score=1),
-    ]
-    vote_plugin = VotePlugin(
-        debug=True, access=lambda w: (w.output[0], len(intents)), mutate=update_intent
-    )()
-    workflow = Workflow(preprocessors=[], postprocessors=[vote_plugin])
-    workflow.output = intents, []
-    intent, _ = workflow.run(input_="")
-    assert intent.name == "a"
-
-
-
-
-
-
- # -
-

Testing the case with conflicts.

-
-
-
def test_voting_on_conflicts():
-
-
-
-
-
-
- # -
- -
-
-
    intents = [
-        Intent(name="a", score=1),
-        Intent(name="a", score=1),
-        Intent(name="b", score=1),
-        Intent(name="b", score=1),
-    ]
-    vote_plugin = VotePlugin(
-        access=lambda w: (w.output[0], len(intents)), mutate=update_intent
-    )()
-    workflow = Workflow(preprocessors=[], postprocessors=[vote_plugin])
-    workflow.output = intents, []
-    intent, _ = workflow.run(input_="")
-    assert intent.name == "_oos_"
-
-
-
-
-
-
- # -
-

Testing all weak intents.

-
-
-
def test_voting_on_weak_signals():
-
-
-
-
-
-
- # -
- -
-
-
    intents = [
-        Intent(name="a", score=0.3),
-        Intent(name="a", score=0.2),
-        Intent(name="b", score=0.1),
-        Intent(name="b", score=0.1),
-    ]
-    vote_plugin = VotePlugin(
-        access=lambda w: (w.output[0], len(intents)), mutate=update_intent
-    )()
-    workflow = Workflow(preprocessors=[], postprocessors=[vote_plugin])
-    workflow.output = intents, []
-    intent, _ = workflow.run(input_="")
-    assert intent.name == "_oos_"
-
-
-
-
-
-
- # -
- -
-
-
def test_missing_access():
-    intents = [
-        Intent(name="a", score=0.3),
-        Intent(name="a", score=0.2),
-        Intent(name="b", score=0.1),
-        Intent(name="b", score=0.1),
-    ]
-
-    vote_plugin = VotePlugin(mutate=update_intent)()
-    workflow = Workflow(preprocessors=[], postprocessors=[vote_plugin])
-    workflow.output = intents, []
-    with pytest.raises(TypeError):
-        intent, _ = workflow.run(input_="")
-
-
-
-
-
-
- # -
- -
-
-
def test_missing_mutate():
-    intents = [
-        Intent(name="a", score=0.3),
-        Intent(name="a", score=0.2),
-        Intent(name="b", score=0.1),
-        Intent(name="b", score=0.1),
-    ]
-
-    vote_plugin = VotePlugin(access=lambda w: w.output[0])()
-    workflow = Workflow(preprocessors=[], postprocessors=[vote_plugin])
-    workflow.output = intents, []
-    with pytest.raises(TypeError):
-        intent, _ = workflow.run(input_="")
-
-
-
-
-
-
- # -
- -
-
-
def test_representation_oos():
-    intents = [
-        Intent(name="a", score=0.99),
-        Intent(name="b", score=0.1),
-        Intent(name="c", score=0.31),
-        Intent(name="d", score=0.44),
-    ]
-
-    vote_plugin = VotePlugin(
-        access=lambda w: (w.output[0], len(intents)), mutate=update_intent
-    )()
-    workflow = Workflow(preprocessors=[], postprocessors=[vote_plugin])
-    workflow.output = intents, []
-    intent, _ = workflow.run(input_="")
-    assert intent.name == "_oos_"
-
-
-
-
-
-
- # -
- -
-
-
def test_representation_intent():
-    intents = [
-        Intent(name="a", score=0.99),
-        Intent(name="a", score=0.99),
-        Intent(name="a", score=0.91),
-        Intent(name="b", score=0.1),
-        Intent(name="c", score=0.31),
-        Intent(name="d", score=0.44),
-    ]
-
-    vote_plugin = VotePlugin(
-        access=lambda w: (w.output[0], len(intents)), mutate=update_intent
-    )()
-    workflow = Workflow(preprocessors=[], postprocessors=[vote_plugin])
-    workflow.output = intents, []
-    intent, _ = workflow.run(input_="")
-    assert intent.name == "a"
-
-
-
-
-
-
- diff --git a/docs/tests/postprocessors/__init__.html b/docs/tests/postprocessors/__init__.html deleted file mode 100644 index 282d6589..00000000 --- a/docs/tests/postprocessors/__init__.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - __init__.py - - - -
-
-
-

__init__.py

-
-
-
-
-
- # -
- -
-
-

-
-
-
-
-
-
- diff --git a/docs/tests/postprocessors/text/__init__.html b/docs/tests/postprocessors/text/__init__.html deleted file mode 100644 index 2f36ff57..00000000 --- a/docs/tests/postprocessors/text/__init__.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - __init__.py - - - -
-
-
-

__init__.py

-
-
-
-
-
- # -
- -
-
-

-
-
-
-
-
-
- diff --git a/docs/tests/postprocessors/text/slot_filler/__init__.html b/docs/tests/postprocessors/text/slot_filler/__init__.html deleted file mode 100644 index 80a67825..00000000 --- a/docs/tests/postprocessors/text/slot_filler/__init__.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - __init__.py - - - -
-
-
-

__init__.py

-
-
-
-
-
- # -
- -
-
-

-
-
-
-
-
-
- diff --git a/docs/tests/postprocessors/text/slot_filler/test_rule_slot_filler.html b/docs/tests/postprocessors/text/slot_filler/test_rule_slot_filler.html deleted file mode 100644 index 66f1b46d..00000000 --- a/docs/tests/postprocessors/text/slot_filler/test_rule_slot_filler.html +++ /dev/null @@ -1,149 +0,0 @@ - - - - - test_rule_slot_filler.py - - - -
-
-
-

test_rule_slot_filler.py

-
-
-
-
-
- # -
-

[summary]

-

Returns: - [type]: [description]

-
-
-
from typing import Any
-import pytest
-
-from dialogy.postprocess.text.slot_filler.rule_slot_filler import (
-    RuleBasedSlotFillerPlugin,
-)
-from dialogy.workflow import Workflow
-from dialogy.types.entity import BaseEntity
-from dialogy.types.intent import Intent
-
-
-
-
-
-
- # -
- -
-
-
def test_rule_slot_filler() -> None:
-    rules = {"basic": {"slot_name": "basic_slot", "entity_type": "basic"}}
-
-
-
-
-
-
- # -
- -
-
-
    def access(workflow: Workflow) -> Any:
-        return workflow.output
-
-    slot_filler = RuleBasedSlotFillerPlugin(rules=rules)(access=access)
-    workflow = Workflow(preprocessors=[], postprocessors=[slot_filler])
-    intent = Intent(name="intent", score=0.8)
-
-    body = "12th december"
-    entity = BaseEntity(
-        range={"from": 0, "to": len(body)},
-        body=body,
-        dim="default",
-        type="basic",
-        values=[{"key": "value"}],
-        slot_name="basic_slot",
-    )
-
-    workflow.output = (intent, [entity])
-    workflow.run("")
-    assert workflow.output[0].slots["basic_slot"].values[0] == entity
-
-
-
-
-
-
- # -
- -
-
-
def test_missing_access_fn():
-    rules = {"basic": {"slot_name": "basic_slot", "entity_type": "basic"}}
-
-    slot_filler = RuleBasedSlotFillerPlugin(rules=rules)()
-    workflow = Workflow(preprocessors=[], postprocessors=[slot_filler])
-    intent = Intent(name="intent", score=0.8)
-
-    body = "12th december"
-    entity = BaseEntity(
-        range={"from": 0, "to": len(body)},
-        body=body,
-        dim="default",
-        type="basic",
-        values=[{"key": "value"}],
-        slot_name="basic_slot",
-    )
-
-    workflow.output = (intent, [entity])
-
-    with pytest.raises(TypeError):
-        workflow.run("")
-
-
-
-
-
-
- # -
- -
-
-
def test_incorrect_access_fn():
-    rules = {"basic": {"slot_name": "basic_slot", "entity_type": "basic"}}
-    access = 5
-
-    slot_filler = RuleBasedSlotFillerPlugin(rules=rules)(access=access)
-    workflow = Workflow(preprocessors=[], postprocessors=[slot_filler])
-    intent = Intent(name="intent", score=0.8)
-
-    body = "12th december"
-    entity = BaseEntity(
-        range={"from": 0, "to": len(body)},
-        body=body,
-        dim="default",
-        type="basic",
-        values=[{"key": "value"}],
-        slot_name="basic_slot",
-    )
-
-    workflow.output = (intent, [entity])
-
-    with pytest.raises(TypeError):
-        workflow.run("")
-
-
-
-
-
-
- diff --git a/docs/tests/preprocess/__init__.html b/docs/tests/preprocess/__init__.html deleted file mode 100644 index 282d6589..00000000 --- a/docs/tests/preprocess/__init__.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - __init__.py - - - -
-
-
-

__init__.py

-
-
-
-
-
- # -
- -
-
-

-
-
-
-
-
-
- diff --git a/docs/tests/preprocess/test_merge_asr_output.html b/docs/tests/preprocess/test_merge_asr_output.html deleted file mode 100644 index 4149a271..00000000 --- a/docs/tests/preprocess/test_merge_asr_output.html +++ /dev/null @@ -1,122 +0,0 @@ - - - - - test_merge_asr_output.py - - - -
-
-
-

test_merge_asr_output.py

-
-
-
-
-
- # -
- -
-
-
import pytest
-from dialogy.workflow import Workflow
-from dialogy.preprocess.text.merge_asr_output import merge_asr_output
-
-
-
-
-
-
- # -
- -
-
-
def test_merge_as_output():
-
-
-
-
-
-
- # -
- -
-
-
    def access(workflow):
-        return workflow.input
-
-
-
-
-
-
- # -
- -
-
-
    def mutate(workflow, value):
-        workflow.input = value
-
-    workflow = Workflow(
-        preprocessors=[merge_asr_output(access, mutate)], postprocessors=[]
-    )
-
-    workflow.run([[{"transcript": "hello world", "confidence": None}]])
-    assert workflow.input == "<s> hello world </s>"
-
-
-
-
-
-
- # -
- -
-
-
def test_merge_keyerror_on_missing_transcript():
-
-
-
-
-
-
- # -
- -
-
-
    def access(workflow):
-        return workflow.input
-
-
-
-
-
-
- # -
- -
-
-
    def mutate(workflow, value):
-        workflow.input = value
-
-    workflow = Workflow(
-        preprocessors=[merge_asr_output(access, mutate)], postprocessors=[]
-    )
-
-    with pytest.raises(KeyError):
-        workflow.run([[{"not_transcript": "hello world", "confidence": None}]])
-
-
-
-
-
-
- diff --git a/docs/tests/preprocess/text/__init__.html b/docs/tests/preprocess/text/__init__.html deleted file mode 100644 index 2f36ff57..00000000 --- a/docs/tests/preprocess/text/__init__.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - __init__.py - - - -
-
-
-

__init__.py

-
-
-
-
-
- # -
- -
-
-

-
-
-
-
-
-
- diff --git a/docs/tests/preprocess/text/test_merge_asr_output.html b/docs/tests/preprocess/text/test_merge_asr_output.html deleted file mode 100644 index d9667601..00000000 --- a/docs/tests/preprocess/text/test_merge_asr_output.html +++ /dev/null @@ -1,158 +0,0 @@ - - - - - test_merge_asr_output.py - - - -
-
-
-

test_merge_asr_output.py

-
-
-
-
-
- # -
- -
-
-
import pytest
-
-from dialogy.preprocess.text.merge_asr_output import merge_asr_output_plugin
-from dialogy.workflow import Workflow
-
-
-
-
-
-
- # -
- -
-
-
def access(workflow):
-    return workflow.input
-
-
-
-
-
-
- # -
- -
-
-
def mutate(workflow, value):
-    workflow.input = value
-
-
-
-
-
-
- # -
-

This case shows the merge in case there is only one option.

-
-
-
def test_merge_asr_output() -> None:
-
-
-
-
-
-
- # -
- -
-
-
    workflow = Workflow(
-        preprocessors=[merge_asr_output_plugin(access, mutate)], postprocessors=[]
-    )
-
-    workflow.run([[{"transcript": "hello world", "confidence": None}]])
-    assert workflow.input == "<s> hello world </s>"
-
-
-
-
-
-
- # -
-

This case shows the merge in case there are multiple options.

-
-
-
def test_merge_longer_asr_output() -> None:
-
-
-
-
-
-
- # -
- -
-
-
    workflow = Workflow(
-        preprocessors=[merge_asr_output_plugin(access, mutate)], postprocessors=[]
-    )
-
-    workflow.run(
-        [
-            [
-                {"transcript": "hello world", "confidence": None},
-                {"transcript": "hello word", "confidence": None},
-                {"transcript": "jello world", "confidence": None},
-            ]
-        ]
-    )
-    assert (
-        workflow.input
-        == "<s> hello world </s> <s> hello word </s> <s> jello world </s>"
-    )
-
-
-
-
-
-
- # -
-

This test, shows that transcript is an important key. If the asr has a different key, than transcript -then this plugin would not work for you.

-
-
-
def test_merge_keyerror_on_missing_transcript() -> None:
-
-
-
-
-
-
- # -
- -
-
-
    workflow = Workflow(
-        preprocessors=[merge_asr_output_plugin(access, mutate)], postprocessors=[]
-    )
-
-    with pytest.raises(TypeError):
-        workflow.run([[{"not_transcript": "hello world", "confidence": None}]])
-
-
-
-
-
-
- diff --git a/docs/tests/preprocess/text/test_normalize_utterance.html b/docs/tests/preprocess/text/test_normalize_utterance.html deleted file mode 100644 index ef6324db..00000000 --- a/docs/tests/preprocess/text/test_normalize_utterance.html +++ /dev/null @@ -1,92 +0,0 @@ - - - - - test_normalize_utterance.py - - - -
-
-
-

test_normalize_utterance.py

-
-
-
-
-
- # -
-

This module was created in response to: https://github.com/Vernacular-ai/dialogy/issues/9 -we will ship functions to assist normalization of ASR output, we will refer to these as Utterances.

-
-
-
from typing import Any, List
-
-import pytest
-
-from dialogy import constants as const
-from dialogy.preprocess.text.normalize_utterance import is_list_of_string, normalize
-
-TEST_STRING = "hello world"
-EXPECTED_OUTPUT = [TEST_STRING]
-
-
-
-
-
-
- # -
- -
-
-
@pytest.mark.parametrize(
-    "utterance,expected",
-    [
-        ([[{"transcript": TEST_STRING}]], EXPECTED_OUTPUT),
-        ([{"transcript": TEST_STRING}], EXPECTED_OUTPUT),
-        ([TEST_STRING], EXPECTED_OUTPUT),
-        (TEST_STRING, EXPECTED_OUTPUT),
-    ],
-)
-def test_normalize_utterance(utterance: Any, expected: List[str]) -> None:
-    output = normalize(utterance)
-    assert output == expected
-
-
-@pytest.mark.parametrize(
-    "utterance",
-    [
-        1,
-        [[{"teapot": TEST_STRING}]],
-        [{"teapot": TEST_STRING}],
-        [1, 2],
-        None,
-    ],
-)
-def test_cant_normalize_utterance(utterance: Any) -> None:
-    with pytest.raises(TypeError):
-        _ = normalize(utterance)
-
-
-@pytest.mark.parametrize(
-    "utterance,expected",
-    [
-        ([[{"teapot": TEST_STRING}]], False),
-        ([{"teapot": TEST_STRING}], False),
-        ([1, 2], False),
-        (1, False),
-        (None, False),
-    ],
-)
-def test_is_list_of_string(utterance: Any, expected: bool) -> None:
-    output = is_list_of_string(utterance)
-    assert output == expected
-
-
-
-
-
-
- diff --git a/docs/tests/preprocessors/__init__.html b/docs/tests/preprocessors/__init__.html deleted file mode 100644 index 282d6589..00000000 --- a/docs/tests/preprocessors/__init__.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - __init__.py - - - -
-
-
-

__init__.py

-
-
-
-
-
- # -
- -
-
-

-
-
-
-
-
-
- diff --git a/docs/tests/preprocessors/test_merge_asr_output.html b/docs/tests/preprocessors/test_merge_asr_output.html deleted file mode 100644 index 4149a271..00000000 --- a/docs/tests/preprocessors/test_merge_asr_output.html +++ /dev/null @@ -1,122 +0,0 @@ - - - - - test_merge_asr_output.py - - - -
-
-
-

test_merge_asr_output.py

-
-
-
-
-
- # -
- -
-
-
import pytest
-from dialogy.workflow import Workflow
-from dialogy.preprocess.text.merge_asr_output import merge_asr_output
-
-
-
-
-
-
- # -
- -
-
-
def test_merge_as_output():
-
-
-
-
-
-
- # -
- -
-
-
    def access(workflow):
-        return workflow.input
-
-
-
-
-
-
- # -
- -
-
-
    def mutate(workflow, value):
-        workflow.input = value
-
-    workflow = Workflow(
-        preprocessors=[merge_asr_output(access, mutate)], postprocessors=[]
-    )
-
-    workflow.run([[{"transcript": "hello world", "confidence": None}]])
-    assert workflow.input == "<s> hello world </s>"
-
-
-
-
-
-
- # -
- -
-
-
def test_merge_keyerror_on_missing_transcript():
-
-
-
-
-
-
- # -
- -
-
-
    def access(workflow):
-        return workflow.input
-
-
-
-
-
-
- # -
- -
-
-
    def mutate(workflow, value):
-        workflow.input = value
-
-    workflow = Workflow(
-        preprocessors=[merge_asr_output(access, mutate)], postprocessors=[]
-    )
-
-    with pytest.raises(KeyError):
-        workflow.run([[{"not_transcript": "hello world", "confidence": None}]])
-
-
-
-
-
-
- diff --git a/docs/tests/types/__init__.html b/docs/tests/types/__init__.html deleted file mode 100644 index 282d6589..00000000 --- a/docs/tests/types/__init__.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - __init__.py - - - -
-
-
-

__init__.py

-
-
-
-
-
- # -
- -
-
-

-
-
-
-
-
-
- diff --git a/docs/tests/types/entities/__init__.html b/docs/tests/types/entities/__init__.html deleted file mode 100644 index 2f36ff57..00000000 --- a/docs/tests/types/entities/__init__.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - __init__.py - - - -
-
-
-

__init__.py

-
-
-
-
-
- # -
- -
-
-

-
-
-
-
-
-
- diff --git a/docs/tests/types/entities/test_entities.html b/docs/tests/types/entities/test_entities.html deleted file mode 100644 index d8de910d..00000000 --- a/docs/tests/types/entities/test_entities.html +++ /dev/null @@ -1,344 +0,0 @@ - - - - - test_entities.py - - - -
-
-
-

test_entities.py

-
-
-
-
-
- # -
-

Tests for entities

-
-
-
import pytest
-
-from dialogy.types.entity import (
-    BaseEntity,
-    NumericalEntity,
-    PeopleEntity,
-    TimeEntity,
-    TimeIntervalEntity,
-    LocationEntity,
-    entity_synthesis,
-)
-from dialogy.workflow import Workflow
-
-
-
-
-
-
- # -
- -
-
-
def mock_plugin(_: Workflow) -> None:
-    pass
-
-
-
-
-
-
- # -
- -
-
-
def make_mock_entity():
-    return {
-        "body": "6pm",
-        "start": 0,
-        "value": {
-            "values": [
-                {
-                    "value": "2021-01-15T18:00:00.000-08:00",
-                    "grain": "hour",
-                    "type": "value",
-                },
-                {
-                    "value": "2021-01-16T18:00:00.000-08:00",
-                    "grain": "hour",
-                    "type": "value",
-                },
-                {
-                    "value": "2021-01-17T18:00:00.000-08:00",
-                    "grain": "hour",
-                    "type": "value",
-                },
-            ],
-            "value": "2021-01-15T18:00:00.000-08:00",
-            "grain": "hour",
-            "type": "value",
-        },
-        "end": 3,
-        "dim": "time",
-        "latent": False,
-    }
-
-
-
-
-
-
- # -
- -
-
-
def test_entity_parser():
-    body = "12th december"
-    entity = BaseEntity(
-        range={"from": 0, "to": len(body)},
-        body=body,
-        dim="default",
-        type="basic",
-        values=[{"value": 0}],
-    )
-    entity.add_parser(mock_plugin)
-
-    assert entity.parsers == ["mock_plugin"], "parser was not added"
-    assert entity.get_value() == 0, "value incorrect"
-
-
-
-
-
-
- # -
- -
-
-
def test_entity_values_index_error():
-    body = "12th december"
-    entity = BaseEntity(
-        range={"from": 0, "to": len(body)},
-        body=body,
-        dim="default",
-        type="basic",
-        values=[],
-    )
-    with pytest.raises(IndexError):
-        entity.get_value()
-
-
-
-
-
-
- # -
- -
-
-
def test_entity_deep_copy():
-    body = "12th december"
-    entity = BaseEntity(
-        range={"from": 0, "to": len(body)},
-        body=body,
-        type="basic",
-        dim="default",
-        values=[],
-    )
-
-    entity_copy = entity.copy()
-    entity_copy.body = "12th november"
-
-
-
-
-
-
- # -
-

Had this not been a deep copy, it would have matched.

-
-
-
    assert entity_copy.body != entity.body, "Shouldn't be same"
-
-
-
-
-
-
- # -
- -
-
-
def test_entity_synthesis():
-    body = "12th december"
-    entity = BaseEntity(
-        range={"from": 0, "to": len(body)},
-        body=body,
-        dim="default",
-        type="basic",
-        values=[],
-    )
-    synthetic_entity = entity_synthesis(entity, "body", "12th november")
-    assert synthetic_entity.body != entity.body, "Shouldn't be same"
-
-
-
-
-
-
- # -
- -
-
-
def test_entity_synthesis_exception():
-    body = "12th december"
-    entity = {}
-    with pytest.raises(TypeError):
-        entity_synthesis(entity, "body", "12th november")
-
-
-
-
-
-
- # -
- -
-
-
def test_entity_values_key_error():
-    body = "12th december"
-    entity = BaseEntity(
-        range={"from": 0, "to": len(body)},
-        body=body,
-        dim="default",
-        type="basic",
-        values=[{"key": "value"}],
-    )
-    with pytest.raises(KeyError):
-        entity.get_value()
-
-
-
-
-
-
- # -
- -
-
-
def test_entity_parser_from_dict():
-    mock_entity = make_mock_entity()
-    mock_entity["range"] = {"start": mock_entity["start"], "end": mock_entity["end"]}
-    mock_entity["type"] = "basic"
-    del mock_entity["start"]
-    del mock_entity["end"]
-    mock_entity["values"] = mock_entity["value"]["values"]
-    del mock_entity["value"]
-    BaseEntity.from_dict(mock_entity)
-
-
-
-
-
-
- # -
- -
-
-
def test_numerical_type_not_str_error():
-    body = "12 december"
-    with pytest.raises(TypeError):
-        _ = NumericalEntity(
-            range={"from": 0, "to": len(body)},
-            body=body,
-            origin="pattern",
-            type="numeric",
-        )
-
-
-
-
-
-
- # -
- -
-
-
def test_people_entity_unit_not_str_error():
-    body = "12 people"
-    with pytest.raises(TypeError):
-        _ = PeopleEntity(
-            range={"from": 0, "to": len(body)}, body=body, type="people", unit=0
-        )
-
-
-
-
-
-
- # -
- -
-
-
def test_time_entity_grain_not_str_error():
-    body = "12 pm"
-    with pytest.raises(TypeError):
-        _ = TimeEntity(
-            range={"from": 0, "to": len(body)}, body=body, type="time", grain=0
-        )
-
-
-
-
-
-
- # -
- -
-
-
def test_time_interval_entity_value_not_dict_error():
-    body = "from 4 pm to 12 am"
-    with pytest.raises(TypeError):
-        _ = TimeIntervalEntity(
-            range={"from": 0, "to": len(body)}, body=body, type="time", grain=0
-        )
-
-
-
-
-
-
- # -
- -
-
-
def test_location_entity_value_not_int_error():
-    body = "bangalore"
-    with pytest.raises(TypeError):
-        _ = LocationEntity(
-            range={"from": 0, "to": len(body)}, body=body, type="location"
-        )
-
-
-
-
-
-
- diff --git a/docs/tests/types/entities/test_utils.html b/docs/tests/types/entities/test_utils.html deleted file mode 100644 index e2f85114..00000000 --- a/docs/tests/types/entities/test_utils.html +++ /dev/null @@ -1,105 +0,0 @@ - - - - - test_utils.py - - - -
-
-
-

test_utils.py

-
-
-
-
-
- # -
- -
-
-
import pytest
-from dialogy.types.entity.utils import traverse_dict, validate_type
-
-
-
-
-
-
- # -
- -
-
-
def test_traverse_dict() -> None:
-    obj = {"a": {"b": {"c": 10}, "1": {"d": 11}}}
-    assert traverse_dict(obj, ["a", "b", "c"]) == 10, "Traversal failed."
-
-
-
-
-
-
- # -
- -
-
-
def test_traverse_dict_raises_type_error() -> None:
-    obj = {"a": {"b": {"c": 10}, "1": {"d": 11}}}
-    with pytest.raises(TypeError):
-        traverse_dict(obj, ["a", "b", "c", 1])
-
-
-
-
-
-
- # -
- -
-
-
def test_traverse_dict_raises_key_error():
-    obj = {"a": {"b": {"c": 10}, "1": {"d": 11}}}
-    with pytest.raises(KeyError):
-        traverse_dict(obj, ["a", "k"])
-
-
-
-
-
-
- # -
- -
-
-
def test_validate_type_raises_error() -> None:
-    test_input = "string"
-    with pytest.raises(TypeError):
-        validate_type(test_input, int)
-
-
-
-
-
-
- # -
- -
-
-
def test_validate_type_happy_case() -> None:
-    test_input = "string"
-    result = validate_type(test_input, str)
-    assert result is None, "False positives from validate_type"
-
-
-
-
-
-
- diff --git a/docs/tests/types/entity/__init__.html b/docs/tests/types/entity/__init__.html deleted file mode 100644 index 2f36ff57..00000000 --- a/docs/tests/types/entity/__init__.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - __init__.py - - - -
-
-
-

__init__.py

-
-
-
-
-
- # -
- -
-
-

-
-
-
-
-
-
- diff --git a/docs/tests/types/entity/test_entities.html b/docs/tests/types/entity/test_entities.html deleted file mode 100644 index 1ab53b37..00000000 --- a/docs/tests/types/entity/test_entities.html +++ /dev/null @@ -1,539 +0,0 @@ - - - - - test_entities.py - - - -
-
-
-

test_entities.py

-
-
-
-
-
- # -
-

Tests for entities

-
-
-
import pytest
-
-from dialogy.types.entity import (
-    BaseEntity,
-    LocationEntity,
-    NumericalEntity,
-    PeopleEntity,
-    TimeEntity,
-    TimeIntervalEntity,
-    entity_synthesis,
-)
-from dialogy.workflow import Workflow
-
-
-
-
-
-
- # -
- -
-
-
def mock_plugin(_: Workflow) -> None:
-    pass
-
-
-
-
-
-
- # -
- -
-
-
def make_mock_entity():
-    return {
-        "body": "6pm",
-        "start": 0,
-        "value": {
-            "values": [
-                {
-                    "value": "2021-01-15T18:00:00.000-08:00",
-                    "grain": "hour",
-                    "type": "value",
-                },
-                {
-                    "value": "2021-01-16T18:00:00.000-08:00",
-                    "grain": "hour",
-                    "type": "value",
-                },
-                {
-                    "value": "2021-01-17T18:00:00.000-08:00",
-                    "grain": "hour",
-                    "type": "value",
-                },
-            ],
-            "value": "2021-01-15T18:00:00.000-08:00",
-            "grain": "hour",
-            "type": "value",
-        },
-        "end": 3,
-        "dim": "time",
-        "latent": False,
-    }
-
-
-
-
-
-
- # -
- -
-
-
def test_entity_parser():
-    body = "12th december"
-    entity = BaseEntity(
-        range={"from": 0, "to": len(body)},
-        body=body,
-        dim="default",
-        type="basic",
-        values=[{"value": 0}],
-    )
-    entity.add_parser(mock_plugin)
-
-    assert entity.parsers == ["mock_plugin"], "parser was not added"
-    assert entity.get_value() == 0, "value incorrect"
-
-
-
-
-
-
- # -
- -
-
-
def test_entity_values_index_error():
-    body = "12th december"
-    entity = BaseEntity(
-        range={"from": 0, "to": len(body)},
-        body=body,
-        dim="default",
-        type="basic",
-        values=[],
-    )
-    with pytest.raises(IndexError):
-        entity.get_value()
-
-
-
-
-
-
- # -
- -
-
-
def test_entity_deep_copy():
-    body = "12th december"
-    entity = BaseEntity(
-        range={"from": 0, "to": len(body)},
-        body=body,
-        type="basic",
-        dim="default",
-        values=[],
-    )
-
-    entity_copy = entity.copy()
-    entity_copy.body = "12th november"
-
-
-
-
-
-
- # -
-

Had this not been a deep copy, it would have matched.

-
-
-
    assert entity_copy.body != entity.body, "Shouldn't be same"
-
-
-
-
-
-
- # -
- -
-
-
def test_entity_synthesis():
-    body = "12th december"
-    entity = BaseEntity(
-        range={"from": 0, "to": len(body)},
-        body=body,
-        dim="default",
-        type="basic",
-        values=[],
-    )
-    synthetic_entity = entity_synthesis(entity, "body", "12th november")
-    assert synthetic_entity.body != entity.body, "Shouldn't be same"
-
-
-
-
-
-
- # -
- -
-
-
def test_entity_synthesis_exception():
-    body = "12th december"
-    entity = {}
-    with pytest.raises(TypeError):
-        entity_synthesis(entity, "body", body)
-
-
-
-
-
-
- # -
- -
-
-
def test_entity_values_key_error():
-    body = "12th december"
-    entity = BaseEntity(
-        range={"from": 0, "to": len(body)},
-        body=body,
-        dim="default",
-        type="basic",
-        values=[{"key": "value"}],
-    )
-    with pytest.raises(KeyError):
-        entity.get_value()
-
-
-
-
-
-
- # -
- -
-
-
def test_entity_parser_from_dict():
-    mock_entity = make_mock_entity()
-    mock_entity["range"] = {"start": mock_entity["start"], "end": mock_entity["end"]}
-    mock_entity["type"] = "basic"
-    del mock_entity["start"]
-    del mock_entity["end"]
-    mock_entity["values"] = mock_entity["value"]["values"]
-    del mock_entity["value"]
-    BaseEntity.from_dict(mock_entity)
-
-
-
-
-
-
- # -
- -
-
-
def test_people_entity_unit_not_str_error():
-    body = "12 people"
-    with pytest.raises(TypeError):
-        _ = PeopleEntity(
-            range={"from": 0, "to": len(body)}, body=body, type="people", unit=0
-        )
-
-
-
-
-
-
- # -
- -
-
-
def test_time_entity_grain_not_str_error():
-    body = "12 pm"
-    with pytest.raises(TypeError):
-        _ = TimeEntity(
-            range={"from": 0, "to": len(body)}, body=body, type="time", grain=0
-        )
-
-
-
-
-
-
- # -
- -
-
-
def test_time_interval_entity_value_not_dict_error():
-    body = "from 4 pm to 12 am"
-    with pytest.raises(TypeError):
-        _ = TimeIntervalEntity(
-            range={"from": 0, "to": len(body)}, body=body, type="time", grain=0
-        )
-
-
-
-
-
-
- # -
- -
-
-
def test_location_entity_value_not_int_error():
-    body = "bangalore"
-    with pytest.raises(TypeError):
-        _ = LocationEntity(
-            range={"from": 0, "to": len(body)}, body=body, type="location"
-        )
-
-
-
-
-
-
- # -
- -
-
-
def test_entity_set_value_values_present():
-    body = "four"
-    entity = NumericalEntity(
-        range={"from": 0, "to": len(body)},
-        body=body,
-        dim="default",
-        type="basic",
-        values=[{"value": 4}],
-    )
-    entity.set_value()
-    assert entity.value == 4
-
-
-
-
-
-
- # -
- -
-
-
def test_entity_set_value_values_missing():
-    body = "four"
-    entity = BaseEntity(
-        range={"from": 0, "to": len(body)},
-        body=body,
-        dim="default",
-        type="basic",
-    )
-    entity.set_value(value=4)
-    assert entity.value == 4
-
-
-
-
-
-
- # -
- -
-
-
def test_interval_entity_set_value_values_missing() -> None:
-    body = "between 2 to 4 am"
-    value = {
-        "to": {"value": "2021-01-22T05:00:00.000+05:30", "grain": "hour"},
-        "from": {"value": "2021-01-22T02:00:00.000+05:30", "grain": "hour"},
-    }
-    entity = TimeIntervalEntity(
-        range={"from": 0, "to": len(body)},
-        body=body,
-        type="time",
-        grain="hour",
-        values=[value],
-    )
-    entity.set_value()
-    assert entity.value == value
-
-
-
-
-
-
- # -
- -
-
-
def test_interval_entity_set_value_values_present() -> None:
-    body = "between 2 to 4 am"
-    value = {
-        "to": {"value": "2021-01-22T05:00:00.000+05:30", "grain": "hour"},
-        "from": {"value": "2021-01-22T02:00:00.000+05:30", "grain": "hour"},
-    }
-    entity = TimeIntervalEntity(
-        range={"from": 0, "to": len(body)},
-        body=body,
-        type="time",
-        grain="hour",
-    )
-    entity.set_value(value)
-    assert entity.value == value
-
-
-
-
-
-
- # -
- -
-
-
def test_interval_entity_value_not_dict() -> None:
-    body = "between 2 to 4 am"
-    entity = TimeIntervalEntity(
-        range={"from": 0, "to": len(body)},
-        body=body,
-        type="time",
-        grain="hour",
-    )
-    with pytest.raises(TypeError):
-        entity.set_value(4)
-
-
-
-
-
-
- # -
- -
-
-
def test_interval_entity_value_none() -> None:
-    body = "between 2 to 4 am"
-    entity = TimeIntervalEntity(
-        range={"from": 0, "to": len(body)},
-        body=body,
-        type="time",
-        grain="hour",
-    )
-    with pytest.raises(TypeError):
-        entity.set_value()
-
-
-
-
-
-
- # -
- -
-
-
def test_entity_jsonify() -> None:
-    body = "12th december"
-    value = "value"
-    values = [{"key": value}]
-    entity = BaseEntity(
-        range={"from": 0, "to": len(body)},
-        body=body,
-        dim="default",
-        type="basic",
-        values=values,
-    )
-    entity.set_value(value)
-    entity_json = entity.json()
-    print(entity_json)
-    assert "dim" not in entity_json
-    assert entity_json.get("value") == value
-
-
-
-
-
-
- # -
- -
-
-
def test_entity_jsonify_unrestricted() -> None:
-    body = "12th december"
-    value = "value"
-    values = [{"key": value}]
-    entity = BaseEntity(
-        range={"from": 0, "to": len(body)},
-        body=body,
-        dim="default",
-        type="basic",
-        values=values,
-    )
-    entity_json = entity.json(add=["dim", "values"])
-    print(entity_json)
-    assert entity_json.get("dim") == "default"
-    assert entity_json.get("body") == body
-    assert entity_json.get("values") == values
-
-
-
-
-
-
- # -
- -
-
-
def test_entity_grain_to_type() -> None:
-    body = "between 2 to 4 am"
-    value = {
-        "to": {"value": "2021-01-22T05:00:00.000+05:30", "grain": "hour"},
-        "from": {"value": "2021-01-22T02:00:00.000+05:30", "grain": "hour"},
-    }
-    entity = TimeIntervalEntity(
-        range={"from": 0, "to": len(body)},
-        body=body,
-        type="time",
-        grain="hour",
-        values=[value],
-    )
-    assert entity.entity_type == "hour"
-
-
-
-
-
-
- diff --git a/docs/tests/types/entity/test_utils.html b/docs/tests/types/entity/test_utils.html deleted file mode 100644 index feac8c02..00000000 --- a/docs/tests/types/entity/test_utils.html +++ /dev/null @@ -1,106 +0,0 @@ - - - - - test_utils.py - - - -
-
-
-

test_utils.py

-
-
-
-
-
- # -
- -
-
-
import pytest
-
-from dialogy.types.entity.utils import traverse_dict, validate_type
-
-
-
-
-
-
- # -
- -
-
-
def test_traverse_dict() -> None:
-    obj = {"a": {"b": {"c": 10}, "1": {"d": 11}}}
-    assert traverse_dict(obj, ["a", "b", "c"]) == 10, "Traversal failed."
-
-
-
-
-
-
- # -
- -
-
-
def test_traverse_dict_raises_type_error() -> None:
-    obj = {"a": {"b": {"c": 10}, "1": {"d": 11}}}
-    with pytest.raises(TypeError):
-        traverse_dict(obj, ["a", "b", "c", 1])
-
-
-
-
-
-
- # -
- -
-
-
def test_traverse_dict_raises_key_error():
-    obj = {"a": {"b": {"c": 10}, "1": {"d": 11}}}
-    with pytest.raises(KeyError):
-        traverse_dict(obj, ["a", "k"])
-
-
-
-
-
-
- # -
- -
-
-
def test_validate_type_raises_error() -> None:
-    test_input = "string"
-    with pytest.raises(TypeError):
-        validate_type(test_input, int)
-
-
-
-
-
-
- # -
- -
-
-
def test_validate_type_happy_case() -> None:
-    test_input = "string"
-    result = validate_type(test_input, str)
-    assert result is None, "False positives from validate_type"
-
-
-
-
-
-
- diff --git a/docs/tests/types/intents/__init__.html b/docs/tests/types/intents/__init__.html deleted file mode 100644 index 2f36ff57..00000000 --- a/docs/tests/types/intents/__init__.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - __init__.py - - - -
-
-
-

__init__.py

-
-
-
-
-
- # -
- -
-
-

-
-
-
-
-
-
- diff --git a/docs/tests/types/intents/test_intents.html b/docs/tests/types/intents/test_intents.html deleted file mode 100644 index 31c3087a..00000000 --- a/docs/tests/types/intents/test_intents.html +++ /dev/null @@ -1,203 +0,0 @@ - - - - - test_intents.py - - - -
-
-
-

test_intents.py

-
-
-
-
-
- # -
-

Tests for intents

-
-
-
from dialogy.types.entity import BaseEntity
-from dialogy.types.intent import Intent
-from dialogy.workflow import Workflow
-
-
-
-
-
-
- # -
- -
-
-
def mock_plugin(_: Workflow) -> None:
-    pass
-
-
-
-
-
-
- # -
-

Creating an instance.

-
-
-
def test_intent_parser() -> None:
-
-
-
-
-
-
- # -
- -
-
-
    intent = Intent(name="intent_name", score=0.5)
-    intent.add_parser(mock_plugin)
-
-    assert intent.parsers == ["mock_plugin"]
-
-
-
-
-
-
- # -
-

A rule application case.

-

This is helpful if you wish to understand how slots are filled within an intent. -An initial setup is rule application, once that’s done, you can expect -the slots to be ready for containing entities.

-
-
-
def test_rule_application() -> None:
-
-
-
-
-
-
- # -
- -
-
-
    rules = {
-        "intent": {
-            "date_slot": "date",
-            "number_slot": "number",
-        }
-    }
-
-    intent = Intent(name="intent", score=0.8)
-    intent.apply(rules)
-
-    assert "date_slot" in intent.slots, "date_slot should be present."
-    assert "number_slot" in intent.slots, "number_slot should be present."
-
-    assert intent.slots["date_slot"].type == ["date"]
-    assert intent.slots["number_slot"].type == ["number"]
-
-
-
-
-
-
- # -
-

In case there is no rule for an intent?

-
-
-
def test_missing_rule() -> None:
-
-
-
-
-
-
- # -
- -
-
-
    rules = {
-        "intent": {
-            "date_slot": "date",
-            "number_slot": "number",
-        }
-    }
-
-    intent = Intent(name="some-other-intent", score=0.8)
-    intent.apply(rules)
-
-    assert "date_slot" not in intent.slots, "date_slot should be present."
-    assert "number_slot" not in intent.slots, "number_slot should be present."
-
-
-
-
-
-
- # -
-

This test shows rule application, and filling an entity within a slot.

-
-
-
def test_slot_filling() -> None:
-
-
-
-
-
-
- # -
- -
-
-
    body = "12th december"
-    entity = BaseEntity(
-        range={"from": 0, "to": len(body)},
-        body=body,
-        dim="default",
-        type="basic",
-        values=[{"key": "value"}],
-        slot_names=["basic_slot"],
-    )
-    rules = {"intent": {"basic_slot": "basic"}}
-    intent = Intent(name="intent", score=0.8)
-    intent.apply(rules)
-
-    intent.fill_slot(entity)
-
-    assert intent.slots["basic_slot"].values[0] == entity
-
-
-
-
-
-
- # -
- -
-
-
def test_intent_json() -> None:
-    name = "intent_name"
-    intent = Intent(name=name, score=0.5)
-    intent_json = intent.json()
-    assert intent_json.get("name") == name
-
-
-
-
-
-
- diff --git a/docs/tests/types/slots/__init__.html b/docs/tests/types/slots/__init__.html deleted file mode 100644 index 2f36ff57..00000000 --- a/docs/tests/types/slots/__init__.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - __init__.py - - - -
-
-
-

__init__.py

-
-
-
-
-
- # -
- -
-
-

-
-
-
-
-
-
- diff --git a/docs/tests/types/slots/test_slot.html b/docs/tests/types/slots/test_slot.html deleted file mode 100644 index b7d7c643..00000000 --- a/docs/tests/types/slots/test_slot.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - test_slot.py - - - -
-
-
-

test_slot.py

-
-
-
-
-
- # -
- -
-
-
from dialogy.types.slots import Slot
-from dialogy.types.entity import BaseEntity
-
-
-
-
-
-
- diff --git a/docs/tests/workflow/__init__.html b/docs/tests/workflow/__init__.html deleted file mode 100644 index 282d6589..00000000 --- a/docs/tests/workflow/__init__.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - __init__.py - - - -
-
-
-

__init__.py

-
-
-
-
-
- # -
- -
-
-

-
-
-
-
-
-
- diff --git a/docs/tests/workflow/test_workflow.html b/docs/tests/workflow/test_workflow.html deleted file mode 100644 index 744629d4..00000000 --- a/docs/tests/workflow/test_workflow.html +++ /dev/null @@ -1,437 +0,0 @@ - - - - - test_workflow.py - - - -
-
-
-

test_workflow.py

-
-
-
-
-
- # -
- -
-
-
import pytest
-
-from dialogy.workflow import Workflow
-
-
-
-
-
-
- # -
-

Basic initialization.

-
-
-
def test_workflow_get_input() -> None:
-
-
-
-
-
-
- # -
- -
-
-
    workflow = Workflow(preprocessors=[], postprocessors=[])
-    assert workflow.input is None, "workflow.get_input() is not None."
-
-
-
-
-
-
- # -
-

We can set output and input as anything.

-
-
-
def test_workflow_set_output() -> None:
-
-
-
-
-
-
- # -
- -
-
-
    workflow = Workflow(preprocessors=[], postprocessors=[])
-    workflow.output = 10
-    assert workflow.output == 10, "workflow.get_output() should == 10."
-
-
-
-
-
-
- # -
-

load_model has to be defined by the subclass.

-
-
-
def test_workflow_load_model_error() -> None:
-
-
-
-
-
-
- # -
- -
-
-
    workflow = Workflow(preprocessors=[], postprocessors=[])
-    with pytest.raises(NotImplementedError):
-        workflow.load_model()
-
-
-
-
-
-
- # -
-

postprocessrors should be of type PluginFn.

-
-
-
def test_workflow_postprocessors_not_list_error() -> None:
-
-
-
-
-
-
- # -
- -
-
-
    with pytest.raises(TypeError):
-        _ = Workflow(preprocessors=[], postprocessors=10)  # type: ignore
-
-
-
-
-
-
- # -
-

preprocessors should be of type PluginFn

-
-
-
def test_workflow_preprocessors_not_list_error() -> None:
-
-
-
-
-
-
- # -
- -
-
-
    with pytest.raises(TypeError):
-        _ = Workflow(preprocessors=10, postprocessors=[])  # type: ignore
-
-
-
-
-
-
- # -
-

Trivial setup.

-
-
-
def test_workflow_run() -> None:
-
-
-
-
-
-
- # -
- -
-
-
-
-
-
-
-
-
- # -
- -
-
-
    def mock_postproc(w) -> None:
-        w.output = 10
-
-
-
-
-
-
- # -
- -
-
-
    def mock_preproc(w) -> None:
-        w.input = 20
-
-    workflow = Workflow(preprocessors=[mock_preproc], postprocessors=[mock_postproc])
-
-
-
-
-
-
- # -
-

initially the value of workflow.input is = 2

-
-
-
    workflow.run(2)
-
-
-
-
-
-
- # -
-

once the run method is complete, the value of input and output is modified by the -mock_postproc and mock_preproc functions.

-
-
-
    assert workflow.input == 20, "workflow.get_input() should be 20."
-    assert workflow.output == 10, "workflow.get_output() should be 10."
-
-
-
-
-
-
- # -
-

Sub-classes should implement the inference method.

-
-
-
def test_child_class_inference_not_implemented_error() -> None:
-
-
-
-
-
-
- # -
- -
-
-
-
-
-
-
-
-
- # -
- -
-
-
    class Wkflw(Workflow):
-        pass
-
-    w = Wkflw(preprocessors=[], postprocessors=[])
-    with pytest.raises(NotImplementedError):
-        w.inference()
-
-
-
-
-
-
- # -
- -
-
-
def test_not_callable_pre_post_processors_type_error() -> None:
-    workflow = Workflow(preprocessors=[2], postprocessors=[3])  # type: ignore
-
-    with pytest.raises(TypeError):
-        workflow.preprocess()
-
-    with pytest.raises(TypeError):
-        workflow.postprocess()
-
-
-
-
-
-
- # -
-

This test is just to get coverage.

-
-
-
def test_workflow_run_debug_mode() -> None:
-
-
-
-
-
-
- # -
- -
-
-
-
-
-
-
-
-
- # -
- -
-
-
    def mock_postproc(w):
-        w.output = 10
-
-
-
-
-
-
- # -
- -
-
-
    def mock_preproc(w):
-        w.input = 20
-
-    workflow = Workflow(
-        preprocessors=[mock_preproc], postprocessors=[mock_postproc], debug=True
-    )
-
-    workflow.run(2)
-
-    assert workflow.input == 20, "workflow.get_input() should be 2."
-    assert workflow.output == 10, "workflow.get_output() should be 10."
-
-
-
-
-
-
- # -
-

Trivial setup.

-
-
-
def test_workflow_flush() -> None:
-
-
-
-
-
-
- # -
- -
-
-
-
-
-
-
-
-
- # -
- -
-
-
    def mock_postproc(w) -> None:
-        w.output = 10
-
-
-
-
-
-
- # -
- -
-
-
    def mock_preproc(w) -> None:
-        w.input = 20
-
-    workflow = Workflow(preprocessors=[mock_preproc], postprocessors=[mock_postproc])
-
-
-
-
-
-
- # -
-

initially the value of workflow.input is = 2

-
-
-
    workflow.run(2)
-
-
-
-
-
-
- # -
-

once the run method is complete, the value of input and output is modified by the -mock_postproc and mock_preproc functions.

-
-
-
    assert workflow.input == 20, "workflow.get_input() should be 20."
-    assert workflow.output == 10, "workflow.get_output() should be 10."
-    workflow.flush()
-    assert workflow.input == None, "workflow.get_input() should be None."
-    assert workflow.output == None, "workflow.get_output() should be None."
-
-
-
-
-
-
- From 199e836283d0ed84e706007bd643f2bcbf5c55de Mon Sep 17 00:00:00 2001 From: Amresh Venugopal Date: Fri, 9 Apr 2021 05:44:01 +0530 Subject: [PATCH 03/30] add: flask theme and numpy. --- poetry.lock | 51 +++++++++++++++++++++++++++++++++++++++++++++++++- pyproject.toml | 2 ++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index f8dcd0c7..f7ecddd6 100644 --- a/poetry.lock +++ b/poetry.lock @@ -193,6 +193,17 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" version = "0.17" +[[package]] +category = "dev" +description = "Sphinx themes for Flask and related projects." +name = "flask-sphinx-themes" +optional = false +python-versions = "*" +version = "1.0.2" + +[package.dependencies] +Sphinx = "*" + [[package]] category = "dev" description = "Git Object Database" @@ -344,6 +355,14 @@ optional = false python-versions = "*" version = "0.4.3" +[[package]] +category = "main" +description = "NumPy is the fundamental package for array computing with Python." +name = "numpy" +optional = false +python-versions = ">=3.7" +version = "1.20.2" + [[package]] category = "main" description = "Core utilities for Python packages" @@ -834,7 +853,7 @@ python-versions = "*" version = "1.12.1" [metadata] -content-hash = "021a715dc2c2e9d500096c8f3a1b93668e4cb5ae3c6fc2fd47a1be7538fb6fad" +content-hash = "dd0c3a0b9543adc832c5a95d8d79182e9e482494fb0d9e8f19eeb76869f63550" lock-version = "1.0" python-versions = "^3.8" @@ -952,6 +971,10 @@ docutils = [ {file = "docutils-0.17-py2.py3-none-any.whl", hash = "sha256:a71042bb7207c03d5647f280427f14bfbd1a65c9eb84f4b341d85fafb6bb4bdf"}, {file = "docutils-0.17.tar.gz", hash = "sha256:e2ffeea817964356ba4470efba7c2f42b6b0de0b04e66378507e3e2504bbff4c"}, ] +flask-sphinx-themes = [ + {file = "Flask-Sphinx-Themes-1.0.2.tar.gz", hash = "sha256:bb23d7dd1a8ad9f47315bcb0439373c7feb24bcb0a1f8c52bb075f06489bb285"}, + {file = "Flask_Sphinx_Themes-1.0.2-py2.py3-none-any.whl", hash = "sha256:d00ac0c04947b8325e13be862ef604b60b71aae50e79e30b9df3560f3536cb8e"}, +] gitdb = [ {file = "gitdb-4.0.5-py3-none-any.whl", hash = "sha256:91f36bfb1ab7949b3b40e23736db18231bf7593edada2ba5c3a174a7b23657ac"}, {file = "gitdb-4.0.5.tar.gz", hash = "sha256:c9e1f2d0db7ddb9a704c2a0217be31214e91a4fe1dea1efad19ae42ba0c285c9"}, @@ -1092,6 +1115,32 @@ mypy-extensions = [ {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, ] +numpy = [ + {file = "numpy-1.20.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e9459f40244bb02b2f14f6af0cd0732791d72232bbb0dc4bab57ef88e75f6935"}, + {file = "numpy-1.20.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:a8e6859913ec8eeef3dbe9aed3bf475347642d1cdd6217c30f28dee8903528e6"}, + {file = "numpy-1.20.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:9cab23439eb1ebfed1aaec9cd42b7dc50fc96d5cd3147da348d9161f0501ada5"}, + {file = "numpy-1.20.2-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:9c0fab855ae790ca74b27e55240fe4f2a36a364a3f1ebcfd1fb5ac4088f1cec3"}, + {file = "numpy-1.20.2-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:61d5b4cf73622e4d0c6b83408a16631b670fc045afd6540679aa35591a17fe6d"}, + {file = "numpy-1.20.2-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:d15007f857d6995db15195217afdbddfcd203dfaa0ba6878a2f580eaf810ecd6"}, + {file = "numpy-1.20.2-cp37-cp37m-win32.whl", hash = "sha256:d76061ae5cab49b83a8cf3feacefc2053fac672728802ac137dd8c4123397677"}, + {file = "numpy-1.20.2-cp37-cp37m-win_amd64.whl", hash = "sha256:bad70051de2c50b1a6259a6df1daaafe8c480ca98132da98976d8591c412e737"}, + {file = "numpy-1.20.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:719656636c48be22c23641859ff2419b27b6bdf844b36a2447cb39caceb00935"}, + {file = "numpy-1.20.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:aa046527c04688af680217fffac61eec2350ef3f3d7320c07fd33f5c6e7b4d5f"}, + {file = "numpy-1.20.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:2428b109306075d89d21135bdd6b785f132a1f5a3260c371cee1fae427e12727"}, + {file = "numpy-1.20.2-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:e8e4fbbb7e7634f263c5b0150a629342cc19b47c5eba8d1cd4363ab3455ab576"}, + {file = "numpy-1.20.2-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:edb1f041a9146dcf02cd7df7187db46ab524b9af2515f392f337c7cbbf5b52cd"}, + {file = "numpy-1.20.2-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:c73a7975d77f15f7f68dacfb2bca3d3f479f158313642e8ea9058eea06637931"}, + {file = "numpy-1.20.2-cp38-cp38-win32.whl", hash = "sha256:6c915ee7dba1071554e70a3664a839fbc033e1d6528199d4621eeaaa5487ccd2"}, + {file = "numpy-1.20.2-cp38-cp38-win_amd64.whl", hash = "sha256:471c0571d0895c68da309dacee4e95a0811d0a9f9f532a48dc1bea5f3b7ad2b7"}, + {file = "numpy-1.20.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4703b9e937df83f5b6b7447ca5912b5f5f297aba45f91dbbbc63ff9278c7aa98"}, + {file = "numpy-1.20.2-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:abc81829c4039e7e4c30f7897938fa5d4916a09c2c7eb9b244b7a35ddc9656f4"}, + {file = "numpy-1.20.2-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:377751954da04d4a6950191b20539066b4e19e3b559d4695399c5e8e3e683bf6"}, + {file = "numpy-1.20.2-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:6e51e417d9ae2e7848314994e6fc3832c9d426abce9328cf7571eefceb43e6c9"}, + {file = "numpy-1.20.2-cp39-cp39-win32.whl", hash = "sha256:780ae5284cb770ade51d4b4a7dce4faa554eb1d88a56d0e8b9f35fca9b0270ff"}, + {file = "numpy-1.20.2-cp39-cp39-win_amd64.whl", hash = "sha256:924dc3f83de20437de95a73516f36e09918e9c9c18d5eac520062c49191025fb"}, + {file = "numpy-1.20.2-pp37-pypy37_pp73-manylinux2010_x86_64.whl", hash = "sha256:97ce8b8ace7d3b9288d88177e66ee75480fb79b9cf745e91ecfe65d91a856042"}, + {file = "numpy-1.20.2.zip", hash = "sha256:878922bf5ad7550aa044aa9301d417e2d3ae50f0f577de92051d739ac6096cee"}, +] packaging = [ {file = "packaging-20.8-py2.py3-none-any.whl", hash = "sha256:24e0da08660a87484d1602c30bb4902d74816b6985b93de36926f5bc95741858"}, {file = "packaging-20.8.tar.gz", hash = "sha256:78598185a7008a470d64526a8059de9aaa449238f280fc9eb6b13ba6c4109093"}, diff --git a/pyproject.toml b/pyproject.toml index c31d6114..da758b2d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,6 +15,7 @@ watchdog = "^1.0.2" docopt = "^0.6.2" copier = "^5.1.0" pydash = "^4.9.3" +numpy = "^1.20.2" [tool.poetry.dev-dependencies] pytest = "^6.2.0" @@ -29,6 +30,7 @@ pycco = "^0.6.0" watchdog = "^1.0.2" isort = "^5.7.0" sphinx = "^3.5.3" +Flask-Sphinx-Themes = "^1.0.2" [tool.poetry.scripts] dialogy = "dialogy.cli:main" From af6a8f0486343eb8a6413185c5b5d22f56f6b9be Mon Sep 17 00:00:00 2001 From: Amresh Venugopal Date: Fri, 9 Apr 2021 05:44:43 +0530 Subject: [PATCH 04/30] docs: remove dialogy docs made via pycco. --- docs/dialogy/__init__.html | 30 - docs/dialogy/cli/__init__.html | 75 -- docs/dialogy/cli/project.html | 76 --- docs/dialogy/constants/__init__.html | 127 ---- docs/dialogy/errors/__init__.html | 30 - docs/dialogy/parser/__init__.html | 30 - docs/dialogy/parser/text/__init__.html | 30 - docs/dialogy/parser/text/entity/__init__.html | 30 - .../parser/text/entity/duckling_parser.html | 643 ------------------ docs/dialogy/plugin/__init__.html | 30 - docs/dialogy/plugin/plugin.html | 130 ---- docs/dialogy/postprocess/__init__.html | 30 - docs/dialogy/postprocess/text/__init__.html | 32 - .../text/slot_filler/__init__.html | 44 -- .../text/slot_filler/rule_slot_filler.html | 195 ------ .../postprocess/text/voting/__init__.html | 30 - .../postprocess/text/voting/intent.html | 267 -------- docs/dialogy/preprocess/__init__.html | 30 - docs/dialogy/preprocess/text/__init__.html | 30 - .../preprocess/text/merge_asr_output.html | 176 ----- .../preprocess/text/normalize_utterance.html | 331 --------- docs/dialogy/types/__init__.html | 30 - docs/dialogy/types/entity/__init__.html | 64 -- docs/dialogy/types/entity/base_entity.html | 496 -------------- .../dialogy/types/entity/location_entity.html | 62 -- .../types/entity/numerical_entity.html | 75 -- docs/dialogy/types/entity/people_entity.html | 65 -- docs/dialogy/types/entity/time_entity.html | 86 --- .../types/entity/time_interval_entity.html | 121 ---- docs/dialogy/types/entity/utils.html | 108 --- docs/dialogy/types/intent/__init__.html | 284 -------- docs/dialogy/types/plugin/__init__.html | 41 -- docs/dialogy/types/signal/__init__.html | 30 - docs/dialogy/types/signal/signal.html | 35 - docs/dialogy/types/slots/__init__.html | 120 ---- docs/dialogy/types/utterances/__init__.html | 36 - docs/dialogy/utils/__init__.html | 30 - docs/dialogy/utils/logger.html | 67 -- docs/dialogy/workflow/__init__.html | 30 - docs/dialogy/workflow/workflow.html | 474 ------------- 40 files changed, 4650 deletions(-) delete mode 100644 docs/dialogy/__init__.html delete mode 100644 docs/dialogy/cli/__init__.html delete mode 100644 docs/dialogy/cli/project.html delete mode 100644 docs/dialogy/constants/__init__.html delete mode 100644 docs/dialogy/errors/__init__.html delete mode 100644 docs/dialogy/parser/__init__.html delete mode 100644 docs/dialogy/parser/text/__init__.html delete mode 100644 docs/dialogy/parser/text/entity/__init__.html delete mode 100644 docs/dialogy/parser/text/entity/duckling_parser.html delete mode 100644 docs/dialogy/plugin/__init__.html delete mode 100644 docs/dialogy/plugin/plugin.html delete mode 100644 docs/dialogy/postprocess/__init__.html delete mode 100644 docs/dialogy/postprocess/text/__init__.html delete mode 100644 docs/dialogy/postprocess/text/slot_filler/__init__.html delete mode 100644 docs/dialogy/postprocess/text/slot_filler/rule_slot_filler.html delete mode 100644 docs/dialogy/postprocess/text/voting/__init__.html delete mode 100644 docs/dialogy/postprocess/text/voting/intent.html delete mode 100644 docs/dialogy/preprocess/__init__.html delete mode 100644 docs/dialogy/preprocess/text/__init__.html delete mode 100644 docs/dialogy/preprocess/text/merge_asr_output.html delete mode 100644 docs/dialogy/preprocess/text/normalize_utterance.html delete mode 100644 docs/dialogy/types/__init__.html delete mode 100644 docs/dialogy/types/entity/__init__.html delete mode 100644 docs/dialogy/types/entity/base_entity.html delete mode 100644 docs/dialogy/types/entity/location_entity.html delete mode 100644 docs/dialogy/types/entity/numerical_entity.html delete mode 100644 docs/dialogy/types/entity/people_entity.html delete mode 100644 docs/dialogy/types/entity/time_entity.html delete mode 100644 docs/dialogy/types/entity/time_interval_entity.html delete mode 100644 docs/dialogy/types/entity/utils.html delete mode 100644 docs/dialogy/types/intent/__init__.html delete mode 100644 docs/dialogy/types/plugin/__init__.html delete mode 100644 docs/dialogy/types/signal/__init__.html delete mode 100644 docs/dialogy/types/signal/signal.html delete mode 100644 docs/dialogy/types/slots/__init__.html delete mode 100644 docs/dialogy/types/utterances/__init__.html delete mode 100644 docs/dialogy/utils/__init__.html delete mode 100644 docs/dialogy/utils/logger.html delete mode 100644 docs/dialogy/workflow/__init__.html delete mode 100644 docs/dialogy/workflow/workflow.html diff --git a/docs/dialogy/__init__.html b/docs/dialogy/__init__.html deleted file mode 100644 index 62dcb268..00000000 --- a/docs/dialogy/__init__.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - __init__.py - - - -
-
-
-

__init__.py

-
-
-
-
-
- # -
- -
-
-

-
-
-
-
-
-
- diff --git a/docs/dialogy/cli/__init__.html b/docs/dialogy/cli/__init__.html deleted file mode 100644 index eb55cb91..00000000 --- a/docs/dialogy/cli/__init__.html +++ /dev/null @@ -1,75 +0,0 @@ - - - - - __init__.py - - - -
-
-
-

__init__.py

-
-
-
-
-
- # -
-

Usage: - init.py create