diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 2f2eaa1..383fe11 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -13,7 +13,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - python-version: ["3.8"] + python-version: ["3.10"] timeout-minutes: 30 diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index 9008814..7b6b75f 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -13,7 +13,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - python-version: ["3.8"] + python-version: ["3.10"] timeout-minutes: 30 @@ -25,4 +25,5 @@ jobs: - name: Install dependencies run: pip install tox - name: Code style check - run: tox -e precommit + run: | + tox -e ruff-format,ruff-check diff --git a/.github/workflows/python-publish.yml b/.github/workflows/pypi-publish.yml similarity index 100% rename from .github/workflows/python-publish.yml rename to .github/workflows/pypi-publish.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8f11a02..f977b9f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,7 +13,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - python-version: ["3.8"] + python-version: ["3.10"] timeout-minutes: 30 @@ -25,8 +25,9 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install pytest pytest-cov pytest-randomly hypothesis-pytest - pip install -r requirements.txt + pip install pytest && pip install pytest-cov + pip install -e . + pip install -e ".[rasa]" - name: Unit tests and coverage run: | pytest -k "not gpt" \ @@ -36,7 +37,6 @@ jobs: --cov-report=xml \ --cov-report=html \ --cov-report=term \ - --hypothesis-show-statistics - name: Upload coverage to Codecov uses: codecov/codecov-action@v3 with: diff --git a/.github/workflows/test_gpt.yml b/.github/workflows/test_gpt.yml index f7af973..1c85c1a 100644 --- a/.github/workflows/test_gpt.yml +++ b/.github/workflows/test_gpt.yml @@ -9,7 +9,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - python-version: ["3.8"] + python-version: ["3.10"] timeout-minutes: 30 @@ -21,8 +21,8 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install pytest pytest-cov pytest-randomly hypothesis-pytest - pip install -r requirements.txt + pip install pytest + pip install -e . - name: Unit tests and coverage run: | pytest test_gpt.py \ @@ -32,7 +32,6 @@ jobs: --cov-report=xml \ --cov-report=html \ --cov-report=term \ - --hypothesis-show-statistics env: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} - name: Upload coverage to Codecov diff --git a/CHANGES.md b/CHANGES.md index 67fa048..85c4939 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,12 @@ # Change Log +## 0.0.5 (2024-02-10) + +* Make Rasa an optional package. +* Update OpenAI GPT models. +* Update Python version. +* Update building tools. + ## 0.0.4 (2023-07-07) * Fix the grounding process of formulas. diff --git a/Pipfile b/Pipfile deleted file mode 100644 index 1b70f3c..0000000 --- a/Pipfile +++ /dev/null @@ -1,24 +0,0 @@ -[[source]] -url = "https://pypi.org/simple" -verify_ssl = true -name = "pypi" - -[packages] - -[dev-packages] -hypothesis = "*" -mkdocs = "*" -mknotebooks = "*" -markdown-include = "*" -mkdocs-material = "*" -pre-commit = "*" -pymdown-extensions = "*" -pytest = "*" -black = "==22.6.0" -flake8 = "==4.0.1" -isort = "==5.12.0" -tox = "==3.25.1" -pytest-cov = "*" - -[requires] -python_version = "3.8" diff --git a/Pipfile.lock b/Pipfile.lock deleted file mode 100644 index b5a981e..0000000 --- a/Pipfile.lock +++ /dev/null @@ -1,1211 +0,0 @@ -{ - "_meta": { - "hash": { - "sha256": "bb314edf7198aee30168145cf778e3e4407cc061ae6312af30751e53a30344c8" - }, - "pipfile-spec": 6, - "requires": { - "python_version": "3.8" - }, - "sources": [ - { - "name": "pypi", - "url": "https://pypi.org/simple", - "verify_ssl": true - } - ] - }, - "default": {}, - "develop": { - "attrs": { - "hashes": [ - "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04", - "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015" - ], - "markers": "python_version >= '3.7'", - "version": "==23.1.0" - }, - "beautifulsoup4": { - "hashes": [ - "sha256:492bbc69dca35d12daac71c4db1bfff0c876c00ef4a2ffacce226d4638eb72da", - "sha256:bd2520ca0d9d7d12694a53d44ac482d181b4ec1888909b035a3dbf40d0f57d4a" - ], - "markers": "python_full_version >= '3.6.0'", - "version": "==4.12.2" - }, - "black": { - "hashes": [ - "sha256:074458dc2f6e0d3dab7928d4417bb6957bb834434516f21514138437accdbe90", - "sha256:187d96c5e713f441a5829e77120c269b6514418f4513a390b0499b0987f2ff1c", - "sha256:2ea29072e954a4d55a2ff58971b83365eba5d3d357352a07a7a4df0d95f51c78", - "sha256:4af5bc0e1f96be5ae9bd7aaec219c901a94d6caa2484c21983d043371c733fc4", - "sha256:560558527e52ce8afba936fcce93a7411ab40c7d5fe8c2463e279e843c0328ee", - "sha256:568ac3c465b1c8b34b61cd7a4e349e93f91abf0f9371eda1cf87194663ab684e", - "sha256:6797f58943fceb1c461fb572edbe828d811e719c24e03375fd25170ada53825e", - "sha256:6c1734ab264b8f7929cef8ae5f900b85d579e6cbfde09d7387da8f04771b51c6", - "sha256:6c6d39e28aed379aec40da1c65434c77d75e65bb59a1e1c283de545fb4e7c6c9", - "sha256:7ba9be198ecca5031cd78745780d65a3f75a34b2ff9be5837045dce55db83d1c", - "sha256:94783f636bca89f11eb5d50437e8e17fbc6a929a628d82304c80fa9cd945f256", - "sha256:a218d7e5856f91d20f04e931b6f16d15356db1c846ee55f01bac297a705ca24f", - "sha256:a3db5b6409b96d9bd543323b23ef32a1a2b06416d525d27e0f67e74f1446c8f2", - "sha256:ac609cf8ef5e7115ddd07d85d988d074ed00e10fbc3445aee393e70164a2219c", - "sha256:b154e6bbde1e79ea3260c4b40c0b7b3109ffcdf7bc4ebf8859169a6af72cd70b", - "sha256:b270a168d69edb8b7ed32c193ef10fd27844e5c60852039599f9184460ce0807", - "sha256:b9fd45787ba8aa3f5e0a0a98920c1012c884622c6c920dbe98dbd05bc7c70fbf", - "sha256:c85928b9d5f83b23cee7d0efcb310172412fbf7cb9d9ce963bd67fd141781def", - "sha256:c9a3ac16efe9ec7d7381ddebcc022119794872abce99475345c5a61aa18c45ad", - "sha256:cfaf3895a9634e882bf9d2363fed5af8888802d670f58b279b0bece00e9a872d", - "sha256:e439798f819d49ba1c0bd9664427a05aab79bfba777a6db94fd4e56fae0cb849", - "sha256:f586c26118bc6e714ec58c09df0157fe2d9ee195c764f630eb0d8e7ccce72e69", - "sha256:f6fe02afde060bbeef044af7996f335fbe90b039ccf3f5eb8f16df8b20f77666" - ], - "index": "pypi", - "version": "==22.6.0" - }, - "bleach": { - "hashes": [ - "sha256:1a1a85c1595e07d8db14c5f09f09e6433502c51c595970edc090551f0db99414", - "sha256:33c16e3353dbd13028ab4799a0f89a83f113405c766e9c122df8a06f5b85b3f4" - ], - "markers": "python_version >= '3.7'", - "version": "==6.0.0" - }, - "certifi": { - "hashes": [ - "sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7", - "sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716" - ], - "markers": "python_version >= '3.6'", - "version": "==2023.5.7" - }, - "cfgv": { - "hashes": [ - "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426", - "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736" - ], - "markers": "python_full_version >= '3.6.1'", - "version": "==3.3.1" - }, - "charset-normalizer": { - "hashes": [ - "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96", - "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c", - "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710", - "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706", - "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020", - "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252", - "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad", - "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329", - "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a", - "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f", - "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6", - "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4", - "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a", - "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46", - "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2", - "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23", - "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace", - "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd", - "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982", - "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10", - "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2", - "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea", - "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09", - "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5", - "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149", - "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489", - "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9", - "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80", - "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592", - "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3", - "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6", - "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed", - "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c", - "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200", - "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a", - "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e", - "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d", - "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6", - "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623", - "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669", - "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3", - "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa", - "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9", - "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2", - "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f", - "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1", - "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4", - "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a", - "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8", - "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3", - "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029", - "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f", - "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959", - "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22", - "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7", - "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952", - "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346", - "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e", - "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d", - "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299", - "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd", - "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a", - "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3", - "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037", - "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94", - "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c", - "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858", - "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a", - "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449", - "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c", - "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918", - "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1", - "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c", - "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac", - "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa" - ], - "markers": "python_full_version >= '3.7.0'", - "version": "==3.2.0" - }, - "click": { - "hashes": [ - "sha256:2739815aaa5d2c986a88f1e9230c55e17f0caad3d958a5e13ad0797c166db9e3", - "sha256:b97d0c74955da062a7d4ef92fadb583806a585b2ea81958a81bd72726cbb8e37" - ], - "markers": "python_version >= '3.7'", - "version": "==8.1.4" - }, - "colorama": { - "hashes": [ - "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", - "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'", - "version": "==0.4.6" - }, - "coverage": { - "extras": [ - "toml" - ], - "hashes": [ - "sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f", - "sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2", - "sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a", - "sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a", - "sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01", - "sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6", - "sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7", - "sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f", - "sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02", - "sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c", - "sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063", - "sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a", - "sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5", - "sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959", - "sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97", - "sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6", - "sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f", - "sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9", - "sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5", - "sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f", - "sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562", - "sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe", - "sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9", - "sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f", - "sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb", - "sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb", - "sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1", - "sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb", - "sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250", - "sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e", - "sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511", - "sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5", - "sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59", - "sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2", - "sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d", - "sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3", - "sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4", - "sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de", - "sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9", - "sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833", - "sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0", - "sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9", - "sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d", - "sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050", - "sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d", - "sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6", - "sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353", - "sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb", - "sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e", - "sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8", - "sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495", - "sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2", - "sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd", - "sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27", - "sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1", - "sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818", - "sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4", - "sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e", - "sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850", - "sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3" - ], - "markers": "python_version >= '3.7'", - "version": "==7.2.7" - }, - "defusedxml": { - "hashes": [ - "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69", - "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==0.7.1" - }, - "distlib": { - "hashes": [ - "sha256:14bad2d9b04d3a36127ac97f30b12a19268f211063d8f8ee4f47108896e11b46", - "sha256:f35c4b692542ca110de7ef0bea44d73981caeb34ca0b9b6b2e6d7790dda8f80e" - ], - "version": "==0.3.6" - }, - "exceptiongroup": { - "hashes": [ - "sha256:12c3e887d6485d16943a309616de20ae5582633e0a2eda17f4e10fd61c1e8af5", - "sha256:e346e69d186172ca7cf029c8c1d16235aa0e04035e5750b4b95039e65204328f" - ], - "markers": "python_version < '3.11'", - "version": "==1.1.2" - }, - "fastjsonschema": { - "hashes": [ - "sha256:4b90b252628ca695280924d863fe37234eebadc29c5360d322571233dc9746e0", - "sha256:f4eeb8a77cef54861dbf7424ac8ce71306f12cbb086c45131bcba2c6a4f726e3" - ], - "version": "==2.17.1" - }, - "filelock": { - "hashes": [ - "sha256:002740518d8aa59a26b0c76e10fb8c6e15eae825d34b6fdf670333fd7b938d81", - "sha256:cbb791cdea2a72f23da6ac5b5269ab0a0d161e9ef0100e653b69049a7706d1ec" - ], - "markers": "python_version >= '3.7'", - "version": "==3.12.2" - }, - "flake8": { - "hashes": [ - "sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d", - "sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d" - ], - "index": "pypi", - "version": "==4.0.1" - }, - "ghp-import": { - "hashes": [ - "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619", - "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343" - ], - "version": "==2.1.0" - }, - "gitdb": { - "hashes": [ - "sha256:6eb990b69df4e15bad899ea868dc46572c3f75339735663b81de79b06f17eb9a", - "sha256:c286cf298426064079ed96a9e4a9d39e7f3e9bf15ba60701e95f5492f28415c7" - ], - "markers": "python_version >= '3.7'", - "version": "==4.0.10" - }, - "gitpython": { - "hashes": [ - "sha256:8ce3bcf69adfdf7c7d503e78fd3b1c492af782d58893b650adb2ac8912ddd573", - "sha256:f04893614f6aa713a60cbbe1e6a97403ef633103cdd0ef5eb6efe0deb98dbe8d" - ], - "markers": "python_version >= '3.7'", - "version": "==3.1.31" - }, - "hypothesis": { - "hashes": [ - "sha256:a9b889f60e5804e3bba708dee471e3c4b190c6387d9cb74c7472b4a7d32377fb", - "sha256:dbc8ab5881224bf85b242fa08488faf8693b2d2b92ef2af9b21f43e0124365a1" - ], - "index": "pypi", - "version": "==6.80.1" - }, - "identify": { - "hashes": [ - "sha256:0aac67d5b4812498056d28a9a512a483f5085cc28640b02b258a59dac34301d4", - "sha256:986dbfb38b1140e763e413e6feb44cd731faf72d1909543178aa79b0e258265d" - ], - "markers": "python_version >= '3.7'", - "version": "==2.5.24" - }, - "idna": { - "hashes": [ - "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4", - "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2" - ], - "markers": "python_version >= '3.5'", - "version": "==3.4" - }, - "importlib-metadata": { - "hashes": [ - "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb", - "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743" - ], - "markers": "python_version < '3.10'", - "version": "==6.8.0" - }, - "importlib-resources": { - "hashes": [ - "sha256:4cf94875a8368bd89531a756df9a9ebe1f150e0f885030b461237bc7f2d905f2", - "sha256:d952faee11004c045f785bb5636e8f885bed30dc3c940d5d42798a2a4541c185" - ], - "markers": "python_version < '3.9'", - "version": "==6.0.0" - }, - "iniconfig": { - "hashes": [ - "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", - "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374" - ], - "markers": "python_version >= '3.7'", - "version": "==2.0.0" - }, - "isort": { - "hashes": [ - "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504", - "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6" - ], - "index": "pypi", - "version": "==5.12.0" - }, - "jinja2": { - "hashes": [ - "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852", - "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61" - ], - "markers": "python_version >= '3.7'", - "version": "==3.1.2" - }, - "jsonschema": { - "hashes": [ - "sha256:8caf5b57a990a98e9b39832ef3cb35c176fe331414252b6e1b26fd5866f891a4", - "sha256:b508dd6142bd03f4c3670534c80af68cd7bbff9ea830b9cf2625d4a3c49ddf60" - ], - "markers": "python_version >= '3.8'", - "version": "==4.18.0" - }, - "jsonschema-specifications": { - "hashes": [ - "sha256:3d2b82663aff01815f744bb5c7887e2121a63399b49b104a3c96145474d091d7", - "sha256:ca1c4dd059a9e7b34101cf5b3ab7ff1d18b139f35950d598d629837ef66e8f28" - ], - "markers": "python_version >= '3.8'", - "version": "==2023.6.1" - }, - "jupyter-client": { - "hashes": [ - "sha256:3af69921fe99617be1670399a0b857ad67275eefcfa291e2c81a160b7b650f5f", - "sha256:7441af0c0672edc5d28035e92ba5e32fadcfa8a4e608a434c228836a89df6158" - ], - "markers": "python_version >= '3.8'", - "version": "==8.3.0" - }, - "jupyter-core": { - "hashes": [ - "sha256:5ba5c7938a7f97a6b0481463f7ff0dbac7c15ba48cf46fa4035ca6e838aa1aba", - "sha256:ae9036db959a71ec1cac33081eeb040a79e681f08ab68b0883e9a676c7a90dce" - ], - "markers": "python_version >= '3.8'", - "version": "==5.3.1" - }, - "jupyterlab-pygments": { - "hashes": [ - "sha256:2405800db07c9f770863bcf8049a529c3dd4d3e28536638bd7c1c01d2748309f", - "sha256:7405d7fde60819d905a9fa8ce89e4cd830e318cdad22a0030f7a901da705585d" - ], - "markers": "python_version >= '3.7'", - "version": "==0.2.2" - }, - "markdown": { - "hashes": [ - "sha256:cbb516f16218e643d8e0a95b309f77eb118cb138d39a4f27851e6a63581db874", - "sha256:f5da449a6e1c989a4cea2631aa8ee67caa5a2ef855d551c88f9e309f4634c621" - ], - "markers": "python_version >= '3.6'", - "version": "==3.3.7" - }, - "markdown-include": { - "hashes": [ - "sha256:1d0623e0fc2757c38d35df53752768356162284259d259c486b4ab6285cdbbe3", - "sha256:32f0635b9cfef46997b307e2430022852529f7a5b87c0075c504283e7cc7db53" - ], - "index": "pypi", - "version": "==0.8.1" - }, - "markupsafe": { - "hashes": [ - "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e", - "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e", - "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431", - "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686", - "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559", - "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc", - "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c", - "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0", - "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4", - "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9", - "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575", - "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba", - "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d", - "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3", - "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00", - "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155", - "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac", - "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52", - "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f", - "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8", - "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b", - "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24", - "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea", - "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198", - "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0", - "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee", - "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be", - "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2", - "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707", - "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6", - "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58", - "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779", - "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636", - "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c", - "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad", - "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee", - "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc", - "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2", - "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48", - "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7", - "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e", - "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b", - "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa", - "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5", - "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e", - "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb", - "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9", - "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57", - "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc", - "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2" - ], - "markers": "python_version >= '3.7'", - "version": "==2.1.3" - }, - "mccabe": { - "hashes": [ - "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", - "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f" - ], - "version": "==0.6.1" - }, - "mergedeep": { - "hashes": [ - "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8", - "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307" - ], - "markers": "python_version >= '3.6'", - "version": "==1.3.4" - }, - "mistune": { - "hashes": [ - "sha256:b9b3e438efbb57c62b5beb5e134dab664800bdf1284a7ee09e8b12b13eb1aac6", - "sha256:e912116c13aa0944f9dc530db38eb88f6a77087ab128f49f84a48f4c05ea163c" - ], - "markers": "python_version >= '3.7'", - "version": "==3.0.1" - }, - "mkdocs": { - "hashes": [ - "sha256:5955093bbd4dd2e9403c5afaf57324ad8b04f16886512a3ee6ef828956481c57", - "sha256:6ee46d309bda331aac915cd24aab882c179a933bd9e77b80ce7d2eaaa3f689dd" - ], - "index": "pypi", - "version": "==1.4.3" - }, - "mkdocs-material": { - "hashes": [ - "sha256:5bcf8fb79ac2f253c0ffe93fa181cba87718c6438f459dc4180ac7418cc9a450", - "sha256:981dd39979723d4cda7cfc77bbbe5e54922d5761a7af23fb8ba9edb52f114b13" - ], - "index": "pypi", - "version": "==9.1.18" - }, - "mkdocs-material-extensions": { - "hashes": [ - "sha256:9c003da71e2cc2493d910237448c672e00cefc800d3d6ae93d2fc69979e3bd93", - "sha256:e41d9f38e4798b6617ad98ca8f7f1157b1e4385ac1459ca1e4ea219b556df945" - ], - "markers": "python_version >= '3.7'", - "version": "==1.1.1" - }, - "mknotebooks": { - "hashes": [ - "sha256:e2fa000b706683fc56b93adada7190a0da22ad85c4f1bfd5c4468cc3552b78e5" - ], - "index": "pypi", - "version": "==0.7.1" - }, - "mypy-extensions": { - "hashes": [ - "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", - "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782" - ], - "markers": "python_version >= '3.5'", - "version": "==1.0.0" - }, - "nbclient": { - "hashes": [ - "sha256:25e861299e5303a0477568557c4045eccc7a34c17fc08e7959558707b9ebe548", - "sha256:f9b179cd4b2d7bca965f900a2ebf0db4a12ebff2f36a711cb66861e4ae158e55" - ], - "markers": "python_full_version >= '3.8.0'", - "version": "==0.8.0" - }, - "nbconvert": { - "hashes": [ - "sha256:24fcf27efdef2b51d7f090cc5ce5a9b178766a55be513c4ebab08c91899ab550", - "sha256:5a445c6794b0791984bc5436608fe2c066cb43c83920c7bc91bde3b765e9a264" - ], - "markers": "python_version >= '3.7'", - "version": "==7.6.0" - }, - "nbformat": { - "hashes": [ - "sha256:8c8fa16d6d05062c26177754bfbfac22de644888e2ef69d27ad2a334cf2576e5", - "sha256:e98ebb6120c3efbafdee2a40af2a140cadee90bb06dd69a2a63d9551fcc7f976" - ], - "markers": "python_version >= '3.8'", - "version": "==5.9.0" - }, - "nodeenv": { - "hashes": [ - "sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2", - "sha256:df865724bb3c3adc86b3876fa209771517b0cfe596beff01a92700e0e8be4cec" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'", - "version": "==1.8.0" - }, - "packaging": { - "hashes": [ - "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61", - "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f" - ], - "markers": "python_version >= '3.7'", - "version": "==23.1" - }, - "pandocfilters": { - "hashes": [ - "sha256:0b679503337d233b4339a817bfc8c50064e2eff681314376a47cb582305a7a38", - "sha256:33aae3f25fd1a026079f5d27bdd52496f0e0803b3469282162bafdcbdf6ef14f" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.5.0" - }, - "pathspec": { - "hashes": [ - "sha256:2798de800fa92780e33acca925945e9a19a133b715067cf165b8866c15a31687", - "sha256:d8af70af76652554bd134c22b3e8a1cc46ed7d91edcdd721ef1a0c51a84a5293" - ], - "markers": "python_version >= '3.7'", - "version": "==0.11.1" - }, - "pkgutil-resolve-name": { - "hashes": [ - "sha256:357d6c9e6a755653cfd78893817c0853af365dd51ec97f3d358a819373bbd174", - "sha256:ca27cc078d25c5ad71a9de0a7a330146c4e014c2462d9af19c6b828280649c5e" - ], - "markers": "python_version < '3.9'", - "version": "==1.3.10" - }, - "platformdirs": { - "hashes": [ - "sha256:cec7b889196b9144d088e4c57d9ceef7374f6c39694ad1577a0aab50d27ea28c", - "sha256:f87ca4fcff7d2b0f81c6a748a77973d7af0f4d526f98f308477c3c436c74d528" - ], - "markers": "python_version >= '3.7'", - "version": "==3.8.1" - }, - "pluggy": { - "hashes": [ - "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849", - "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3" - ], - "markers": "python_version >= '3.7'", - "version": "==1.2.0" - }, - "pre-commit": { - "hashes": [ - "sha256:10badb65d6a38caff29703362271d7dca483d01da88f9d7e05d0b97171c136cb", - "sha256:a2256f489cd913d575c145132ae196fe335da32d91a8294b7afe6622335dd023" - ], - "index": "pypi", - "version": "==3.3.3" - }, - "py": { - "hashes": [ - "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719", - "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==1.11.0" - }, - "pycodestyle": { - "hashes": [ - "sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20", - "sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==2.8.0" - }, - "pyflakes": { - "hashes": [ - "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c", - "sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.4.0" - }, - "pygments": { - "hashes": [ - "sha256:8ace4d3c1dd481894b2005f560ead0f9f19ee64fe983366be1a21e171d12775c", - "sha256:db2db3deb4b4179f399a09054b023b6a586b76499d36965813c71aa8ed7b5fd1" - ], - "markers": "python_version >= '3.7'", - "version": "==2.15.1" - }, - "pymdown-extensions": { - "hashes": [ - "sha256:ae66d84013c5d027ce055693e09a4628b67e9dec5bce05727e45b0918e36f274", - "sha256:b44e1093a43b8a975eae17b03c3a77aad4681b3b56fce60ce746dbef1944c8cb" - ], - "index": "pypi", - "version": "==10.0.1" - }, - "pytest": { - "hashes": [ - "sha256:78bf16451a2eb8c7a2ea98e32dc119fd2aa758f1d5d66dbf0a59d69a3969df32", - "sha256:b4bf8c45bd59934ed84001ad51e11b4ee40d40a1229d2c79f9c592b0a3f6bd8a" - ], - "index": "pypi", - "version": "==7.4.0" - }, - "pytest-cov": { - "hashes": [ - "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6", - "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a" - ], - "index": "pypi", - "version": "==4.1.0" - }, - "python-dateutil": { - "hashes": [ - "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", - "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.8.2" - }, - "pyyaml": { - "hashes": [ - "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf", - "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293", - "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b", - "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57", - "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b", - "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4", - "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07", - "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba", - "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9", - "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287", - "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513", - "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0", - "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782", - "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0", - "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92", - "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f", - "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2", - "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc", - "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1", - "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c", - "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86", - "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4", - "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c", - "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34", - "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b", - "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d", - "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c", - "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb", - "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7", - "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737", - "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3", - "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d", - "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358", - "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53", - "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78", - "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803", - "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a", - "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f", - "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174", - "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5" - ], - "markers": "python_version >= '3.6'", - "version": "==6.0" - }, - "pyyaml-env-tag": { - "hashes": [ - "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb", - "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069" - ], - "markers": "python_version >= '3.6'", - "version": "==0.1" - }, - "pyzmq": { - "hashes": [ - "sha256:01f06f33e12497dca86353c354461f75275a5ad9eaea181ac0dc1662da8074fa", - "sha256:0b6b42f7055bbc562f63f3df3b63e3dd1ebe9727ff0f124c3aa7bcea7b3a00f9", - "sha256:0c4fc2741e0513b5d5a12fe200d6785bbcc621f6f2278893a9ca7bed7f2efb7d", - "sha256:108c96ebbd573d929740d66e4c3d1bdf31d5cde003b8dc7811a3c8c5b0fc173b", - "sha256:13bbe36da3f8aaf2b7ec12696253c0bf6ffe05f4507985a8844a1081db6ec22d", - "sha256:154bddda2a351161474b36dba03bf1463377ec226a13458725183e508840df89", - "sha256:19d0383b1f18411d137d891cab567de9afa609b214de68b86e20173dc624c101", - "sha256:1a6169e69034eaa06823da6a93a7739ff38716142b3596c180363dee729d713d", - "sha256:1fc56a0221bdf67cfa94ef2d6ce5513a3d209c3dfd21fed4d4e87eca1822e3a3", - "sha256:2a21fec5c3cea45421a19ccbe6250c82f97af4175bc09de4d6dd78fb0cb4c200", - "sha256:2b15247c49d8cbea695b321ae5478d47cffd496a2ec5ef47131a9e79ddd7e46c", - "sha256:2f5efcc29056dfe95e9c9db0dfbb12b62db9c4ad302f812931b6d21dd04a9119", - "sha256:2f666ae327a6899ff560d741681fdcdf4506f990595201ed39b44278c471ad98", - "sha256:332616f95eb400492103ab9d542b69d5f0ff628b23129a4bc0a2fd48da6e4e0b", - "sha256:33d5c8391a34d56224bccf74f458d82fc6e24b3213fc68165c98b708c7a69325", - "sha256:3575699d7fd7c9b2108bc1c6128641a9a825a58577775ada26c02eb29e09c517", - "sha256:3830be8826639d801de9053cf86350ed6742c4321ba4236e4b5568528d7bfed7", - "sha256:3a522510e3434e12aff80187144c6df556bb06fe6b9d01b2ecfbd2b5bfa5c60c", - "sha256:3bed53f7218490c68f0e82a29c92335daa9606216e51c64f37b48eb78f1281f4", - "sha256:414b8beec76521358b49170db7b9967d6974bdfc3297f47f7d23edec37329b00", - "sha256:442d3efc77ca4d35bee3547a8e08e8d4bb88dadb54a8377014938ba98d2e074a", - "sha256:47b915ba666c51391836d7ed9a745926b22c434efa76c119f77bcffa64d2c50c", - "sha256:48e5e59e77c1a83162ab3c163fc01cd2eebc5b34560341a67421b09be0891287", - "sha256:4a82faae00d1eed4809c2f18b37f15ce39a10a1c58fe48b60ad02875d6e13d80", - "sha256:4a983c8694667fd76d793ada77fd36c8317e76aa66eec75be2653cef2ea72883", - "sha256:4c2fc7aad520a97d64ffc98190fce6b64152bde57a10c704b337082679e74f67", - "sha256:4cb27ef9d3bdc0c195b2dc54fcb8720e18b741624686a81942e14c8b67cc61a6", - "sha256:4d67609b37204acad3d566bb7391e0ecc25ef8bae22ff72ebe2ad7ffb7847158", - "sha256:5482f08d2c3c42b920e8771ae8932fbaa0a67dff925fc476996ddd8155a170f3", - "sha256:5489738a692bc7ee9a0a7765979c8a572520d616d12d949eaffc6e061b82b4d1", - "sha256:5693dcc4f163481cf79e98cf2d7995c60e43809e325b77a7748d8024b1b7bcba", - "sha256:58416db767787aedbfd57116714aad6c9ce57215ffa1c3758a52403f7c68cff5", - "sha256:5873d6a60b778848ce23b6c0ac26c39e48969823882f607516b91fb323ce80e5", - "sha256:5af31493663cf76dd36b00dafbc839e83bbca8a0662931e11816d75f36155897", - "sha256:5e7fbcafa3ea16d1de1f213c226005fea21ee16ed56134b75b2dede5a2129e62", - "sha256:65346f507a815a731092421d0d7d60ed551a80d9b75e8b684307d435a5597425", - "sha256:6581e886aec3135964a302a0f5eb68f964869b9efd1dbafdebceaaf2934f8a68", - "sha256:69511d604368f3dc58d4be1b0bad99b61ee92b44afe1cd9b7bd8c5e34ea8248a", - "sha256:7018289b402ebf2b2c06992813523de61d4ce17bd514c4339d8f27a6f6809492", - "sha256:71c7b5896e40720d30cd77a81e62b433b981005bbff0cb2f739e0f8d059b5d99", - "sha256:75217e83faea9edbc29516fc90c817bc40c6b21a5771ecb53e868e45594826b0", - "sha256:7e23a8c3b6c06de40bdb9e06288180d630b562db8ac199e8cc535af81f90e64b", - "sha256:80c41023465d36280e801564a69cbfce8ae85ff79b080e1913f6e90481fb8957", - "sha256:831ba20b660b39e39e5ac8603e8193f8fce1ee03a42c84ade89c36a251449d80", - "sha256:851fb2fe14036cfc1960d806628b80276af5424db09fe5c91c726890c8e6d943", - "sha256:8751f9c1442624da391bbd92bd4b072def6d7702a9390e4479f45c182392ff78", - "sha256:8b45d722046fea5a5694cba5d86f21f78f0052b40a4bbbbf60128ac55bfcc7b6", - "sha256:8b697774ea8273e3c0460cf0bba16cd85ca6c46dfe8b303211816d68c492e132", - "sha256:90146ab578931e0e2826ee39d0c948d0ea72734378f1898939d18bc9c823fcf9", - "sha256:9301cf1d7fc1ddf668d0abbe3e227fc9ab15bc036a31c247276012abb921b5ff", - "sha256:95bd3a998d8c68b76679f6b18f520904af5204f089beebb7b0301d97704634dd", - "sha256:968b0c737797c1809ec602e082cb63e9824ff2329275336bb88bd71591e94a90", - "sha256:97d984b1b2f574bc1bb58296d3c0b64b10e95e7026f8716ed6c0b86d4679843f", - "sha256:9e68ae9864d260b18f311b68d29134d8776d82e7f5d75ce898b40a88df9db30f", - "sha256:adecf6d02b1beab8d7c04bc36f22bb0e4c65a35eb0b4750b91693631d4081c70", - "sha256:af56229ea6527a849ac9fb154a059d7e32e77a8cba27e3e62a1e38d8808cb1a5", - "sha256:b324fa769577fc2c8f5efcd429cef5acbc17d63fe15ed16d6dcbac2c5eb00849", - "sha256:b5a07c4f29bf7cb0164664ef87e4aa25435dcc1f818d29842118b0ac1eb8e2b5", - "sha256:bad172aba822444b32eae54c2d5ab18cd7dee9814fd5c7ed026603b8cae2d05f", - "sha256:bdca18b94c404af6ae5533cd1bc310c4931f7ac97c148bbfd2cd4bdd62b96253", - "sha256:be24a5867b8e3b9dd5c241de359a9a5217698ff616ac2daa47713ba2ebe30ad1", - "sha256:be86a26415a8b6af02cd8d782e3a9ae3872140a057f1cadf0133de685185c02b", - "sha256:c66b7ff2527e18554030319b1376d81560ca0742c6e0b17ff1ee96624a5f1afd", - "sha256:c8398a1b1951aaa330269c35335ae69744be166e67e0ebd9869bdc09426f3871", - "sha256:cad9545f5801a125f162d09ec9b724b7ad9b6440151b89645241d0120e119dcc", - "sha256:cb6d161ae94fb35bb518b74bb06b7293299c15ba3bc099dccd6a5b7ae589aee3", - "sha256:d40682ac60b2a613d36d8d3a0cd14fbdf8e7e0618fbb40aa9fa7b796c9081584", - "sha256:d6128d431b8dfa888bf51c22a04d48bcb3d64431caf02b3cb943269f17fd2994", - "sha256:dbc466744a2db4b7ca05589f21ae1a35066afada2f803f92369f5877c100ef62", - "sha256:ddbef8b53cd16467fdbfa92a712eae46dd066aa19780681a2ce266e88fbc7165", - "sha256:e21cc00e4debe8f54c3ed7b9fcca540f46eee12762a9fa56feb8512fd9057161", - "sha256:eb52e826d16c09ef87132c6e360e1879c984f19a4f62d8a935345deac43f3c12", - "sha256:f0d9e7ba6a815a12c8575ba7887da4b72483e4cfc57179af10c9b937f3f9308f", - "sha256:f1e931d9a92f628858a50f5bdffdfcf839aebe388b82f9d2ccd5d22a38a789dc", - "sha256:f45808eda8b1d71308c5416ef3abe958f033fdbb356984fabbfc7887bed76b3f", - "sha256:f6d39e42a0aa888122d1beb8ec0d4ddfb6c6b45aecb5ba4013c27e2f28657765", - "sha256:fc34fdd458ff77a2a00e3c86f899911f6f269d393ca5675842a6e92eea565bae" - ], - "markers": "python_version >= '3.6'", - "version": "==25.1.0" - }, - "referencing": { - "hashes": [ - "sha256:90cb53782d550ba28d2166ef3f55731f38397def8832baac5d45235f1995e35e", - "sha256:d3c8f323ee1480095da44d55917cfb8278d73d6b4d5f677e3e40eb21314ac67f" - ], - "markers": "python_version >= '3.8'", - "version": "==0.29.1" - }, - "regex": { - "hashes": [ - "sha256:0385e73da22363778ef2324950e08b689abdf0b108a7d8decb403ad7f5191938", - "sha256:051da80e6eeb6e239e394ae60704d2b566aa6a7aed6f2890a7967307267a5dc6", - "sha256:05ed27acdf4465c95826962528f9e8d41dbf9b1aa8531a387dee6ed215a3e9ef", - "sha256:0654bca0cdf28a5956c83839162692725159f4cda8d63e0911a2c0dc76166525", - "sha256:09e4a1a6acc39294a36b7338819b10baceb227f7f7dbbea0506d419b5a1dd8af", - "sha256:0b49c764f88a79160fa64f9a7b425620e87c9f46095ef9c9920542ab2495c8bc", - "sha256:0b71e63226e393b534105fcbdd8740410dc6b0854c2bfa39bbda6b0d40e59a54", - "sha256:0c29ca1bd61b16b67be247be87390ef1d1ef702800f91fbd1991f5c4421ebae8", - "sha256:10590510780b7541969287512d1b43f19f965c2ece6c9b1c00fc367b29d8dce7", - "sha256:10cb847aeb1728412c666ab2e2000ba6f174f25b2bdc7292e7dd71b16db07568", - "sha256:12b74fbbf6cbbf9dbce20eb9b5879469e97aeeaa874145517563cca4029db65c", - "sha256:20326216cc2afe69b6e98528160b225d72f85ab080cbdf0b11528cbbaba2248f", - "sha256:2239d95d8e243658b8dbb36b12bd10c33ad6e6933a54d36ff053713f129aa536", - "sha256:25be746a8ec7bc7b082783216de8e9473803706723b3f6bef34b3d0ed03d57e2", - "sha256:271f0bdba3c70b58e6f500b205d10a36fb4b58bd06ac61381b68de66442efddb", - "sha256:29cdd471ebf9e0f2fb3cac165efedc3c58db841d83a518b082077e612d3ee5df", - "sha256:2d44dc13229905ae96dd2ae2dd7cebf824ee92bc52e8cf03dcead37d926da019", - "sha256:3676f1dd082be28b1266c93f618ee07741b704ab7b68501a173ce7d8d0d0ca18", - "sha256:36efeba71c6539d23c4643be88295ce8c82c88bbd7c65e8a24081d2ca123da3f", - "sha256:3e5219bf9e75993d73ab3d25985c857c77e614525fac9ae02b1bebd92f7cecac", - "sha256:43e1dd9d12df9004246bacb79a0e5886b3b6071b32e41f83b0acbf293f820ee8", - "sha256:457b6cce21bee41ac292d6753d5e94dcbc5c9e3e3a834da285b0bde7aa4a11e9", - "sha256:463b6a3ceb5ca952e66550a4532cef94c9a0c80dc156c4cc343041951aec1697", - "sha256:4959e8bcbfda5146477d21c3a8ad81b185cd252f3d0d6e4724a5ef11c012fb06", - "sha256:4d3850beab9f527f06ccc94b446c864059c57651b3f911fddb8d9d3ec1d1b25d", - "sha256:5708089ed5b40a7b2dc561e0c8baa9535b77771b64a8330b684823cfd5116036", - "sha256:5c6b48d0fa50d8f4df3daf451be7f9689c2bde1a52b1225c5926e3f54b6a9ed1", - "sha256:61474f0b41fe1a80e8dfa70f70ea1e047387b7cd01c85ec88fa44f5d7561d787", - "sha256:6343c6928282c1f6a9db41f5fd551662310e8774c0e5ebccb767002fcf663ca9", - "sha256:65ba8603753cec91c71de423a943ba506363b0e5c3fdb913ef8f9caa14b2c7e0", - "sha256:687ea9d78a4b1cf82f8479cab23678aff723108df3edeac098e5b2498879f4a7", - "sha256:6b2675068c8b56f6bfd5a2bda55b8accbb96c02fd563704732fd1c95e2083461", - "sha256:7117d10690c38a622e54c432dfbbd3cbd92f09401d622902c32f6d377e2300ee", - "sha256:7178bbc1b2ec40eaca599d13c092079bf529679bf0371c602edaa555e10b41c3", - "sha256:72d1a25bf36d2050ceb35b517afe13864865268dfb45910e2e17a84be6cbfeb0", - "sha256:742e19a90d9bb2f4a6cf2862b8b06dea5e09b96c9f2df1779e53432d7275331f", - "sha256:74390d18c75054947e4194019077e243c06fbb62e541d8817a0fa822ea310c14", - "sha256:74419d2b50ecb98360cfaa2974da8689cb3b45b9deff0dcf489c0d333bcc1477", - "sha256:824bf3ac11001849aec3fa1d69abcb67aac3e150a933963fb12bda5151fe1bfd", - "sha256:83320a09188e0e6c39088355d423aa9d056ad57a0b6c6381b300ec1a04ec3d16", - "sha256:837328d14cde912af625d5f303ec29f7e28cdab588674897baafaf505341f2fc", - "sha256:841d6e0e5663d4c7b4c8099c9997be748677d46cbf43f9f471150e560791f7ff", - "sha256:87b2a5bb5e78ee0ad1de71c664d6eb536dc3947a46a69182a90f4410f5e3f7dd", - "sha256:890e5a11c97cf0d0c550eb661b937a1e45431ffa79803b942a057c4fb12a2da2", - "sha256:8abbc5d54ea0ee80e37fef009e3cec5dafd722ed3c829126253d3e22f3846f1e", - "sha256:8e3f1316c2293e5469f8f09dc2d76efb6c3982d3da91ba95061a7e69489a14ef", - "sha256:8f56fcb7ff7bf7404becdfc60b1e81a6d0561807051fd2f1860b0d0348156a07", - "sha256:9427a399501818a7564f8c90eced1e9e20709ece36be701f394ada99890ea4b3", - "sha256:976d7a304b59ede34ca2921305b57356694f9e6879db323fd90a80f865d355a3", - "sha256:9a5bfb3004f2144a084a16ce19ca56b8ac46e6fd0651f54269fc9e230edb5e4a", - "sha256:9beb322958aaca059f34975b0df135181f2e5d7a13b84d3e0e45434749cb20f7", - "sha256:9edcbad1f8a407e450fbac88d89e04e0b99a08473f666a3f3de0fd292badb6aa", - "sha256:9edce5281f965cf135e19840f4d93d55b3835122aa76ccacfd389e880ba4cf82", - "sha256:a4c3b7fa4cdaa69268748665a1a6ff70c014d39bb69c50fda64b396c9116cf77", - "sha256:a8105e9af3b029f243ab11ad47c19b566482c150c754e4c717900a798806b222", - "sha256:a99b50300df5add73d307cf66abea093304a07eb017bce94f01e795090dea87c", - "sha256:aad51907d74fc183033ad796dd4c2e080d1adcc4fd3c0fd4fd499f30c03011cd", - "sha256:af4dd387354dc83a3bff67127a124c21116feb0d2ef536805c454721c5d7993d", - "sha256:b28f5024a3a041009eb4c333863d7894d191215b39576535c6734cd88b0fcb68", - "sha256:b4598b1897837067a57b08147a68ac026c1e73b31ef6e36deeeb1fa60b2933c9", - "sha256:b6192d5af2ccd2a38877bfef086d35e6659566a335b1492786ff254c168b1693", - "sha256:b862c2b9d5ae38a68b92e215b93f98d4c5e9454fa36aae4450f61dd33ff48487", - "sha256:b956231ebdc45f5b7a2e1f90f66a12be9610ce775fe1b1d50414aac1e9206c06", - "sha256:bb60b503ec8a6e4e3e03a681072fa3a5adcbfa5479fa2d898ae2b4a8e24c4591", - "sha256:bbb02fd4462f37060122e5acacec78e49c0fbb303c30dd49c7f493cf21fc5b27", - "sha256:bdff5eab10e59cf26bc479f565e25ed71a7d041d1ded04ccf9aee1d9f208487a", - "sha256:c123f662be8ec5ab4ea72ea300359023a5d1df095b7ead76fedcd8babbedf969", - "sha256:c2b867c17a7a7ae44c43ebbeb1b5ff406b3e8d5b3e14662683e5e66e6cc868d3", - "sha256:c5f8037000eb21e4823aa485149f2299eb589f8d1fe4b448036d230c3f4e68e0", - "sha256:c6a57b742133830eec44d9b2290daf5cbe0a2f1d6acee1b3c7b1c7b2f3606df7", - "sha256:ccf91346b7bd20c790310c4147eee6ed495a54ddb6737162a36ce9dbef3e4751", - "sha256:cf67ca618b4fd34aee78740bea954d7c69fdda419eb208c2c0c7060bb822d747", - "sha256:d2da3abc88711bce7557412310dfa50327d5769a31d1c894b58eb256459dc289", - "sha256:d4f03bb71d482f979bda92e1427f3ec9b220e62a7dd337af0aa6b47bf4498f72", - "sha256:d54af539295392611e7efbe94e827311eb8b29668e2b3f4cadcfe6f46df9c777", - "sha256:d77f09bc4b55d4bf7cc5eba785d87001d6757b7c9eec237fe2af57aba1a071d9", - "sha256:d831c2f8ff278179705ca59f7e8524069c1a989e716a1874d6d1aab6119d91d1", - "sha256:dbbbfce33cd98f97f6bffb17801b0576e653f4fdb1d399b2ea89638bc8d08ae1", - "sha256:dcba6dae7de533c876255317c11f3abe4907ba7d9aa15d13e3d9710d4315ec0e", - "sha256:e0bb18053dfcfed432cc3ac632b5e5e5c5b7e55fb3f8090e867bfd9b054dbcbf", - "sha256:e2fbd6236aae3b7f9d514312cdb58e6494ee1c76a9948adde6eba33eb1c4264f", - "sha256:e5087a3c59eef624a4591ef9eaa6e9a8d8a94c779dade95d27c0bc24650261cd", - "sha256:e8915cc96abeb8983cea1df3c939e3c6e1ac778340c17732eb63bb96247b91d2", - "sha256:ea353ecb6ab5f7e7d2f4372b1e779796ebd7b37352d290096978fea83c4dba0c", - "sha256:ee2d1a9a253b1729bb2de27d41f696ae893507c7db224436abe83ee25356f5c1", - "sha256:f415f802fbcafed5dcc694c13b1292f07fe0befdb94aa8a52905bd115ff41e88", - "sha256:fb5ec16523dc573a4b277663a2b5a364e2099902d3944c9419a40ebd56a118f9", - "sha256:fea75c3710d4f31389eed3c02f62d0b66a9da282521075061ce875eb5300cf23" - ], - "markers": "python_version >= '3.6'", - "version": "==2023.6.3" - }, - "requests": { - "hashes": [ - "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", - "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" - ], - "markers": "python_version >= '3.7'", - "version": "==2.31.0" - }, - "rpds-py": { - "hashes": [ - "sha256:0c62fdb01111da948e8446caaefebf2ca4307a58fcbc10039b48d0db7205397c", - "sha256:0df2ae878fd99342415a42659f3bcee34b12441a509033e0ab04c6e301895607", - "sha256:0dfec14a64759186153115d987f9e60b1fa7e8e14a00004a02482e696199e554", - "sha256:0e8da63b9baa154ec9ddd6dd397893830d17e5812ceb50edbae8122d8ecb9f2e", - "sha256:13aed64f2e0bef04a0eae6d1d1295f901f6c1640d1e20264dc3b19d62ef1721d", - "sha256:180963bb3e1fcc6ed6313ece5e065f0df4021a7eb7016084d3cbc90cd2a8af3e", - "sha256:1891903e567d728175c0475a1f0ffc1d1580013b0b265b9e2f1b8c93d58b2d05", - "sha256:18a97bb7f211b247346983092186927c517153ac155c611f43ca83d5ee93a3e2", - "sha256:1f60a7eb96fedcc5bf59761d33ac0f2f127d75f8c4b99ed0f138fc0f3601c537", - "sha256:22afed13c6ad4ccdc650ad44cbc06f835f4f30de201bd4ee2afc09bde06a357a", - "sha256:246a410e540ce7f635c6ad1b7aa00b7dcfc966c5f97217e41092c3f764dac4bf", - "sha256:247a1fd9bcdb373380cb8c0041417c9995fc163c9d88a39f5ec3d960114aca22", - "sha256:25a4b357ba7540d7cc709915699d67d505c8177cdb30824127092e1b4886b504", - "sha256:2d6a26953d3b291dd7e79e43bb203ed134ca889e63c8ebbc65e3ff98154303ef", - "sha256:300b8579740b06e246238b730e636f314a7d8dc475be1868650f5d3ddc29a0d8", - "sha256:316a66b0379a9e954872593aa2eb6d61949da2ecc8f572b4dafb07aa0e247171", - "sha256:358c7a976482537d26fcbdc7808e7cc25f64816fe89681f9aa8bef13e16c7370", - "sha256:36266e2e49b36ec6cc148e36667030d8e7f1c009edd2ca978ab09ed9c5a7589a", - "sha256:3660bd2afb23e1ca685df0d3092208fe6c7b2cae8c0be199b3da6d1a4bc91dc5", - "sha256:42eb3030665ee7a5c03fd4db6b8db1983aa91bcdffbed0f4687751deb2a94a7c", - "sha256:4333b5c2801e44bf342207a7700378a1013f300116c9553ce1ffbc73047d2a02", - "sha256:4b5164fdad37847e90683d3748dca7c4604f47ecd21e2d651dafc80393d1d314", - "sha256:4c66a5f9ca9c5fcb2527ad969541521f7216db713a7bd63aee52c3f5efa5924a", - "sha256:5b7c87503843a036f898d44c47326a117d23b6269a9f1574adf83d7bb051b839", - "sha256:657348b35a4c2e7c2340bf0bc37597900037bd87e9db7e6282711aaa77256e16", - "sha256:681ef7a21e6990583533c3a3038b7176f5e51e5d345fe2d9109b54f6bffcabcd", - "sha256:6b1b235b890373f785507f8f6a644a4f191b7195939e7f6108dc0e5e4fab57fd", - "sha256:6e85ea159f2d2132d4fcb71abb7df9683314f6073bf8ee9f9bd576440245e59c", - "sha256:6ee396f63a1f540fb3aecb8cc698180d30573a661be47fb3fff45cbd2b5d4686", - "sha256:7110854662ccf8db84b90e4624301ef5311cafff7e5f2a63f2d7cc0fc1a75b60", - "sha256:755a837fb7053dbf511fba26343423bd80d3b75a5d7f57f6e407c2fe5ae46682", - "sha256:7628b2080538faa4a1243b0002678cae7111af68ae7b5aa6cd8526762cace868", - "sha256:78c5577f99d2edc9eed9ec39fae27b73d04d1b2462aff6f6b11207e0364fc40d", - "sha256:79ac819182795a2168ed11075c7362de368f360244fb7cea8274c222b2d55365", - "sha256:7bd8dbc1c63668124e5e48e601d32f1053cfd5a86004ae0e55dc9ba8b1e7de29", - "sha256:87d74c2526115daa9d805a66377997602185a837ff7ecceed9d27e625c383572", - "sha256:8ac1e47ee4cb2dbd714537e63c67086eec63f56b13208fe450ae5be4f3d65671", - "sha256:8e1251d6690f356a305192089017da83999cded1d7e2405660d14c1dff976af7", - "sha256:8f64ef5700ff8fded62b12d1ea55463031cc5a353b670ed7146126c6cbf28788", - "sha256:961828c668140796c4963edb14cd968666d5414b9b5829997a4f475fd917906e", - "sha256:9af40bb89e40932e04c0cc1fb516249d6b3ae68ceebd984fdc592a6673244e50", - "sha256:9b331fa451d725258c1ad0ae6816cf36d55294e5cb68338cf91550b9a448a48f", - "sha256:a747477838a90b9264f434b5399309f9badb32c80ff3e9c4f6d5b87fddcbaa09", - "sha256:ac596301c7723809ecb6ec4cb2564b2cadc06f8c07b6348a56fcbf1ae043d751", - "sha256:b189640d59afa8aeff59865fa9d314bca97987c378950f215297e15d64ae1124", - "sha256:b3ed0d3498b69159db0d5db1393c8bae4df51cf936b2ef5cda53d800acab0019", - "sha256:b5a55fd01f61df19e4f53fd67b63ca9bf47559632c3f7d4037faa06d3a6fed54", - "sha256:b5cbcbd6451a4af2048fc0b21c15981462f6a378cb039aa53612c6e39958064e", - "sha256:b949e86affe17c8828d82936c51d7aa9b686511f9ac99a4b1de596d7140c8083", - "sha256:bfe98ad05400e7ac7a1df791645db08c66adc92d7a6449a406111303a265b71a", - "sha256:c0fe018430e5e8e1d8b513bcbccdb0ea34b9fd81c32b3a49c41a109fade17cfb", - "sha256:c26b1a0425c038cc23cf5770a47d7a7382fe68d6d10fb2a52c2896ca94e72550", - "sha256:c7019b2522af6b835118177b6b53f7ed08da28061aa5d44e06286be09799e7a4", - "sha256:c97e4cbe722474d17c309ee49e09331ceffe345bb72e2b10c6c740788871b122", - "sha256:cafbfa8f3a27e592bdcc420497e0c9a957c9f812b6c6ebfb7f961409215ba82d", - "sha256:cea42c2f52e37877e6b877bce64d109a6b0213e32545ecc70d4492d2a4641b8f", - "sha256:d2f8666fde7cfd9cdbc6c223876b39697d387f0215d12ed25147e9efec2dff5a", - "sha256:d418d2fd8c0fffe2897bc3e15a2e2ec87abf29076f0c36898cc33fb7881c2cbe", - "sha256:d4334405f6c73c29ff94521f78ad53ebb76a9c1b8dafea75852f9f64c3679cf7", - "sha256:d6696c2a002e982e89975063939a2579623d6d6b24634b147848ec9f35dad7d6", - "sha256:d7e46f52272ceecc42c05ad869b068b2dbfb6eb5643bcccecd2327d3cded5a2e", - "sha256:db71c665fc7ddb9ac53d7b69dc588493c0b71635b28fc8ff64b31eb9db5b3461", - "sha256:ddb5226b11f4fce98c6e47c07819fbbfdda6d3fd529cd176ad8a1e0b98a70b05", - "sha256:df3097abf5fd09bfcd8f6fd02d052b25cc3e160b3ee71b6fbd831b2cd516c958", - "sha256:e086610118163400a1822af0ee857581c0e047aa50a9c3543d17fbe65183a339", - "sha256:e1700fba17dd63c9c7d5cb03cf838db23cf938dd5cdb1eecb6ba8b8da62c3e73", - "sha256:e261fa453ad50fe1d9287fa21d962cdbcd3d495cf1160dd0f893883040c455b6", - "sha256:e4e11f71673905d9e8735b8dd4ef8fa85a82e6003851fe46f9bdc51aebc2cd5d", - "sha256:ea8c4a1232c7bacf73366b0490dda7f67d25958aec1c2f099b6753c8bfe84427", - "sha256:ed823997c3300b541da0fcc9eee8fbe6740e07939ffa432824cfca287472d652", - "sha256:ee42ce4ef46ea334ce8ab63d5a57c7fd78238c9c7293b3caa6dfedf11bd28773", - "sha256:f1c84912d77b01651488bbe392df593b4c5852e213477e268ebbb7c799059d78", - "sha256:f81a570a20f9fce617d728f4e3bdc05bfbb68afa2e795ec0c52544a7923de517", - "sha256:f8a1cc37e2395002381510a6862c29634acd67edfe5774661a6c48d8617acae7", - "sha256:fffd98c1fd6b38df35e471549c2486d826af0fda6ca55c0bbbb956b291e7f2ae" - ], - "markers": "python_version >= '3.8'", - "version": "==0.8.8" - }, - "setuptools": { - "hashes": [ - "sha256:11e52c67415a381d10d6b462ced9cfb97066179f0e871399e006c4ab101fc85f", - "sha256:baf1fdb41c6da4cd2eae722e135500da913332ab3f2f5c7d33af9b492acb5235" - ], - "markers": "python_version >= '3.7'", - "version": "==68.0.0" - }, - "six": { - "hashes": [ - "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", - "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.16.0" - }, - "smmap": { - "hashes": [ - "sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94", - "sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936" - ], - "markers": "python_version >= '3.6'", - "version": "==5.0.0" - }, - "sortedcontainers": { - "hashes": [ - "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88", - "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0" - ], - "version": "==2.4.0" - }, - "soupsieve": { - "hashes": [ - "sha256:1c1bfee6819544a3447586c889157365a27e10d88cde3ad3da0cf0ddf646feb8", - "sha256:89d12b2d5dfcd2c9e8c22326da9d9aa9cb3dfab0a83a024f05704076ee8d35ea" - ], - "markers": "python_version >= '3.7'", - "version": "==2.4.1" - }, - "tinycss2": { - "hashes": [ - "sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847", - "sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627" - ], - "markers": "python_version >= '3.7'", - "version": "==1.2.1" - }, - "toml": { - "hashes": [ - "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", - "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" - ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.10.2" - }, - "tomli": { - "hashes": [ - "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", - "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f" - ], - "markers": "python_full_version < '3.11.0a7'", - "version": "==2.0.1" - }, - "tornado": { - "hashes": [ - "sha256:05615096845cf50a895026f749195bf0b10b8909f9be672f50b0fe69cba368e4", - "sha256:0c325e66c8123c606eea33084976c832aa4e766b7dff8aedd7587ea44a604cdf", - "sha256:29e71c847a35f6e10ca3b5c2990a52ce38b233019d8e858b755ea6ce4dcdd19d", - "sha256:4b927c4f19b71e627b13f3db2324e4ae660527143f9e1f2e2fb404f3a187e2ba", - "sha256:5b17b1cf5f8354efa3d37c6e28fdfd9c1c1e5122f2cb56dac121ac61baa47cbe", - "sha256:6a0848f1aea0d196a7c4f6772197cbe2abc4266f836b0aac76947872cd29b411", - "sha256:7efcbcc30b7c654eb6a8c9c9da787a851c18f8ccd4a5a3a95b05c7accfa068d2", - "sha256:834ae7540ad3a83199a8da8f9f2d383e3c3d5130a328889e4cc991acc81e87a0", - "sha256:b46a6ab20f5c7c1cb949c72c1994a4585d2eaa0be4853f50a03b5031e964fc7c", - "sha256:c2de14066c4a38b4ecbbcd55c5cc4b5340eb04f1c5e81da7451ef555859c833f", - "sha256:c367ab6c0393d71171123ca5515c61ff62fe09024fa6bf299cd1339dc9456829" - ], - "markers": "python_version >= '3.8'", - "version": "==6.3.2" - }, - "tox": { - "hashes": [ - "sha256:c138327815f53bc6da4fe56baec5f25f00622ae69ef3fe4e1e385720e22486f9", - "sha256:c38e15f4733683a9cc0129fba078633e07eb0961f550a010ada879e95fb32632" - ], - "index": "pypi", - "version": "==3.25.1" - }, - "traitlets": { - "hashes": [ - "sha256:9e6ec080259b9a5940c797d58b613b5e31441c2257b87c2e795c5228ae80d2d8", - "sha256:f6cde21a9c68cf756af02035f72d5a723bf607e862e7be33ece505abf4a3bad9" - ], - "markers": "python_version >= '3.7'", - "version": "==5.9.0" - }, - "typing-extensions": { - "hashes": [ - "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36", - "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2" - ], - "markers": "python_version < '3.10'", - "version": "==4.7.1" - }, - "urllib3": { - "hashes": [ - "sha256:48e7fafa40319d358848e1bc6809b208340fafe2096f1725d05d67443d0483d1", - "sha256:bee28b5e56addb8226c96f7f13ac28cb4c301dd5ea8a6ca179c0b9835e032825" - ], - "markers": "python_version >= '3.7'", - "version": "==2.0.3" - }, - "virtualenv": { - "hashes": [ - "sha256:34da10f14fea9be20e0fd7f04aba9732f84e593dac291b757ce42e3368a39419", - "sha256:8ff19a38c1021c742148edc4f81cb43d7f8c6816d2ede2ab72af5b84c749ade1" - ], - "markers": "python_version >= '3.7'", - "version": "==20.23.1" - }, - "watchdog": { - "hashes": [ - "sha256:0e06ab8858a76e1219e68c7573dfeba9dd1c0219476c5a44d5333b01d7e1743a", - "sha256:13bbbb462ee42ec3c5723e1205be8ced776f05b100e4737518c67c8325cf6100", - "sha256:233b5817932685d39a7896b1090353fc8efc1ef99c9c054e46c8002561252fb8", - "sha256:25f70b4aa53bd743729c7475d7ec41093a580528b100e9a8c5b5efe8899592fc", - "sha256:2b57a1e730af3156d13b7fdddfc23dea6487fceca29fc75c5a868beed29177ae", - "sha256:336adfc6f5cc4e037d52db31194f7581ff744b67382eb6021c868322e32eef41", - "sha256:3aa7f6a12e831ddfe78cdd4f8996af9cf334fd6346531b16cec61c3b3c0d8da0", - "sha256:3ed7c71a9dccfe838c2f0b6314ed0d9b22e77d268c67e015450a29036a81f60f", - "sha256:4c9956d27be0bb08fc5f30d9d0179a855436e655f046d288e2bcc11adfae893c", - "sha256:4d98a320595da7a7c5a18fc48cb633c2e73cda78f93cac2ef42d42bf609a33f9", - "sha256:4f94069eb16657d2c6faada4624c39464f65c05606af50bb7902e036e3219be3", - "sha256:5113334cf8cf0ac8cd45e1f8309a603291b614191c9add34d33075727a967709", - "sha256:51f90f73b4697bac9c9a78394c3acbbd331ccd3655c11be1a15ae6fe289a8c83", - "sha256:5d9f3a10e02d7371cd929b5d8f11e87d4bad890212ed3901f9b4d68767bee759", - "sha256:7ade88d0d778b1b222adebcc0927428f883db07017618a5e684fd03b83342bd9", - "sha256:7c5f84b5194c24dd573fa6472685b2a27cc5a17fe5f7b6fd40345378ca6812e3", - "sha256:7e447d172af52ad204d19982739aa2346245cc5ba6f579d16dac4bfec226d2e7", - "sha256:8ae9cda41fa114e28faf86cb137d751a17ffd0316d1c34ccf2235e8a84365c7f", - "sha256:8f3ceecd20d71067c7fd4c9e832d4e22584318983cabc013dbf3f70ea95de346", - "sha256:9fac43a7466eb73e64a9940ac9ed6369baa39b3bf221ae23493a9ec4d0022674", - "sha256:a70a8dcde91be523c35b2bf96196edc5730edb347e374c7de7cd20c43ed95397", - "sha256:adfdeab2da79ea2f76f87eb42a3ab1966a5313e5a69a0213a3cc06ef692b0e96", - "sha256:ba07e92756c97e3aca0912b5cbc4e5ad802f4557212788e72a72a47ff376950d", - "sha256:c07253088265c363d1ddf4b3cdb808d59a0468ecd017770ed716991620b8f77a", - "sha256:c9d8c8ec7efb887333cf71e328e39cffbf771d8f8f95d308ea4125bf5f90ba64", - "sha256:d00e6be486affb5781468457b21a6cbe848c33ef43f9ea4a73b4882e5f188a44", - "sha256:d429c2430c93b7903914e4db9a966c7f2b068dd2ebdd2fa9b9ce094c7d459f33" - ], - "markers": "python_version >= '3.7'", - "version": "==3.0.0" - }, - "webencodings": { - "hashes": [ - "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", - "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923" - ], - "version": "==0.5.1" - }, - "zipp": { - "hashes": [ - "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b", - "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556" - ], - "markers": "python_version >= '3.7'", - "version": "==3.15.0" - } - } -} diff --git a/README.md b/README.md index c77dc2d..a9f385c 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,9 @@ NL2LTL is an interface to translate natural language (NL) utterances to linear temporal logic (LTL) formulas. +> 🏆 NL2LTL won the People's Choice Best System Demonstration Award Runner-Up in the ICAPS 2023 System Demonstration +> Track in Prague. Read more about it [here](https://icaps23.icaps-conference.org/demos/papers/6374_paper.pdf). + ## Installation - from PyPI: ```bash @@ -27,7 +30,7 @@ pip install git+https://github.com/IBM/nl2ltl.git ```bash git clone https://github.com/IBM/nl2ltl.git cd nl2ltl -pip install . +pip install -e . ``` ## Quickstart @@ -57,12 +60,12 @@ For instance, Rasa requires a `.tar.gz` format trained model in the `models/` folder to run. To train the model use the available NL2LTL `train(...)` API. ## NLU Engines -- [x] [Rasa](https://rasa.com/) intents/entities classifier - [x] [GPT-3.x](https://openai.com/api/) large language models - [x] [GPT-4](https://openai.com/api/) large language model +- [x] [Rasa](https://rasa.com/) intents/entities classifier (to use Rasa, please install it with `pip install -e ".[rasa]"`) - [ ] [Watson Assistant](https://www.ibm.com/products/watson-assistant) intents/entities classifier -- Planned -To use GPT models you need to have an API KEY set as environment variable. To set it: +To use GPT models you need to have the OPEN_API_KEY set as environment variable. To set it: ```bash export OPENAI_API_KEY=your_api_key ``` @@ -113,17 +116,15 @@ ltl_formulas = translate(utterance, engine=my_engine, filter=my_filter) ## Development Contributions are welcome! Here's how to set up the development environment: -- install [Pipenv](https://pipenv-fork.readthedocs.io/en/latest/) +- set up your preferred virtualenv environment - clone the repo: `git clone https://github.com/IBM/nl2ltl.git && cd nl2ltl` -- install dev dependencies: `pipenv shell --python 3.8 && pipenv install --dev` +- install dev dependencies: `pip install -e ".[dev]"` ## Tests To run tests: `tox` -To run the code tests only: `tox -e py3.8` - -To run the code style checks only: `tox -e precommit` +To run the code tests only: `tox -e py310` ## Docs @@ -135,24 +136,23 @@ and then go to [http://localhost:8000](http://localhost:8000) ## Citing ``` -@inproceedings{aaai2023fc, +@inproceedings{icaps2023fc, author = {Francesco Fuggitti and Tathagata Chakraborti}, title = {{NL2LTL} -- A Python Package for Converting Natural Language ({NL}) Instructions to Linear Temporal Logic ({LTL}) Formulas}, - booktitle = {{AAAI}}, + booktitle = {{ICAPS}}, year = {2023}, - note = {System Demonstration.}, + note = {Best System Demonstration Award Runner-Up.}, url_code = {https://github.com/IBM/nl2ltl}, } ``` and ``` -@inproceedings{icaps2023fc, +@inproceedings{aaai2023fc, author = {Francesco Fuggitti and Tathagata Chakraborti}, title = {{NL2LTL} -- A Python Package for Converting Natural Language ({NL}) Instructions to Linear Temporal Logic ({LTL}) Formulas}, - booktitle = {{ICAPS}}, + booktitle = {{AAAI}}, year = {2023}, note = {System Demonstration.}, url_code = {https://github.com/IBM/nl2ltl}, } ``` - diff --git a/mkdocs.yml b/mkdocs.yml index 48db829..06e1856 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,6 +1,6 @@ site_name: NL2LTL repo_name: 'NL2LTL' -repo_url: https://github.ibm.com/Francesco-Fuggitti/nl2ltl +repo_url: https://github.com/IBM/nl2ltl nav: - Home: index.md diff --git a/nl2ltl/__init__.py b/nl2ltl/__init__.py index eac6686..8a0f830 100644 --- a/nl2ltl/__init__.py +++ b/nl2ltl/__init__.py @@ -1,7 +1,3 @@ -# -*- coding: utf-8 -*- - """From Natural Language to Linear-time Temporal Logic on Finite Traces.""" -__version__ = "0.0.4" - from .core import translate # noqa: F401 diff --git a/nl2ltl/core.py b/nl2ltl/core.py index 07053fe..d7763eb 100644 --- a/nl2ltl/core.py +++ b/nl2ltl/core.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """NL2LTLf core module.""" from typing import Dict @@ -17,11 +15,8 @@ def _call_translation_method( return method(utterance, filtering) -def translate( - utterance: str, engine: Engine, filtering: Filter = None -) -> Dict[Formula, float]: - """ - From NL to LTLf. +def translate(utterance: str, engine: Engine, filtering: Filter = None) -> Dict[Formula, float]: + """From NL to LTLf. :param utterance: the natural language utterance to translate. :param engine: the engine to use. diff --git a/nl2ltl/declare/__init__.py b/nl2ltl/declare/__init__.py index 03e9771..8da4533 100644 --- a/nl2ltl/declare/__init__.py +++ b/nl2ltl/declare/__init__.py @@ -1,3 +1 @@ -# -*- coding: utf-8 -*- - """Implementation of DECLARE templates.""" diff --git a/nl2ltl/declare/base.py b/nl2ltl/declare/base.py index 511a7c7..bc317be 100644 --- a/nl2ltl/declare/base.py +++ b/nl2ltl/declare/base.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """Base classes for declare templates.""" from abc import abstractmethod diff --git a/nl2ltl/declare/declare.py b/nl2ltl/declare/declare.py index 4aacf71..6191eb8 100644 --- a/nl2ltl/declare/declare.py +++ b/nl2ltl/declare/declare.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """Classes for declare templates.""" from pylogics.syntax.base import And, Formula, Implies, Not, Or, _BinaryOp, _UnaryOp from pylogics.syntax.ltl import Always, Eventually, Next, Until @@ -120,16 +118,11 @@ def to_ltlf(self) -> Formula: def to_english(self) -> str: """English meaning.""" - return ( - f"Whenever {self.operands[0]} happens, {self.operands[1]} has to happen " - f"eventually afterward." - ) + return f"Whenever {self.operands[0]} happens, {self.operands[1]} has to happen " f"eventually afterward." def to_ppltl(self) -> Formula: """Translate Response to PPLTL.""" - return Not( - Since(Not(self.operands[1]), And(self.operands[0], Not(self.operands[1]))) - ) + return Not(Since(Not(self.operands[1]), And(self.operands[0], Not(self.operands[1])))) class Precedence(Template, _BinaryOp): @@ -151,10 +144,7 @@ def to_ltlf(self) -> Formula: def to_english(self) -> str: """English meaning.""" - return ( - f"Whenever {self.operands[1]} happens, {self.operands[0]} has to have happened " - f"before it." - ) + return f"Whenever {self.operands[1]} happens, {self.operands[0]} has to have happened " f"before it." def to_ppltl(self) -> Formula: """Translate Precedence to PPLTL.""" diff --git a/nl2ltl/declare/misc.py b/nl2ltl/declare/misc.py index e17bda4..6ccc398 100644 --- a/nl2ltl/declare/misc.py +++ b/nl2ltl/declare/misc.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """Helper functions.""" from typing import Sequence, Type @@ -7,9 +5,7 @@ from pylogics.syntax.ltl import Atomic -def _enforce( - condition: bool, message: str = "", exception_cls: Type[Exception] = AssertionError -): +def _enforce(condition: bool, message: str = "", exception_cls: Type[Exception] = AssertionError): """User-defined assert.""" if not condition: raise exception_cls(message) diff --git a/nl2ltl/engines/__init__.py b/nl2ltl/engines/__init__.py index 527a8f4..8c3de16 100644 --- a/nl2ltl/engines/__init__.py +++ b/nl2ltl/engines/__init__.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """Engines for nl2ltl.""" from nl2ltl.engines.base import Engine # noqa: F401 diff --git a/nl2ltl/engines/base.py b/nl2ltl/engines/base.py index 9b63def..8991cbc 100644 --- a/nl2ltl/engines/base.py +++ b/nl2ltl/engines/base.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """Abstract definition of a engine.""" from abc import ABC, ABCMeta from typing import Dict @@ -13,8 +11,6 @@ class _MetaEngine(ABCMeta): """Metaclass for rasa.""" - # TODO: Do some Engine validation here? e.g., we may want to check whether certain parameters are present - def __new__(mcs, *args, **kwargs): """Instantiate a new class.""" return super().__new__(mcs, *args, **kwargs) @@ -26,15 +22,10 @@ class Engine(ABC, metaclass=_MetaEngine): @classmethod def __not_supported_error(cls, operation: str) -> Exception: """Raise a not supported error.""" - return NotImplementedEngineFunction( - f"operation '{operation}' is not supported by the '{cls.__name__}' engine" - ) + return NotImplementedEngineFunction(f"operation '{operation}' is not supported by the '{cls.__name__}' engine") - def translate( - self, utterance: str, filtering: Filter = None - ) -> Dict[Formula, float]: - """ - Transform a Natural Language utterance into an LTLf formula. + def translate(self, utterance: str, filtering: Filter = None) -> Dict[Formula, float]: + """Transform a Natural Language utterance into an LTLf formula. :param utterance: a Natural Language utterance :param filtering: a custom filtering algorithm diff --git a/nl2ltl/engines/gpt/__init__.py b/nl2ltl/engines/gpt/__init__.py index 47329bf..38cb579 100644 --- a/nl2ltl/engines/gpt/__init__.py +++ b/nl2ltl/engines/gpt/__init__.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """Implementation of the GPT engine.""" import inspect diff --git a/nl2ltl/engines/gpt/core.py b/nl2ltl/engines/gpt/core.py index 2399d70..4cce8d0 100644 --- a/nl2ltl/engines/gpt/core.py +++ b/nl2ltl/engines/gpt/core.py @@ -1,7 +1,4 @@ -# -*- coding: utf-8 -*- - -""" -Implementation of the GPT engine. +"""Implementation of the GPT engine. Website: @@ -31,9 +28,8 @@ class Models(Enum): """The set of available GPT language models.""" - DAVINCI2 = "text-davinci-002" - DAVINCI3 = "text-davinci-003" - GPT35 = "gpt-3.5-turbo" + GPT35_INSTRUCT = "gpt-3.5-turbo-instruct" + GPT35_TURBO = "gpt-3.5-turbo" GPT4 = "gpt-4" @@ -55,7 +51,7 @@ class GPTEngine(Engine): def __init__( self, - model: str = Models.GPT4.value, + model: str = Models.GPT35_TURBO.value, prompt: Path = PROMPT_PATH, operation_mode: str = OperationModes.CHAT.value, temperature: float = 0.5, @@ -69,7 +65,7 @@ def __init__( self._check_consistency() def _load_prompt(self, prompt): - return json.load(open(prompt, "r"))["prompt"] + return json.load(open(prompt))["prompt"] def _check_consistency(self) -> None: """Run consistency checks.""" @@ -79,30 +75,26 @@ def _check_consistency(self) -> None: def __check_openai_version(self): """Check that the GPT tool is at the right version.""" - is_right_version = openai.__version__ == "0.27.8" + is_right_version = openai.__version__ == "1.12.0" if not is_right_version: raise Exception( - "OpenAI needs to be at version 0.27.8. " + "OpenAI needs to be at version 1.12.0. " "Please install it manually using:" "\n" - "pip install openai==0.27.8" + "pip install openai==1.12.0" ) def __check_model_support(self): """Check if the model is a supported model.""" is_supported = self.model in SUPPORTED_MODELS if not is_supported: - raise Exception( - f"The LLM model {self.model} is not currently supported by nl2ltl." - ) + raise Exception(f"The LLM model {self.model} is not currently supported by nl2ltl.") def __check_operation_mode(self): """Check if the operation mode is a supported mode.""" is_supported = self.operation_mode in SUPPORTED_MODES if not is_supported: - raise Exception( - f"The operation mode {self.operation_mode} is not currently supported by nl2ltl." - ) + raise Exception(f"The operation mode {self.operation_mode} is not currently supported by nl2ltl.") @property def model(self) -> str: @@ -124,9 +116,7 @@ def temperature(self) -> float: """Get the GPT temperature.""" return self._temperature - def translate( - self, utterance: str, filtering: Filter = None - ) -> Dict[Formula, float]: + def translate(self, utterance: str, filtering: Filter = None) -> Dict[Formula, float]: """From NL to best matching LTL formulas with confidence.""" return _process_utterance( utterance, @@ -146,8 +136,7 @@ def _process_utterance( temperature: float, filtering: Filter, ) -> Dict[Formula, float]: - """ - Process NL utterance. + """Process NL utterance. :param utterance: the natural language utterance :param model: the GPT model @@ -160,7 +149,7 @@ def _process_utterance( query = f"NL: {utterance}\n" messages = [{"role": "user", "content": prompt + query}] if operation_mode == OperationModes.CHAT.value: - prediction = openai.ChatCompletion.create( + prediction = openai.chat.completions.create( model=model, messages=messages, temperature=temperature, @@ -171,7 +160,7 @@ def _process_utterance( stop=["\n\n"], ) else: - prediction = openai.Completion.create( + prediction = openai.completions.create( model=model, prompt=messages[0]["content"], temperature=temperature, diff --git a/nl2ltl/engines/gpt/output.py b/nl2ltl/engines/gpt/output.py index a2be882..5377933 100644 --- a/nl2ltl/engines/gpt/output.py +++ b/nl2ltl/engines/gpt/output.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """Parse GPT output to produce Dict[Formula, Float] result.""" import re from dataclasses import dataclass @@ -63,26 +61,19 @@ def entities(self) -> Tuple[str]: return tuple( cast( Match, - re.search( - "SYMBOLS: (.*)", self.output["choices"][0]["message"]["content"] - ), + re.search("SYMBOLS: (.*)", self.output["choices"][0]["message"]["content"]), ) .group(1) .split(", ") ) else: return tuple( - cast( - Match, re.search("SYMBOLS: (.*)", self.output["choices"][0]["text"]) - ) - .group(1) - .split(", ") + cast(Match, re.search("SYMBOLS: (.*)", self.output["choices"][0]["text"])).group(1).split(", ") ) def parse_gpt_output(gpt_output: dict, operation_mode: str) -> GPTOutput: - """ - Parse the GPT output. + """Parse the GPT output. :param gpt_output: the json description of the GPT prediction. :param operation_mode: the operation mode of the GPT engine. @@ -95,11 +86,8 @@ def parse_gpt_output(gpt_output: dict, operation_mode: str) -> GPTOutput: return gpt_result -def parse_gpt_result( - output: GPTOutput, filtering: Filter = None -) -> Dict[Formula, float]: - """ - Build a dict of formulas, given the GPTOutput object. +def parse_gpt_result(output: GPTOutput, filtering: Filter = None) -> Dict[Formula, float]: + """Build a dict of formulas, given the GPTOutput object. :param output: a GPTOutput instance. :param filtering: a custom filtering function diff --git a/nl2ltl/engines/grounding.py b/nl2ltl/engines/grounding.py index 749c331..776e380 100644 --- a/nl2ltl/engines/grounding.py +++ b/nl2ltl/engines/grounding.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """Grounding visitor.""" import logging from typing import Dict, Set @@ -25,9 +23,7 @@ def ground_existence(connectors: Dict[str, float]) -> Set[Template]: if len(list(connectors)) > 0: return {Existence(Atomic(decapitalize(list(connectors)[0])))} else: - logging.warning( - "No valid matching, cannot instantiate Existence with < 1 connectors." - ) + logging.warning("No valid matching, cannot instantiate Existence with < 1 connectors.") return set() @@ -36,9 +32,7 @@ def ground_existencetwo(connectors: Dict[str, float]) -> Set[Template]: if len(list(connectors)) > 0: return {ExistenceTwo(Atomic(decapitalize(list(connectors)[0])))} else: - logging.warning( - "No valid matching, cannot instantiate ExistenceTwo with < 1 connectors." - ) + logging.warning("No valid matching, cannot instantiate ExistenceTwo with < 1 connectors.") return set() @@ -47,9 +41,7 @@ def ground_absence(connectors: Dict[str, float]) -> Set[Template]: if len(list(connectors)) > 0: return {Absence(Atomic(decapitalize(list(connectors)[0])))} else: - logging.warning( - "No valid matching, cannot instantiate Absence with < 1 connectors." - ) + logging.warning("No valid matching, cannot instantiate Absence with < 1 connectors.") return set() @@ -63,9 +55,7 @@ def ground_respondedexistence(connectors: Dict[str, float]) -> Set[Template]: ) } else: - logging.warning( - "No valid matching, cannot instantiate RespondedExistence with < 2 connectors." - ) + logging.warning("No valid matching, cannot instantiate RespondedExistence with < 2 connectors.") return set() @@ -79,9 +69,7 @@ def ground_response(connectors: Dict[str, float]) -> Set[Template]: ) } else: - logging.warning( - "No valid matching, cannot instantiate Response with < 2 connectors." - ) + logging.warning("No valid matching, cannot instantiate Response with < 2 connectors.") return set() @@ -95,9 +83,7 @@ def ground_precedence(connectors: Dict[str, float]) -> Set[Template]: ) } else: - logging.warning( - "No valid matching, cannot instantiate Precedence with < 2 connectors." - ) + logging.warning("No valid matching, cannot instantiate Precedence with < 2 connectors.") return set() @@ -111,9 +97,7 @@ def ground_chainresponse(connectors: Dict[str, float]) -> Set[Template]: ) } else: - logging.warning( - "No valid matching, cannot instantiate ChainResponse with < 2 connectors." - ) + logging.warning("No valid matching, cannot instantiate ChainResponse with < 2 connectors.") return set() @@ -127,7 +111,5 @@ def ground_notcoexistence(connectors: Dict[str, float]) -> Set[Template]: ) } else: - logging.warning( - "No valid matching, cannot instantiate NotCoExistence with < 2 connectors." - ) + logging.warning("No valid matching, cannot instantiate NotCoExistence with < 2 connectors.") return set() diff --git a/nl2ltl/engines/rasa/__init__.py b/nl2ltl/engines/rasa/__init__.py index 900d17a..1c1b16c 100644 --- a/nl2ltl/engines/rasa/__init__.py +++ b/nl2ltl/engines/rasa/__init__.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """Implementation of the RASA engine.""" import inspect diff --git a/nl2ltl/engines/rasa/core.py b/nl2ltl/engines/rasa/core.py index b6a83f5..33c7ac0 100644 --- a/nl2ltl/engines/rasa/core.py +++ b/nl2ltl/engines/rasa/core.py @@ -1,7 +1,4 @@ -# -*- coding: utf-8 -*- - -""" -Implementation of the RASA engine. +"""Implementation of the RASA engine. Repository: @@ -13,9 +10,15 @@ from pathlib import Path from typing import Dict -import rasa from pylogics.syntax.base import Formula -from rasa.core.agent import Agent + +from nl2ltl.helpers import requires_optional + +try: + import rasa + from rasa.core.agent import Agent +except ImportError: + rasa = Agent = None from nl2ltl.engines.base import Engine from nl2ltl.engines.rasa import ENGINE_ROOT @@ -31,6 +34,7 @@ MODEL_OUTPUT_PATH = engine_root / "models" +@requires_optional class RasaEngine(Engine): """The RASA engine.""" @@ -65,13 +69,13 @@ def __check_rasa_available(self): def __check_rasa_version(self): """Check that the Rasa tool is at the right version.""" - is_right_version = rasa.__version__ == "3.5.11" + is_right_version = rasa.__version__ == "3.6.16" if not is_right_version: raise Exception( - "Rasa needs to be at version 3.5.11. " + "Rasa needs to be at version 3.6.16. " "Please install it manually using:" "\n" - "pip install rasa==3.5.11" + "pip install rasa==3.6.16" ) @staticmethod @@ -90,18 +94,13 @@ def train( ) return Path(result.model) - def translate( - self, utterance: str, filtering: Filter = None - ) -> Dict[Formula, float]: + def translate(self, utterance: str, filtering: Filter = None) -> Dict[Formula, float]: """From NL to best matching LTL formulas with confidence.""" return _process_utterance(utterance, self.agent, filtering) -def _process_utterance( - utterance: str, rasa_agent: Agent, filtering: Filter -) -> Dict[Formula, float]: - """ - Process NL utterance. +def _process_utterance(utterance: str, rasa_agent: Agent, filtering: Filter) -> Dict[Formula, float]: + """Process NL utterance. :param utterance: the natural language utterance :return: a dict with matching formulas and confidence diff --git a/nl2ltl/engines/rasa/helpers.py b/nl2ltl/engines/rasa/helpers.py index 96c1df5..27669a5 100644 --- a/nl2ltl/engines/rasa/helpers.py +++ b/nl2ltl/engines/rasa/helpers.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """This module contains utilities to call the Lydia tool from Python.""" import glob import os diff --git a/nl2ltl/engines/rasa/output.py b/nl2ltl/engines/rasa/output.py index 1395082..d4135c6 100644 --- a/nl2ltl/engines/rasa/output.py +++ b/nl2ltl/engines/rasa/output.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """Parse Rasa output to produce Dict[Formula, Float] result.""" from dataclasses import dataclass from typing import Any, Dict @@ -59,8 +57,7 @@ def intent_ranking(self) -> Dict[str, float]: def parse_rasa_output(rasa_output: dict) -> RasaOutput: - """ - Parse the Rasa output. + """Parse the Rasa output. :param rasa_output: the json description of the RASA prediction. :return: a RasaOutput instance. @@ -74,11 +71,8 @@ def parse_rasa_output(rasa_output: dict) -> RasaOutput: return rasa_result -def parse_rasa_result( - output: RasaOutput, filtering: Filter = None -) -> Dict[Formula, float]: - """ - Build a dict of formulas, given the RasaOutput object. +def parse_rasa_result(output: RasaOutput, filtering: Filter = None) -> Dict[Formula, float]: + """Build a dict of formulas, given the RasaOutput object. :param output: a RasaOutput instance. :param filtering: a custom filtering function diff --git a/nl2ltl/engines/utils.py b/nl2ltl/engines/utils.py index 33c45ef..e2fb4bb 100644 --- a/nl2ltl/engines/utils.py +++ b/nl2ltl/engines/utils.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """Engines utils.""" import difflib from typing import Callable, Dict, Set, Union @@ -14,14 +12,10 @@ def _get_formulas(name: str, args: Dict[str, float]) -> Set[Formula]: import nl2ltl.declare.declare import nl2ltl.engines.grounding - class_name_match = difflib.get_close_matches( - name, [x.value for x in TemplateEnum], n=1 - ) + class_name_match = difflib.get_close_matches(name, [x.value for x in TemplateEnum], n=1) grounding_map: Dict[str, Callable] = {} for c_name in TemplateEnum: - grounding_map[c_name.value] = getattr( - nl2ltl.engines.grounding, f"ground_{c_name.value.lower()}" - ) + grounding_map[c_name.value] = getattr(nl2ltl.engines.grounding, f"ground_{c_name.value.lower()}") grounding_func: Callable = grounding_map[str(class_name_match[0])] grounded_formulas: Set[Formula] = grounding_func(args) @@ -32,14 +26,13 @@ def pretty(result: Dict[Formula, float]): """Pretty print Rasa output.""" print("=" * 150) for k, v in result.items(): - print(f"Declare Template: {str(k)}", end="\n") + print(f"Declare Template: {k!s}", end="\n") print(f"English meaning: {k.to_english()}", end="\n") - print(f"Confidence: {str(v)}", end="\n\n") + print(f"Confidence: {v!s}", end="\n\n") def check_(condition: bool, message: str = "") -> None: - """ - User-defined assert. + """User-defined assert. This function is useful to avoid the use of the built-in assert statement, which is removed when the code is compiled in optimized mode. For more information, see diff --git a/nl2ltl/exceptions.py b/nl2ltl/exceptions.py index 579f876..9665828 100644 --- a/nl2ltl/exceptions.py +++ b/nl2ltl/exceptions.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """This module implements the library exceptions.""" diff --git a/nl2ltl/filters/__init__.py b/nl2ltl/filters/__init__.py index cfa2710..3906065 100644 --- a/nl2ltl/filters/__init__.py +++ b/nl2ltl/filters/__init__.py @@ -1,3 +1 @@ -# -*- coding: utf-8 -*- - """Implementation of Filters.""" diff --git a/nl2ltl/filters/base.py b/nl2ltl/filters/base.py index c25c31a..078c26b 100644 --- a/nl2ltl/filters/base.py +++ b/nl2ltl/filters/base.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """Base classes for filters.""" from abc import ABC, abstractmethod @@ -14,8 +12,6 @@ class Filter(ABC): NAME: str @abstractmethod - def enforce( - self, output: Dict[Formula, float], entities: Dict[str, float], **kwargs - ) -> Dict[Formula, float]: + def enforce(self, output: Dict[Formula, float], entities: Dict[str, float], **kwargs) -> Dict[Formula, float]: """Enforce filters on output.""" raise NotImplementedError("Filters must implement this method.") diff --git a/nl2ltl/filters/simple_filters.py b/nl2ltl/filters/simple_filters.py index c647321..506b40d 100644 --- a/nl2ltl/filters/simple_filters.py +++ b/nl2ltl/filters/simple_filters.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """Greedy filter class.""" from typing import Dict @@ -16,11 +14,8 @@ class BasicFilter(Filter): NAME = "basic" @staticmethod - def enforce( - output: Dict[Formula, float], entities: Dict[str, float], **kwargs - ) -> Dict[Formula, float]: - """ - Enforce conflicts and subsumptions to output formulas. + def enforce(output: Dict[Formula, float], entities: Dict[str, float], **kwargs) -> Dict[Formula, float]: + """Enforce conflicts and subsumptions to output formulas. Algorithm: - scan the output @@ -35,11 +30,8 @@ class GreedyFilter(Filter): NAME = "greedy" @staticmethod - def enforce( - output: Dict[Formula, float], entities: Dict[str, float], **kwargs - ) -> Dict[Formula, float]: - """ - Enforce conflicts and subsumptions to output formulas. + def enforce(output: Dict[Formula, float], entities: Dict[str, float], **kwargs) -> Dict[Formula, float]: + """Enforce conflicts and subsumptions to output formulas. Algorithm: - empty set of formulas diff --git a/nl2ltl/filters/utils/__init__.py b/nl2ltl/filters/utils/__init__.py index 245da47..d132082 100644 --- a/nl2ltl/filters/utils/__init__.py +++ b/nl2ltl/filters/utils/__init__.py @@ -1,3 +1 @@ -# -*- coding: utf-8 -*- - """Utils modules.""" diff --git a/nl2ltl/filters/utils/conflicts.py b/nl2ltl/filters/utils/conflicts.py index 88740d9..7b0e750 100644 --- a/nl2ltl/filters/utils/conflicts.py +++ b/nl2ltl/filters/utils/conflicts.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """Conflicts visitor.""" from functools import singledispatch from typing import Set diff --git a/nl2ltl/filters/utils/subsumptions.py b/nl2ltl/filters/utils/subsumptions.py index aeefa83..e27b6f1 100644 --- a/nl2ltl/filters/utils/subsumptions.py +++ b/nl2ltl/filters/utils/subsumptions.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """Subsumptions visitor.""" from functools import singledispatch from typing import Set @@ -22,9 +20,7 @@ @singledispatch def subsumptions(formula: Formula) -> Set[Template]: """Compute subsumptions for a Formula.""" - raise NotImplementedError( - "subsumption handler not implemented for formula %s" % type(formula) - ) + raise NotImplementedError("subsumption handler not implemented for formula %s" % type(formula)) @subsumptions.register diff --git a/nl2ltl/helpers.py b/nl2ltl/helpers.py new file mode 100644 index 0000000..074f42d --- /dev/null +++ b/nl2ltl/helpers.py @@ -0,0 +1,13 @@ +"""This module implements the library exceptions.""" +import functools +import sys + + +def requires_optional(cls): + @functools.wraps(cls) + def wrapper_decor(*args, **kwargs): + if "rasa" not in sys.modules: + raise ModuleNotFoundError(f"Rasa is required to instantiate {cls.__name__}") + return cls(*args, **kwargs) + + return wrapper_decor diff --git a/pyproject.toml b/pyproject.toml index 4043ad7..05f2528 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,116 @@ +[project] +name = "nl2ltl" +version = "0.0.5" +license = {file = "LICENSE"} +authors = [ + { name = "Francesco Fuggitti", email = "francesco.fuggitti@gmail.com" }, + { name = "Tathagata Chakraborti", email = "tchakra2@ibm.com" }, +] +description = "Natural Language (NL) to Linear Temporal Logic (LTL)" +readme = "README.md" +requires-python = ">=3.8,<3.11" + +keywords = [ + "natural language processing", + "linear temporal logics", + "generative ai", + "large language models", + "process automation", + "conversational agents", +] + +classifiers = [ + "Development Status :: 2 - Pre-Alpha", + "Intended Audience :: Developers", + "Intended Audience :: Science/Research", + "Natural Language :: English", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", + "Programming Language :: Python :: 3.10", + "Topic :: Scientific/Engineering :: Artificial Intelligence", + "Topic :: Scientific/Engineering :: Human Machine Interfaces", + "Topic :: Scientific/Engineering :: Information Analysis", +] + +dependencies = [ + "pylogics", + "openai" +] + +[project.optional-dependencies] +rasa = ["rasa==3.6.16"] +dev = [ + "codecov", + "mkdocs", + "markdown-include", + "pre-commit", + "pytest", + "pytest-cov", + "ruff", + "tox==3.27.1" +] + +[project.urls] +Repository = "https://github.com/IBM/nl2ltl" +Issues = "https://github.com/IBM/nl2ltl/issues" + [build-system] -requires = [ - "setuptools", - "wheel" -] \ No newline at end of file +requires = ["setuptools"] +build-backend = "setuptools.build_meta" + +[tool.setuptools] +include-package-data = true + +[tool.setuptools.packages.find] +include = ["nl2ltl*"] + +[tool.ruff] +exclude = [ + ".bzr", + ".direnv", + ".eggs", + ".git", + ".git-rewrite", + ".hg", + ".ipynb_checkpoints", + ".mypy_cache", + ".nox", + ".pants.d", + ".pyenv", + ".pytest_cache", + ".pytype", + ".ruff_cache", + ".svn", + ".tox", + ".venv", + ".vscode", + "__pypackages__", + "_build", + "buck-out", + "build", + "dist", + "node_modules", + "site-packages", + "venv", +] +line-length = 120 +indent-width = 4 +target-version = "py38" +include = ["nl2ltl/**/*.py", "tests/**/*.py"] + +[tool.ruff.lint] +select = [ + # Pyflakes + "F", + # Pycodestyle + "E", + "W", + # isort + "I001" +] + +[tool.ruff.format] +quote-style = "double" +indent-style = "space" +skip-magic-trailing-comma = false +line-ending = "auto" diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 1031c34..0000000 --- a/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -pylogics==0.2.1 -rasa==3.5.11 -openai==0.27.8 diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 54caad7..0000000 --- a/setup.cfg +++ /dev/null @@ -1,77 +0,0 @@ -[metadata] -name=nl2ltl -author=Tathagata Chakraborti, Francesco Fuggitti -author_email=tathagata.chakraborti1@ibm.com, francesco.fuggitti@ibm.com -version = attr: nl2ltl.__version__ -description = From Natural Language to Linear-time Temporal Logic -long_description = file: README.md, LICENSE -long_description_content_type = text/markdown -keywords = natural language nlu ltl temporal logic -license = MIT -license_files = LICENSE -classifiers = - Intended Audience :: Science/Research - Environment :: Console - Environment :: Web Environment - Development Status :: 2 - Pre-Alpha - License :: OSI Approved :: MIT License - Natural Language :: English - Operating System :: MacOS - Operating System :: Unix - Programming Language :: Python :: 3 - Programming Language :: Python :: 3.8 - Topic :: Scientific/Engineering :: Artificial Intelligence - Topic :: Software Development - - -[option.project_urls] -"Source": "https://github.com/IBM/nl2ltl" - -[options] -zip_safe = False -include_package_data = True -packages = find: -scripts = -install_requires = - rasa - openai - pylogics - -python_requires= >=3.8 - -[options.package_data] -* = *.txt, *.md - -[options.packages.find] -include = - nl2ltl* -exclude = - -[bdist_wheel] -universal = 1 - -[aliases] -test = pytest - -[flake8] -ignore = W503 -exclude = - .tox, - .git, - __pycache__, - build, - dist, - tests/fixtures/*, - *.md, - *.pyc, - *.egg-info, - .cache, - .eggs, - nl2ltl/__init__.py, - scripts/whitelist.py -max-complexity = 10 -max-line-length = 120 - -[mypy] -python_version = 3.8 -strict_optional = True diff --git a/setup.py b/setup.py deleted file mode 100644 index b3ffe82..0000000 --- a/setup.py +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -"""The setup script.""" -from setuptools import find_packages, setup # noqa: F401 - -if __name__ == "__main__": - setup() diff --git a/tests/__init__.py b/tests/__init__.py index 88ba6ed..ca78990 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,3 +1 @@ -# -*- coding: utf-8 -*- - """Test for the nl2ltl project.""" diff --git a/tests/conftest.py b/tests/conftest.py index 108519c..0e2ff51 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,11 +1,7 @@ -# -*- coding: utf-8 -*- - """The conftest.py module for pytest.""" import inspect from pathlib import Path -import pytest - import nl2ltl _current_filepath = inspect.getframeinfo(inspect.currentframe()).filename # type: ignore diff --git a/tests/test_gpt.py b/tests/test_gpt.py index cbbd8fa..643bfa6 100644 --- a/tests/test_gpt.py +++ b/tests/test_gpt.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """Tests for GPT engine.""" from typing import Dict @@ -17,10 +15,10 @@ class TestGPT: @classmethod def setup_class(cls): - """setup any state specific to the execution of the given class (which + """Setup any state specific to the execution of the given class (which usually contains tests). """ - cls.gpt_engine = GPTEngine(model=Models.DAVINCI3.value) + cls.gpt_engine = GPTEngine(model=Models.GPT35_INSTRUCT.value) cls.basic_filter = BasicFilter() cls.greedy_filter = GreedyFilter() diff --git a/tests/test_rasa.py b/tests/test_rasa.py index af6ab2f..9cd4dd7 100644 --- a/tests/test_rasa.py +++ b/tests/test_rasa.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - """Tests for Rasa engine.""" from typing import Dict @@ -17,7 +15,7 @@ class TestRasa: @classmethod def setup_class(cls): - """setup any state specific to the execution of the given class (which + """Setup any state specific to the execution of the given class (which usually contains tests). """ cls.rasa_engine = RasaEngine() diff --git a/tox.ini b/tox.ini index d76fa15..7c3febc 100644 --- a/tox.ini +++ b/tox.ini @@ -1,8 +1,6 @@ [tox] -envlist = precommit, docs, py3{8} -labels = - code = py3{8} - meta = precommit, docs +isolated_build = True +envlist = py3{10}, ruff-format, ruff-check, docs [testenv] allowlist_externals = pytest @@ -14,25 +12,41 @@ deps = pytest pytest-cov pytest-randomly - hypothesis-pytest +extras = + rasa commands = - pytest --basetemp={envtmpdir} --doctest-modules \ - {posargs:nl2ltl tests} \ + pytest --basetemp={envtmpdir} \ + --doctest-modules \ + {posargs:nl2ltl tests} \ --cov=nl2ltl \ --cov-report=xml \ --cov-report=html \ --cov-report=term - --hypothesis-show-statistics -[testenv:py{38}] +[testenv:py3{10}] commands = {[testenv]commands} deps = -[testenv:precommit] -skip_install = true -deps = pre-commit -commands = pre-commit run --all-files --show-diff-on-failure +[testenv:ruff-check] +skip_install = True +deps = ruff==0.1.9 +commands = ruff check . + +[testenv:ruff-check-apply] +skip_install = True +deps = ruff==0.1.9r +commands = ruff check --fix --show-fixes . + +[testenv:ruff-format] +skip_install = True +deps = ruff==0.1.9 +commands = ruff format --diff . + +[testenv:ruff-format-apply] +skip_install = True +deps = ruff==0.1.9 +commands = ruff format . [testenv:docs] skip_install = True