diff --git a/fieldExtraction/.dockerignore b/fieldExtraction/.dockerignore deleted file mode 100644 index 6fdd640..0000000 --- a/fieldExtraction/.dockerignore +++ /dev/null @@ -1 +0,0 @@ -.mypy_cache \ No newline at end of file diff --git a/fieldExtraction/.envrc b/fieldExtraction/.envrc deleted file mode 100644 index deef802..0000000 --- a/fieldExtraction/.envrc +++ /dev/null @@ -1,7 +0,0 @@ -dotenv_if_exists .env - -require AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN -require LOCAL_PATH -require BUCKET BUCKET_PREFIX -require READ_MODE MAX_WORKERS -require CLIENT \ No newline at end of file diff --git a/fieldExtraction/.gitignore b/fieldExtraction/.gitignore deleted file mode 100644 index a1b7db3..0000000 --- a/fieldExtraction/.gitignore +++ /dev/null @@ -1,70 +0,0 @@ -# These are some examples of commonly ignored file patterns. -# You should customize this list as applicable to your project. -# Learn more about .gitignore: -# https://www.atlassian.com/git/tutorials/saving-changes/gitignore -# Node artifact files -node_modules/ -dist/ -# Compiled Java class files -*.class -# Compiled Python bytecode -*.py[cod] -# Log files -*.log -# Package files -*.jar -# Maven -target/ -dist/ -# JetBrains IDE -.idea/ -# Unit test reports -TEST*.xml -# Generated by MacOS -.DS_Store -# Generated by Windows -Thumbs.db -# Applications -*.app -*.exe -*.war -# Large media files -*.mp4 -*.tiff -*.avi -*.flv -*.mov -*.wmv -# Terraform files -.terraform/ -terraform.tfstate.backup -terraform.tfstate -.terraform.lock.hcl -build/ -textract-pipeline/terraform/builds/ -# Data Files -streamlit/history.csv -streamlit/RESULTS -streamlit/DB/ -streamlit/RAW_DOCUMENTS/ -streamlit/SOURCE_DOCUMENTS/ -streamlit/contract_field_values.csv -streamlit/contract_fields.csv -streamlit/sample.csv -streamlit/temp1.csv -streamlit/temp2.csv -streamlit/results.csv -# env -streamlit/venv -*.tfplan -*.pem -*.pem -textfiles/ -texts/ -*.csv -*.json -myenv/ -*.env -subset/ -output/ -docs/ \ No newline at end of file diff --git a/fieldExtraction/.python-version b/fieldExtraction/.python-version deleted file mode 100644 index 56bb660..0000000 --- a/fieldExtraction/.python-version +++ /dev/null @@ -1 +0,0 @@ -3.12.7 diff --git a/fieldExtraction/README.md b/fieldExtraction/README.md deleted file mode 100644 index f8ca3ee..0000000 --- a/fieldExtraction/README.md +++ /dev/null @@ -1 +0,0 @@ -# Airflow \ No newline at end of file diff --git a/fieldExtraction/poetry.lock b/fieldExtraction/poetry.lock deleted file mode 100644 index c119225..0000000 --- a/fieldExtraction/poetry.lock +++ /dev/null @@ -1,1292 +0,0 @@ -# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. - -[[package]] -name = "annotated-types" -version = "0.7.0" -description = "Reusable constraint types to use with typing.Annotated" -optional = false -python-versions = ">=3.8" -files = [ - {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, - {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, -] - -[[package]] -name = "anthropic" -version = "0.36.0" -description = "The official Python library for the anthropic API" -optional = false -python-versions = ">=3.7" -files = [ - {file = "anthropic-0.36.0-py3-none-any.whl", hash = "sha256:9183b9eaa0f409f2047244d7ef02c9c3eb916959c0b2960f7605dcb6cabbf548"}, - {file = "anthropic-0.36.0.tar.gz", hash = "sha256:7b0b1457096605572a29559d9a8ce224b9389d379b410e7d1bf5e0c1379f9ee2"}, -] - -[package.dependencies] -anyio = ">=3.5.0,<5" -distro = ">=1.7.0,<2" -httpx = ">=0.23.0,<1" -jiter = ">=0.4.0,<1" -pydantic = ">=1.9.0,<3" -sniffio = "*" -tokenizers = ">=0.13.0" -typing-extensions = ">=4.7,<5" - -[package.extras] -bedrock = ["boto3 (>=1.28.57)", "botocore (>=1.31.57)"] -vertex = ["google-auth (>=2,<3)"] - -[[package]] -name = "anyio" -version = "4.6.2.post1" -description = "High level compatibility layer for multiple asynchronous event loop implementations" -optional = false -python-versions = ">=3.9" -files = [ - {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, - {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, -] - -[package.dependencies] -idna = ">=2.8" -sniffio = ">=1.1" - -[package.extras] -doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] -trio = ["trio (>=0.26.1)"] - -[[package]] -name = "black" -version = "24.10.0" -description = "The uncompromising code formatter." -optional = false -python-versions = ">=3.9" -files = [ - {file = "black-24.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6668650ea4b685440857138e5fe40cde4d652633b1bdffc62933d0db4ed9812"}, - {file = "black-24.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1c536fcf674217e87b8cc3657b81809d3c085d7bf3ef262ead700da345bfa6ea"}, - {file = "black-24.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:649fff99a20bd06c6f727d2a27f401331dc0cc861fb69cde910fe95b01b5928f"}, - {file = "black-24.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:fe4d6476887de70546212c99ac9bd803d90b42fc4767f058a0baa895013fbb3e"}, - {file = "black-24.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5a2221696a8224e335c28816a9d331a6c2ae15a2ee34ec857dcf3e45dbfa99ad"}, - {file = "black-24.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f9da3333530dbcecc1be13e69c250ed8dfa67f43c4005fb537bb426e19200d50"}, - {file = "black-24.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4007b1393d902b48b36958a216c20c4482f601569d19ed1df294a496eb366392"}, - {file = "black-24.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:394d4ddc64782e51153eadcaaca95144ac4c35e27ef9b0a42e121ae7e57a9175"}, - {file = "black-24.10.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b5e39e0fae001df40f95bd8cc36b9165c5e2ea88900167bddf258bacef9bbdc3"}, - {file = "black-24.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d37d422772111794b26757c5b55a3eade028aa3fde43121ab7b673d050949d65"}, - {file = "black-24.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:14b3502784f09ce2443830e3133dacf2c0110d45191ed470ecb04d0f5f6fcb0f"}, - {file = "black-24.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:30d2c30dc5139211dda799758559d1b049f7f14c580c409d6ad925b74a4208a8"}, - {file = "black-24.10.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cbacacb19e922a1d75ef2b6ccaefcd6e93a2c05ede32f06a21386a04cedb981"}, - {file = "black-24.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1f93102e0c5bb3907451063e08b9876dbeac810e7da5a8bfb7aeb5a9ef89066b"}, - {file = "black-24.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ddacb691cdcdf77b96f549cf9591701d8db36b2f19519373d60d31746068dbf2"}, - {file = "black-24.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:680359d932801c76d2e9c9068d05c6b107f2584b2a5b88831c83962eb9984c1b"}, - {file = "black-24.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:17374989640fbca88b6a448129cd1745c5eb8d9547b464f281b251dd00155ccd"}, - {file = "black-24.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:63f626344343083322233f175aaf372d326de8436f5928c042639a4afbbf1d3f"}, - {file = "black-24.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfa1d0cb6200857f1923b602f978386a3a2758a65b52e0950299ea014be6800"}, - {file = "black-24.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:2cd9c95431d94adc56600710f8813ee27eea544dd118d45896bb734e9d7a0dc7"}, - {file = "black-24.10.0-py3-none-any.whl", hash = "sha256:3bb2b7a1f7b685f85b11fed1ef10f8a9148bceb49853e47a294a3dd963c1dd7d"}, - {file = "black-24.10.0.tar.gz", hash = "sha256:846ea64c97afe3bc677b761787993be4991810ecc7a4a937816dd6bddedc4875"}, -] - -[package.dependencies] -click = ">=8.0.0" -mypy-extensions = ">=0.4.3" -packaging = ">=22.0" -pathspec = ">=0.9.0" -platformdirs = ">=2" - -[package.extras] -colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.10)"] -jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] -uvloop = ["uvloop (>=0.15.2)"] - -[[package]] -name = "boto3" -version = "1.35.37" -description = "The AWS SDK for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "boto3-1.35.37-py3-none-any.whl", hash = "sha256:385ca77bf8ea4ab2d97f6e2435bdb29f77d9301e2f7ac796c2f465753c2adf3c"}, - {file = "boto3-1.35.37.tar.gz", hash = "sha256:470d981583885859fed2fd1c185eeb01cc03e60272d499bafe41b12625b158c8"}, -] - -[package.dependencies] -botocore = ">=1.35.37,<1.36.0" -jmespath = ">=0.7.1,<2.0.0" -s3transfer = ">=0.10.0,<0.11.0" - -[package.extras] -crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] - -[[package]] -name = "botocore" -version = "1.35.37" -description = "Low-level, data-driven core of boto 3." -optional = false -python-versions = ">=3.8" -files = [ - {file = "botocore-1.35.37-py3-none-any.whl", hash = "sha256:64f965d4ba7adb8d79ce044c3aef7356e05dd74753cf7e9115b80f477845d920"}, - {file = "botocore-1.35.37.tar.gz", hash = "sha256:b2b4d29bafd95b698344f2f0577bb67064adbf1735d8a0e3c7473daa59c23ba6"}, -] - -[package.dependencies] -jmespath = ">=0.7.1,<2.0.0" -python-dateutil = ">=2.1,<3.0.0" -urllib3 = {version = ">=1.25.4,<2.2.0 || >2.2.0,<3", markers = "python_version >= \"3.10\""} - -[package.extras] -crt = ["awscrt (==0.22.0)"] - -[[package]] -name = "certifi" -version = "2024.8.30" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.6" -files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, -] - -[[package]] -name = "charset-normalizer" -version = "3.4.0" -description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, -] - -[[package]] -name = "click" -version = "8.1.7" -description = "Composable command line interface toolkit" -optional = false -python-versions = ">=3.7" -files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -files = [ - {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, - {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, -] - -[[package]] -name = "distro" -version = "1.9.0" -description = "Distro - an OS platform information API" -optional = false -python-versions = ">=3.6" -files = [ - {file = "distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2"}, - {file = "distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed"}, -] - -[[package]] -name = "filelock" -version = "3.16.1" -description = "A platform independent file lock." -optional = false -python-versions = ">=3.8" -files = [ - {file = "filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0"}, - {file = "filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435"}, -] - -[package.extras] -docs = ["furo (>=2024.8.6)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4.1)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.6.1)", "diff-cover (>=9.2)", "pytest (>=8.3.3)", "pytest-asyncio (>=0.24)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.26.4)"] -typing = ["typing-extensions (>=4.12.2)"] - -[[package]] -name = "fsspec" -version = "2024.9.0" -description = "File-system specification" -optional = false -python-versions = ">=3.8" -files = [ - {file = "fsspec-2024.9.0-py3-none-any.whl", hash = "sha256:a0947d552d8a6efa72cc2c730b12c41d043509156966cca4fb157b0f2a0c574b"}, - {file = "fsspec-2024.9.0.tar.gz", hash = "sha256:4b0afb90c2f21832df142f292649035d80b421f60a9e1c027802e5a0da2b04e8"}, -] - -[package.extras] -abfs = ["adlfs"] -adl = ["adlfs"] -arrow = ["pyarrow (>=1)"] -dask = ["dask", "distributed"] -dev = ["pre-commit", "ruff"] -doc = ["numpydoc", "sphinx", "sphinx-design", "sphinx-rtd-theme", "yarl"] -dropbox = ["dropbox", "dropboxdrivefs", "requests"] -full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "dask", "distributed", "dropbox", "dropboxdrivefs", "fusepy", "gcsfs", "libarchive-c", "ocifs", "panel", "paramiko", "pyarrow (>=1)", "pygit2", "requests", "s3fs", "smbprotocol", "tqdm"] -fuse = ["fusepy"] -gcs = ["gcsfs"] -git = ["pygit2"] -github = ["requests"] -gs = ["gcsfs"] -gui = ["panel"] -hdfs = ["pyarrow (>=1)"] -http = ["aiohttp (!=4.0.0a0,!=4.0.0a1)"] -libarchive = ["libarchive-c"] -oci = ["ocifs"] -s3 = ["s3fs"] -sftp = ["paramiko"] -smb = ["smbprotocol"] -ssh = ["paramiko"] -test = ["aiohttp (!=4.0.0a0,!=4.0.0a1)", "numpy", "pytest", "pytest-asyncio (!=0.22.0)", "pytest-benchmark", "pytest-cov", "pytest-mock", "pytest-recording", "pytest-rerunfailures", "requests"] -test-downstream = ["aiobotocore (>=2.5.4,<3.0.0)", "dask-expr", "dask[dataframe,test]", "moto[server] (>4,<5)", "pytest-timeout", "xarray"] -test-full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "cloudpickle", "dask", "distributed", "dropbox", "dropboxdrivefs", "fastparquet", "fusepy", "gcsfs", "jinja2", "kerchunk", "libarchive-c", "lz4", "notebook", "numpy", "ocifs", "pandas", "panel", "paramiko", "pyarrow", "pyarrow (>=1)", "pyftpdlib", "pygit2", "pytest", "pytest-asyncio (!=0.22.0)", "pytest-benchmark", "pytest-cov", "pytest-mock", "pytest-recording", "pytest-rerunfailures", "python-snappy", "requests", "smbprotocol", "tqdm", "urllib3", "zarr", "zstandard"] -tqdm = ["tqdm"] - -[[package]] -name = "h11" -version = "0.14.0" -description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" -optional = false -python-versions = ">=3.7" -files = [ - {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, - {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, -] - -[[package]] -name = "httpcore" -version = "1.0.6" -description = "A minimal low-level HTTP client." -optional = false -python-versions = ">=3.8" -files = [ - {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, - {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, -] - -[package.dependencies] -certifi = "*" -h11 = ">=0.13,<0.15" - -[package.extras] -asyncio = ["anyio (>=4.0,<5.0)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] -trio = ["trio (>=0.22.0,<1.0)"] - -[[package]] -name = "httpx" -version = "0.27.2" -description = "The next generation HTTP client." -optional = false -python-versions = ">=3.8" -files = [ - {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, - {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, -] - -[package.dependencies] -anyio = "*" -certifi = "*" -httpcore = "==1.*" -idna = "*" -sniffio = "*" - -[package.extras] -brotli = ["brotli", "brotlicffi"] -cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "huggingface-hub" -version = "0.25.2" -description = "Client library to download and publish models, datasets and other repos on the huggingface.co hub" -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "huggingface_hub-0.25.2-py3-none-any.whl", hash = "sha256:1897caf88ce7f97fe0110603d8f66ac264e3ba6accdf30cd66cc0fed5282ad25"}, - {file = "huggingface_hub-0.25.2.tar.gz", hash = "sha256:a1014ea111a5f40ccd23f7f7ba8ac46e20fa3b658ced1f86a00c75c06ec6423c"}, -] - -[package.dependencies] -filelock = "*" -fsspec = ">=2023.5.0" -packaging = ">=20.9" -pyyaml = ">=5.1" -requests = "*" -tqdm = ">=4.42.1" -typing-extensions = ">=3.7.4.3" - -[package.extras] -all = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "fastapi", "gradio", "jedi", "minijinja (>=1.0)", "mypy (==1.5.1)", "numpy", "pytest (>=8.1.1,<8.2.2)", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-mock", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "ruff (>=0.5.0)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"] -cli = ["InquirerPy (==0.3.4)"] -dev = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "fastapi", "gradio", "jedi", "minijinja (>=1.0)", "mypy (==1.5.1)", "numpy", "pytest (>=8.1.1,<8.2.2)", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-mock", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "ruff (>=0.5.0)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"] -fastai = ["fastai (>=2.4)", "fastcore (>=1.3.27)", "toml"] -hf-transfer = ["hf-transfer (>=0.1.4)"] -inference = ["aiohttp", "minijinja (>=1.0)"] -quality = ["mypy (==1.5.1)", "ruff (>=0.5.0)"] -tensorflow = ["graphviz", "pydot", "tensorflow"] -tensorflow-testing = ["keras (<3.0)", "tensorflow"] -testing = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "fastapi", "gradio", "jedi", "minijinja (>=1.0)", "numpy", "pytest (>=8.1.1,<8.2.2)", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-mock", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "soundfile", "urllib3 (<2.0)"] -torch = ["safetensors[torch]", "torch"] -typing = ["types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)"] - -[[package]] -name = "idna" -version = "3.10" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.6" -files = [ - {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, - {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, -] - -[package.extras] -all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] - -[[package]] -name = "iniconfig" -version = "2.0.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.7" -files = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, -] - -[[package]] -name = "jiter" -version = "0.6.1" -description = "Fast iterable JSON parser." -optional = false -python-versions = ">=3.8" -files = [ - {file = "jiter-0.6.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:d08510593cb57296851080018006dfc394070178d238b767b1879dc1013b106c"}, - {file = "jiter-0.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:adef59d5e2394ebbad13b7ed5e0306cceb1df92e2de688824232a91588e77aa7"}, - {file = "jiter-0.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b3e02f7a27f2bcc15b7d455c9df05df8ffffcc596a2a541eeda9a3110326e7a3"}, - {file = "jiter-0.6.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed69a7971d67b08f152c17c638f0e8c2aa207e9dd3a5fcd3cba294d39b5a8d2d"}, - {file = "jiter-0.6.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2019d966e98f7c6df24b3b8363998575f47d26471bfb14aade37630fae836a1"}, - {file = "jiter-0.6.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:36c0b51a285b68311e207a76c385650322734c8717d16c2eb8af75c9d69506e7"}, - {file = "jiter-0.6.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:220e0963b4fb507c525c8f58cde3da6b1be0bfddb7ffd6798fb8f2531226cdb1"}, - {file = "jiter-0.6.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:aa25c7a9bf7875a141182b9c95aed487add635da01942ef7ca726e42a0c09058"}, - {file = "jiter-0.6.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e90552109ca8ccd07f47ca99c8a1509ced93920d271bb81780a973279974c5ab"}, - {file = "jiter-0.6.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:67723a011964971864e0b484b0ecfee6a14de1533cff7ffd71189e92103b38a8"}, - {file = "jiter-0.6.1-cp310-none-win32.whl", hash = "sha256:33af2b7d2bf310fdfec2da0177eab2fedab8679d1538d5b86a633ebfbbac4edd"}, - {file = "jiter-0.6.1-cp310-none-win_amd64.whl", hash = "sha256:7cea41c4c673353799906d940eee8f2d8fd1d9561d734aa921ae0f75cb9732f4"}, - {file = "jiter-0.6.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:b03c24e7da7e75b170c7b2b172d9c5e463aa4b5c95696a368d52c295b3f6847f"}, - {file = "jiter-0.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:47fee1be677b25d0ef79d687e238dc6ac91a8e553e1a68d0839f38c69e0ee491"}, - {file = "jiter-0.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25f0d2f6e01a8a0fb0eab6d0e469058dab2be46ff3139ed2d1543475b5a1d8e7"}, - {file = "jiter-0.6.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0b809e39e342c346df454b29bfcc7bca3d957f5d7b60e33dae42b0e5ec13e027"}, - {file = "jiter-0.6.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e9ac7c2f092f231f5620bef23ce2e530bd218fc046098747cc390b21b8738a7a"}, - {file = "jiter-0.6.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e51a2d80d5fe0ffb10ed2c82b6004458be4a3f2b9c7d09ed85baa2fbf033f54b"}, - {file = "jiter-0.6.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3343d4706a2b7140e8bd49b6c8b0a82abf9194b3f0f5925a78fc69359f8fc33c"}, - {file = "jiter-0.6.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82521000d18c71e41c96960cb36e915a357bc83d63a8bed63154b89d95d05ad1"}, - {file = "jiter-0.6.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:3c843e7c1633470708a3987e8ce617ee2979ee18542d6eb25ae92861af3f1d62"}, - {file = "jiter-0.6.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a2e861658c3fe849efc39b06ebb98d042e4a4c51a8d7d1c3ddc3b1ea091d0784"}, - {file = "jiter-0.6.1-cp311-none-win32.whl", hash = "sha256:7d72fc86474862c9c6d1f87b921b70c362f2b7e8b2e3c798bb7d58e419a6bc0f"}, - {file = "jiter-0.6.1-cp311-none-win_amd64.whl", hash = "sha256:3e36a320634f33a07794bb15b8da995dccb94f944d298c8cfe2bd99b1b8a574a"}, - {file = "jiter-0.6.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:1fad93654d5a7dcce0809aff66e883c98e2618b86656aeb2129db2cd6f26f867"}, - {file = "jiter-0.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4e6e340e8cd92edab7f6a3a904dbbc8137e7f4b347c49a27da9814015cc0420c"}, - {file = "jiter-0.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:691352e5653af84ed71763c3c427cff05e4d658c508172e01e9c956dfe004aba"}, - {file = "jiter-0.6.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:defee3949313c1f5b55e18be45089970cdb936eb2a0063f5020c4185db1b63c9"}, - {file = "jiter-0.6.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:26d2bdd5da097e624081c6b5d416d3ee73e5b13f1703bcdadbb1881f0caa1933"}, - {file = "jiter-0.6.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18aa9d1626b61c0734b973ed7088f8a3d690d0b7f5384a5270cd04f4d9f26c86"}, - {file = "jiter-0.6.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a3567c8228afa5ddcce950631c6b17397ed178003dc9ee7e567c4c4dcae9fa0"}, - {file = "jiter-0.6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e5c0507131c922defe3f04c527d6838932fcdfd69facebafd7d3574fa3395314"}, - {file = "jiter-0.6.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:540fcb224d7dc1bcf82f90f2ffb652df96f2851c031adca3c8741cb91877143b"}, - {file = "jiter-0.6.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e7b75436d4fa2032b2530ad989e4cb0ca74c655975e3ff49f91a1a3d7f4e1df2"}, - {file = "jiter-0.6.1-cp312-none-win32.whl", hash = "sha256:883d2ced7c21bf06874fdeecab15014c1c6d82216765ca6deef08e335fa719e0"}, - {file = "jiter-0.6.1-cp312-none-win_amd64.whl", hash = "sha256:91e63273563401aadc6c52cca64a7921c50b29372441adc104127b910e98a5b6"}, - {file = "jiter-0.6.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:852508a54fe3228432e56019da8b69208ea622a3069458252f725d634e955b31"}, - {file = "jiter-0.6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f491cc69ff44e5a1e8bc6bf2b94c1f98d179e1aaf4a554493c171a5b2316b701"}, - {file = "jiter-0.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc56c8f0b2a28ad4d8047f3ae62d25d0e9ae01b99940ec0283263a04724de1f3"}, - {file = "jiter-0.6.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:51b58f7a0d9e084a43b28b23da2b09fc5e8df6aa2b6a27de43f991293cab85fd"}, - {file = "jiter-0.6.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5f79ce15099154c90ef900d69c6b4c686b64dfe23b0114e0971f2fecd306ec6c"}, - {file = "jiter-0.6.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:03a025b52009f47e53ea619175d17e4ded7c035c6fbd44935cb3ada11e1fd592"}, - {file = "jiter-0.6.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c74a8d93718137c021d9295248a87c2f9fdc0dcafead12d2930bc459ad40f885"}, - {file = "jiter-0.6.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:40b03b75f903975f68199fc4ec73d546150919cb7e534f3b51e727c4d6ccca5a"}, - {file = "jiter-0.6.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:825651a3f04cf92a661d22cad61fc913400e33aa89b3e3ad9a6aa9dc8a1f5a71"}, - {file = "jiter-0.6.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:928bf25eb69ddb292ab8177fe69d3fbf76c7feab5fce1c09265a7dccf25d3991"}, - {file = "jiter-0.6.1-cp313-none-win32.whl", hash = "sha256:352cd24121e80d3d053fab1cc9806258cad27c53cad99b7a3cac57cf934b12e4"}, - {file = "jiter-0.6.1-cp313-none-win_amd64.whl", hash = "sha256:be7503dd6f4bf02c2a9bacb5cc9335bc59132e7eee9d3e931b13d76fd80d7fda"}, - {file = "jiter-0.6.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:31d8e00e1fb4c277df8ab6f31a671f509ebc791a80e5c61fdc6bc8696aaa297c"}, - {file = "jiter-0.6.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:77c296d65003cd7ee5d7b0965f6acbe6cffaf9d1fa420ea751f60ef24e85fed5"}, - {file = "jiter-0.6.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aeeb0c0325ef96c12a48ea7e23e2e86fe4838e6e0a995f464cf4c79fa791ceeb"}, - {file = "jiter-0.6.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a31c6fcbe7d6c25d6f1cc6bb1cba576251d32795d09c09961174fe461a1fb5bd"}, - {file = "jiter-0.6.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59e2b37f3b9401fc9e619f4d4badcab2e8643a721838bcf695c2318a0475ae42"}, - {file = "jiter-0.6.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bae5ae4853cb9644144e9d0755854ce5108d470d31541d83f70ca7ecdc2d1637"}, - {file = "jiter-0.6.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9df588e9c830b72d8db1dd7d0175af6706b0904f682ea9b1ca8b46028e54d6e9"}, - {file = "jiter-0.6.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:15f8395e835cf561c85c1adee72d899abf2733d9df72e9798e6d667c9b5c1f30"}, - {file = "jiter-0.6.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5a99d4e0b5fc3b05ea732d67eb2092fe894e95a90e6e413f2ea91387e228a307"}, - {file = "jiter-0.6.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a311df1fa6be0ccd64c12abcd85458383d96e542531bafbfc0a16ff6feda588f"}, - {file = "jiter-0.6.1-cp38-none-win32.whl", hash = "sha256:81116a6c272a11347b199f0e16b6bd63f4c9d9b52bc108991397dd80d3c78aba"}, - {file = "jiter-0.6.1-cp38-none-win_amd64.whl", hash = "sha256:13f9084e3e871a7c0b6e710db54444088b1dd9fbefa54d449b630d5e73bb95d0"}, - {file = "jiter-0.6.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:f1c53615fcfec3b11527c08d19cff6bc870da567ce4e57676c059a3102d3a082"}, - {file = "jiter-0.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f791b6a4da23238c17a81f44f5b55d08a420c5692c1fda84e301a4b036744eb1"}, - {file = "jiter-0.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c97e90fec2da1d5f68ef121444c2c4fa72eabf3240829ad95cf6bbeca42a301"}, - {file = "jiter-0.6.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3cbc1a66b4e41511209e97a2866898733c0110b7245791ac604117b7fb3fedb7"}, - {file = "jiter-0.6.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4e85f9e12cd8418ab10e1fcf0e335ae5bb3da26c4d13a0fd9e6a17a674783b6"}, - {file = "jiter-0.6.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08be33db6dcc374c9cc19d3633af5e47961a7b10d4c61710bd39e48d52a35824"}, - {file = "jiter-0.6.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:677be9550004f5e010d673d3b2a2b815a8ea07a71484a57d3f85dde7f14cf132"}, - {file = "jiter-0.6.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e8bd065be46c2eecc328e419d6557bbc37844c88bb07b7a8d2d6c91c7c4dedc9"}, - {file = "jiter-0.6.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bd95375ce3609ec079a97c5d165afdd25693302c071ca60c7ae1cf826eb32022"}, - {file = "jiter-0.6.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:db459ed22d0208940d87f614e1f0ea5a946d29a3cfef71f7e1aab59b6c6b2afb"}, - {file = "jiter-0.6.1-cp39-none-win32.whl", hash = "sha256:d71c962f0971347bd552940ab96aa42ceefcd51b88c4ced8a27398182efa8d80"}, - {file = "jiter-0.6.1-cp39-none-win_amd64.whl", hash = "sha256:d465db62d2d10b489b7e7a33027c4ae3a64374425d757e963f86df5b5f2e7fc5"}, - {file = "jiter-0.6.1.tar.gz", hash = "sha256:e19cd21221fc139fb032e4112986656cb2739e9fe6d84c13956ab30ccc7d4449"}, -] - -[[package]] -name = "jmespath" -version = "1.0.1" -description = "JSON Matching Expressions" -optional = false -python-versions = ">=3.7" -files = [ - {file = "jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980"}, - {file = "jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe"}, -] - -[[package]] -name = "mypy" -version = "1.12.0" -description = "Optional static typing for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "mypy-1.12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4397081e620dc4dc18e2f124d5e1d2c288194c2c08df6bdb1db31c38cd1fe1ed"}, - {file = "mypy-1.12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:684a9c508a283f324804fea3f0effeb7858eb03f85c4402a967d187f64562469"}, - {file = "mypy-1.12.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6cabe4cda2fa5eca7ac94854c6c37039324baaa428ecbf4de4567279e9810f9e"}, - {file = "mypy-1.12.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:060a07b10e999ac9e7fa249ce2bdcfa9183ca2b70756f3bce9df7a92f78a3c0a"}, - {file = "mypy-1.12.0-cp310-cp310-win_amd64.whl", hash = "sha256:0eff042d7257f39ba4ca06641d110ca7d2ad98c9c1fb52200fe6b1c865d360ff"}, - {file = "mypy-1.12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4b86de37a0da945f6d48cf110d5206c5ed514b1ca2614d7ad652d4bf099c7de7"}, - {file = "mypy-1.12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:20c7c5ce0c1be0b0aea628374e6cf68b420bcc772d85c3c974f675b88e3e6e57"}, - {file = "mypy-1.12.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a64ee25f05fc2d3d8474985c58042b6759100a475f8237da1f4faf7fcd7e6309"}, - {file = "mypy-1.12.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:faca7ab947c9f457a08dcb8d9a8664fd438080e002b0fa3e41b0535335edcf7f"}, - {file = "mypy-1.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:5bc81701d52cc8767005fdd2a08c19980de9ec61a25dbd2a937dfb1338a826f9"}, - {file = "mypy-1.12.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:8462655b6694feb1c99e433ea905d46c478041a8b8f0c33f1dab00ae881b2164"}, - {file = "mypy-1.12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:923ea66d282d8af9e0f9c21ffc6653643abb95b658c3a8a32dca1eff09c06475"}, - {file = "mypy-1.12.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1ebf9e796521f99d61864ed89d1fb2926d9ab6a5fab421e457cd9c7e4dd65aa9"}, - {file = "mypy-1.12.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e478601cc3e3fa9d6734d255a59c7a2e5c2934da4378f3dd1e3411ea8a248642"}, - {file = "mypy-1.12.0-cp312-cp312-win_amd64.whl", hash = "sha256:c72861b7139a4f738344faa0e150834467521a3fba42dc98264e5aa9507dd601"}, - {file = "mypy-1.12.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:52b9e1492e47e1790360a43755fa04101a7ac72287b1a53ce817f35899ba0521"}, - {file = "mypy-1.12.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:48d3e37dd7d9403e38fa86c46191de72705166d40b8c9f91a3de77350daa0893"}, - {file = "mypy-1.12.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2f106db5ccb60681b622ac768455743ee0e6a857724d648c9629a9bd2ac3f721"}, - {file = "mypy-1.12.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:233e11b3f73ee1f10efada2e6da0f555b2f3a5316e9d8a4a1224acc10e7181d3"}, - {file = "mypy-1.12.0-cp313-cp313-win_amd64.whl", hash = "sha256:4ae8959c21abcf9d73aa6c74a313c45c0b5a188752bf37dace564e29f06e9c1b"}, - {file = "mypy-1.12.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:eafc1b7319b40ddabdc3db8d7d48e76cfc65bbeeafaa525a4e0fa6b76175467f"}, - {file = "mypy-1.12.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9b9ce1ad8daeb049c0b55fdb753d7414260bad8952645367e70ac91aec90e07e"}, - {file = "mypy-1.12.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bfe012b50e1491d439172c43ccb50db66d23fab714d500b57ed52526a1020bb7"}, - {file = "mypy-1.12.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2c40658d4fa1ab27cb53d9e2f1066345596af2f8fe4827defc398a09c7c9519b"}, - {file = "mypy-1.12.0-cp38-cp38-win_amd64.whl", hash = "sha256:dee78a8b9746c30c1e617ccb1307b351ded57f0de0d287ca6276378d770006c0"}, - {file = "mypy-1.12.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b5df6c8a8224f6b86746bda716bbe4dbe0ce89fd67b1fa4661e11bfe38e8ec8"}, - {file = "mypy-1.12.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5feee5c74eb9749e91b77f60b30771563327329e29218d95bedbe1257e2fe4b0"}, - {file = "mypy-1.12.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:77278e8c6ffe2abfba6db4125de55f1024de9a323be13d20e4f73b8ed3402bd1"}, - {file = "mypy-1.12.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:dcfb754dea911039ac12434d1950d69a2f05acd4d56f7935ed402be09fad145e"}, - {file = "mypy-1.12.0-cp39-cp39-win_amd64.whl", hash = "sha256:06de0498798527451ffb60f68db0d368bd2bae2bbfb5237eae616d4330cc87aa"}, - {file = "mypy-1.12.0-py3-none-any.whl", hash = "sha256:fd313226af375d52e1e36c383f39bf3836e1f192801116b31b090dfcd3ec5266"}, - {file = "mypy-1.12.0.tar.gz", hash = "sha256:65a22d87e757ccd95cbbf6f7e181e6caa87128255eb2b6be901bb71b26d8a99d"}, -] - -[package.dependencies] -mypy-extensions = ">=1.0.0" -typing-extensions = ">=4.6.0" - -[package.extras] -dmypy = ["psutil (>=4.0)"] -install-types = ["pip"] -mypyc = ["setuptools (>=50)"] -reports = ["lxml"] - -[[package]] -name = "mypy-extensions" -version = "1.0.0" -description = "Type system extensions for programs checked with the mypy type checker." -optional = false -python-versions = ">=3.5" -files = [ - {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, - {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, -] - -[[package]] -name = "numpy" -version = "2.1.2" -description = "Fundamental package for array computing in Python" -optional = false -python-versions = ">=3.10" -files = [ - {file = "numpy-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:30d53720b726ec36a7f88dc873f0eec8447fbc93d93a8f079dfac2629598d6ee"}, - {file = "numpy-2.1.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8d3ca0a72dd8846eb6f7dfe8f19088060fcb76931ed592d29128e0219652884"}, - {file = "numpy-2.1.2-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:fc44e3c68ff00fd991b59092a54350e6e4911152682b4782f68070985aa9e648"}, - {file = "numpy-2.1.2-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:7c1c60328bd964b53f8b835df69ae8198659e2b9302ff9ebb7de4e5a5994db3d"}, - {file = "numpy-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6cdb606a7478f9ad91c6283e238544451e3a95f30fb5467fbf715964341a8a86"}, - {file = "numpy-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d666cb72687559689e9906197e3bec7b736764df6a2e58ee265e360663e9baf7"}, - {file = "numpy-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c6eef7a2dbd0abfb0d9eaf78b73017dbfd0b54051102ff4e6a7b2980d5ac1a03"}, - {file = "numpy-2.1.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:12edb90831ff481f7ef5f6bc6431a9d74dc0e5ff401559a71e5e4611d4f2d466"}, - {file = "numpy-2.1.2-cp310-cp310-win32.whl", hash = "sha256:a65acfdb9c6ebb8368490dbafe83c03c7e277b37e6857f0caeadbbc56e12f4fb"}, - {file = "numpy-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:860ec6e63e2c5c2ee5e9121808145c7bf86c96cca9ad396c0bd3e0f2798ccbe2"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b42a1a511c81cc78cbc4539675713bbcf9d9c3913386243ceff0e9429ca892fe"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:faa88bc527d0f097abdc2c663cddf37c05a1c2f113716601555249805cf573f1"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:c82af4b2ddd2ee72d1fc0c6695048d457e00b3582ccde72d8a1c991b808bb20f"}, - {file = "numpy-2.1.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:13602b3174432a35b16c4cfb5de9a12d229727c3dd47a6ce35111f2ebdf66ff4"}, - {file = "numpy-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ebec5fd716c5a5b3d8dfcc439be82a8407b7b24b230d0ad28a81b61c2f4659a"}, - {file = "numpy-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2b49c3c0804e8ecb05d59af8386ec2f74877f7ca8fd9c1e00be2672e4d399b1"}, - {file = "numpy-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2cbba4b30bf31ddbe97f1c7205ef976909a93a66bb1583e983adbd155ba72ac2"}, - {file = "numpy-2.1.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8e00ea6fc82e8a804433d3e9cedaa1051a1422cb6e443011590c14d2dea59146"}, - {file = "numpy-2.1.2-cp311-cp311-win32.whl", hash = "sha256:5006b13a06e0b38d561fab5ccc37581f23c9511879be7693bd33c7cd15ca227c"}, - {file = "numpy-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:f1eb068ead09f4994dec71c24b2844f1e4e4e013b9629f812f292f04bd1510d9"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d7bf0a4f9f15b32b5ba53147369e94296f5fffb783db5aacc1be15b4bf72f43b"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b1d0fcae4f0949f215d4632be684a539859b295e2d0cb14f78ec231915d644db"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:f751ed0a2f250541e19dfca9f1eafa31a392c71c832b6bb9e113b10d050cb0f1"}, - {file = "numpy-2.1.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:bd33f82e95ba7ad632bc57837ee99dba3d7e006536200c4e9124089e1bf42426"}, - {file = "numpy-2.1.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b8cde4f11f0a975d1fd59373b32e2f5a562ade7cde4f85b7137f3de8fbb29a0"}, - {file = "numpy-2.1.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d95f286b8244b3649b477ac066c6906fbb2905f8ac19b170e2175d3d799f4df"}, - {file = "numpy-2.1.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ab4754d432e3ac42d33a269c8567413bdb541689b02d93788af4131018cbf366"}, - {file = "numpy-2.1.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e585c8ae871fd38ac50598f4763d73ec5497b0de9a0ab4ef5b69f01c6a046142"}, - {file = "numpy-2.1.2-cp312-cp312-win32.whl", hash = "sha256:9c6c754df29ce6a89ed23afb25550d1c2d5fdb9901d9c67a16e0b16eaf7e2550"}, - {file = "numpy-2.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:456e3b11cb79ac9946c822a56346ec80275eaf2950314b249b512896c0d2505e"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a84498e0d0a1174f2b3ed769b67b656aa5460c92c9554039e11f20a05650f00d"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4d6ec0d4222e8ffdab1744da2560f07856421b367928026fb540e1945f2eeeaf"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:259ec80d54999cc34cd1eb8ded513cb053c3bf4829152a2e00de2371bd406f5e"}, - {file = "numpy-2.1.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:675c741d4739af2dc20cd6c6a5c4b7355c728167845e3c6b0e824e4e5d36a6c3"}, - {file = "numpy-2.1.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05b2d4e667895cc55e3ff2b56077e4c8a5604361fc21a042845ea3ad67465aa8"}, - {file = "numpy-2.1.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:43cca367bf94a14aca50b89e9bc2061683116cfe864e56740e083392f533ce7a"}, - {file = "numpy-2.1.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:76322dcdb16fccf2ac56f99048af32259dcc488d9b7e25b51e5eca5147a3fb98"}, - {file = "numpy-2.1.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:32e16a03138cabe0cb28e1007ee82264296ac0983714094380b408097a418cfe"}, - {file = "numpy-2.1.2-cp313-cp313-win32.whl", hash = "sha256:242b39d00e4944431a3cd2db2f5377e15b5785920421993770cddb89992c3f3a"}, - {file = "numpy-2.1.2-cp313-cp313-win_amd64.whl", hash = "sha256:f2ded8d9b6f68cc26f8425eda5d3877b47343e68ca23d0d0846f4d312ecaa445"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2ffef621c14ebb0188a8633348504a35c13680d6da93ab5cb86f4e54b7e922b5"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:ad369ed238b1959dfbade9018a740fb9392c5ac4f9b5173f420bd4f37ba1f7a0"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d82075752f40c0ddf57e6e02673a17f6cb0f8eb3f587f63ca1eaab5594da5b17"}, - {file = "numpy-2.1.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:1600068c262af1ca9580a527d43dc9d959b0b1d8e56f8a05d830eea39b7c8af6"}, - {file = "numpy-2.1.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a26ae94658d3ba3781d5e103ac07a876b3e9b29db53f68ed7df432fd033358a8"}, - {file = "numpy-2.1.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13311c2db4c5f7609b462bc0f43d3c465424d25c626d95040f073e30f7570e35"}, - {file = "numpy-2.1.2-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:2abbf905a0b568706391ec6fa15161fad0fb5d8b68d73c461b3c1bab6064dd62"}, - {file = "numpy-2.1.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:ef444c57d664d35cac4e18c298c47d7b504c66b17c2ea91312e979fcfbdfb08a"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:bdd407c40483463898b84490770199d5714dcc9dd9b792f6c6caccc523c00952"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:da65fb46d4cbb75cb417cddf6ba5e7582eb7bb0b47db4b99c9fe5787ce5d91f5"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c193d0b0238638e6fc5f10f1b074a6993cb13b0b431f64079a509d63d3aa8b7"}, - {file = "numpy-2.1.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a7d80b2e904faa63068ead63107189164ca443b42dd1930299e0d1cb041cec2e"}, - {file = "numpy-2.1.2.tar.gz", hash = "sha256:13532a088217fa624c99b843eeb54640de23b3414b14aa66d023805eb731066c"}, -] - -[[package]] -name = "packaging" -version = "24.1" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, -] - -[[package]] -name = "pandas" -version = "2.2.3" -description = "Powerful data structures for data analysis, time series, and statistics" -optional = false -python-versions = ">=3.9" -files = [ - {file = "pandas-2.2.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1948ddde24197a0f7add2bdc4ca83bf2b1ef84a1bc8ccffd95eda17fd836ecb5"}, - {file = "pandas-2.2.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:381175499d3802cde0eabbaf6324cce0c4f5d52ca6f8c377c29ad442f50f6348"}, - {file = "pandas-2.2.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d9c45366def9a3dd85a6454c0e7908f2b3b8e9c138f5dc38fed7ce720d8453ed"}, - {file = "pandas-2.2.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86976a1c5b25ae3f8ccae3a5306e443569ee3c3faf444dfd0f41cda24667ad57"}, - {file = "pandas-2.2.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b8661b0238a69d7aafe156b7fa86c44b881387509653fdf857bebc5e4008ad42"}, - {file = "pandas-2.2.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:37e0aced3e8f539eccf2e099f65cdb9c8aa85109b0be6e93e2baff94264bdc6f"}, - {file = "pandas-2.2.3-cp310-cp310-win_amd64.whl", hash = "sha256:56534ce0746a58afaf7942ba4863e0ef81c9c50d3f0ae93e9497d6a41a057645"}, - {file = "pandas-2.2.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:66108071e1b935240e74525006034333f98bcdb87ea116de573a6a0dccb6c039"}, - {file = "pandas-2.2.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7c2875855b0ff77b2a64a0365e24455d9990730d6431b9e0ee18ad8acee13dbd"}, - {file = "pandas-2.2.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cd8d0c3be0515c12fed0bdbae072551c8b54b7192c7b1fda0ba56059a0179698"}, - {file = "pandas-2.2.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c124333816c3a9b03fbeef3a9f230ba9a737e9e5bb4060aa2107a86cc0a497fc"}, - {file = "pandas-2.2.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:63cc132e40a2e084cf01adf0775b15ac515ba905d7dcca47e9a251819c575ef3"}, - {file = "pandas-2.2.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:29401dbfa9ad77319367d36940cd8a0b3a11aba16063e39632d98b0e931ddf32"}, - {file = "pandas-2.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:3fc6873a41186404dad67245896a6e440baacc92f5b716ccd1bc9ed2995ab2c5"}, - {file = "pandas-2.2.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b1d432e8d08679a40e2a6d8b2f9770a5c21793a6f9f47fdd52c5ce1948a5a8a9"}, - {file = "pandas-2.2.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a5a1595fe639f5988ba6a8e5bc9649af3baf26df3998a0abe56c02609392e0a4"}, - {file = "pandas-2.2.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5de54125a92bb4d1c051c0659e6fcb75256bf799a732a87184e5ea503965bce3"}, - {file = "pandas-2.2.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fffb8ae78d8af97f849404f21411c95062db1496aeb3e56f146f0355c9989319"}, - {file = "pandas-2.2.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6dfcb5ee8d4d50c06a51c2fffa6cff6272098ad6540aed1a76d15fb9318194d8"}, - {file = "pandas-2.2.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:062309c1b9ea12a50e8ce661145c6aab431b1e99530d3cd60640e255778bd43a"}, - {file = "pandas-2.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:59ef3764d0fe818125a5097d2ae867ca3fa64df032331b7e0917cf5d7bf66b13"}, - {file = "pandas-2.2.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f00d1345d84d8c86a63e476bb4955e46458b304b9575dcf71102b5c705320015"}, - {file = "pandas-2.2.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3508d914817e153ad359d7e069d752cdd736a247c322d932eb89e6bc84217f28"}, - {file = "pandas-2.2.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:22a9d949bfc9a502d320aa04e5d02feab689d61da4e7764b62c30b991c42c5f0"}, - {file = "pandas-2.2.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3a255b2c19987fbbe62a9dfd6cff7ff2aa9ccab3fc75218fd4b7530f01efa24"}, - {file = "pandas-2.2.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:800250ecdadb6d9c78eae4990da62743b857b470883fa27f652db8bdde7f6659"}, - {file = "pandas-2.2.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6374c452ff3ec675a8f46fd9ab25c4ad0ba590b71cf0656f8b6daa5202bca3fb"}, - {file = "pandas-2.2.3-cp313-cp313-win_amd64.whl", hash = "sha256:61c5ad4043f791b61dd4752191d9f07f0ae412515d59ba8f005832a532f8736d"}, - {file = "pandas-2.2.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:3b71f27954685ee685317063bf13c7709a7ba74fc996b84fc6821c59b0f06468"}, - {file = "pandas-2.2.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:38cf8125c40dae9d5acc10fa66af8ea6fdf760b2714ee482ca691fc66e6fcb18"}, - {file = "pandas-2.2.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ba96630bc17c875161df3818780af30e43be9b166ce51c9a18c1feae342906c2"}, - {file = "pandas-2.2.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1db71525a1538b30142094edb9adc10be3f3e176748cd7acc2240c2f2e5aa3a4"}, - {file = "pandas-2.2.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:15c0e1e02e93116177d29ff83e8b1619c93ddc9c49083f237d4312337a61165d"}, - {file = "pandas-2.2.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ad5b65698ab28ed8d7f18790a0dc58005c7629f227be9ecc1072aa74c0c1d43a"}, - {file = "pandas-2.2.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bc6b93f9b966093cb0fd62ff1a7e4c09e6d546ad7c1de191767baffc57628f39"}, - {file = "pandas-2.2.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5dbca4c1acd72e8eeef4753eeca07de9b1db4f398669d5994086f788a5d7cc30"}, - {file = "pandas-2.2.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8cd6d7cc958a3910f934ea8dbdf17b2364827bb4dafc38ce6eef6bb3d65ff09c"}, - {file = "pandas-2.2.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99df71520d25fade9db7c1076ac94eb994f4d2673ef2aa2e86ee039b6746d20c"}, - {file = "pandas-2.2.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:31d0ced62d4ea3e231a9f228366919a5ea0b07440d9d4dac345376fd8e1477ea"}, - {file = "pandas-2.2.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7eee9e7cea6adf3e3d24e304ac6b8300646e2a5d1cd3a3c2abed9101b0846761"}, - {file = "pandas-2.2.3-cp39-cp39-win_amd64.whl", hash = "sha256:4850ba03528b6dd51d6c5d273c46f183f39a9baf3f0143e566b89450965b105e"}, - {file = "pandas-2.2.3.tar.gz", hash = "sha256:4f18ba62b61d7e192368b84517265a99b4d7ee8912f8708660fb4a366cc82667"}, -] - -[package.dependencies] -numpy = {version = ">=1.26.0", markers = "python_version >= \"3.12\""} -python-dateutil = ">=2.8.2" -pytz = ">=2020.1" -tzdata = ">=2022.7" - -[package.extras] -all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"] -aws = ["s3fs (>=2022.11.0)"] -clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"] -compression = ["zstandard (>=0.19.0)"] -computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"] -consortium-standard = ["dataframe-api-compat (>=0.1.7)"] -excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"] -feather = ["pyarrow (>=10.0.1)"] -fss = ["fsspec (>=2022.11.0)"] -gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"] -hdf5 = ["tables (>=3.8.0)"] -html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"] -mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"] -output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"] -parquet = ["pyarrow (>=10.0.1)"] -performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"] -plot = ["matplotlib (>=3.6.3)"] -postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"] -pyarrow = ["pyarrow (>=10.0.1)"] -spss = ["pyreadstat (>=1.2.0)"] -sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"] -test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] -xml = ["lxml (>=4.9.2)"] - -[[package]] -name = "pathspec" -version = "0.12.1" -description = "Utility library for gitignore style pattern matching of file paths." -optional = false -python-versions = ">=3.8" -files = [ - {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, - {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, -] - -[[package]] -name = "platformdirs" -version = "4.3.6" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." -optional = false -python-versions = ">=3.8" -files = [ - {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, - {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, -] - -[package.extras] -docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] -type = ["mypy (>=1.11.2)"] - -[[package]] -name = "pluggy" -version = "1.5.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, - {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - -[[package]] -name = "pydantic" -version = "2.9.2" -description = "Data validation using Python type hints" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, - {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, -] - -[package.dependencies] -annotated-types = ">=0.6.0" -pydantic-core = "2.23.4" -typing-extensions = {version = ">=4.6.1", markers = "python_version < \"3.13\""} - -[package.extras] -email = ["email-validator (>=2.0.0)"] -timezone = ["tzdata"] - -[[package]] -name = "pydantic-core" -version = "2.23.4" -description = "Core functionality for Pydantic validation and serialization" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"}, - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071"}, - {file = "pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119"}, - {file = "pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64"}, - {file = "pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f"}, - {file = "pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"}, - {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"}, - {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f"}, - {file = "pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769"}, - {file = "pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb"}, - {file = "pydantic_core-2.23.4-cp38-none-win32.whl", hash = "sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6"}, - {file = "pydantic_core-2.23.4-cp38-none-win_amd64.whl", hash = "sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605"}, - {file = "pydantic_core-2.23.4-cp39-none-win32.whl", hash = "sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6"}, - {file = "pydantic_core-2.23.4-cp39-none-win_amd64.whl", hash = "sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e"}, - {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"}, -] - -[package.dependencies] -typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" - -[[package]] -name = "pytest" -version = "8.3.3" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"}, - {file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "sys_platform == \"win32\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=1.5,<2" - -[package.extras] -dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] - -[[package]] -name = "python-dateutil" -version = "2.9.0.post0" -description = "Extensions to the standard Python datetime module" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -files = [ - {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, - {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, -] - -[package.dependencies] -six = ">=1.5" - -[[package]] -name = "pytz" -version = "2024.2" -description = "World timezone definitions, modern and historical" -optional = false -python-versions = "*" -files = [ - {file = "pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725"}, - {file = "pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a"}, -] - -[[package]] -name = "pyyaml" -version = "6.0.2" -description = "YAML parser and emitter for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, - {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, - {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, - {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, - {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, - {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, - {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, - {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, - {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, - {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, - {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, - {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, - {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, - {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, - {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, - {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, - {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, -] - -[[package]] -name = "requests" -version = "2.32.3" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.8" -files = [ - {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, - {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, -] - -[package.dependencies] -certifi = ">=2017.4.17" -charset-normalizer = ">=2,<4" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "s3transfer" -version = "0.10.3" -description = "An Amazon S3 Transfer Manager" -optional = false -python-versions = ">=3.8" -files = [ - {file = "s3transfer-0.10.3-py3-none-any.whl", hash = "sha256:263ed587a5803c6c708d3ce44dc4dfedaab4c1a32e8329bab818933d79ddcf5d"}, - {file = "s3transfer-0.10.3.tar.gz", hash = "sha256:4f50ed74ab84d474ce614475e0b8d5047ff080810aac5d01ea25231cfc944b0c"}, -] - -[package.dependencies] -botocore = ">=1.33.2,<2.0a.0" - -[package.extras] -crt = ["botocore[crt] (>=1.33.2,<2.0a.0)"] - -[[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] - -[[package]] -name = "sniffio" -version = "1.3.1" -description = "Sniff out which async library your code is running under" -optional = false -python-versions = ">=3.7" -files = [ - {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, - {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, -] - -[[package]] -name = "tokenizers" -version = "0.20.1" -description = "" -optional = false -python-versions = ">=3.7" -files = [ - {file = "tokenizers-0.20.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:439261da7c0a5c88bda97acb284d49fbdaf67e9d3b623c0bfd107512d22787a9"}, - {file = "tokenizers-0.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:03dae629d99068b1ea5416d50de0fea13008f04129cc79af77a2a6392792d93c"}, - {file = "tokenizers-0.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b61f561f329ffe4b28367798b89d60c4abf3f815d37413b6352bc6412a359867"}, - {file = "tokenizers-0.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ec870fce1ee5248a10be69f7a8408a234d6f2109f8ea827b4f7ecdbf08c9fd15"}, - {file = "tokenizers-0.20.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d388d1ea8b7447da784e32e3b86a75cce55887e3b22b31c19d0b186b1c677800"}, - {file = "tokenizers-0.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:299c85c1d21135bc01542237979bf25c32efa0d66595dd0069ae259b97fb2dbe"}, - {file = "tokenizers-0.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e96f6c14c9752bb82145636b614d5a78e9cde95edfbe0a85dad0dd5ddd6ec95c"}, - {file = "tokenizers-0.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc9e95ad49c932b80abfbfeaf63b155761e695ad9f8a58c52a47d962d76e310f"}, - {file = "tokenizers-0.20.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:f22dee205329a636148c325921c73cf3e412e87d31f4d9c3153b302a0200057b"}, - {file = "tokenizers-0.20.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a2ffd9a8895575ac636d44500c66dffaef133823b6b25067604fa73bbc5ec09d"}, - {file = "tokenizers-0.20.1-cp310-none-win32.whl", hash = "sha256:2847843c53f445e0f19ea842a4e48b89dd0db4e62ba6e1e47a2749d6ec11f50d"}, - {file = "tokenizers-0.20.1-cp310-none-win_amd64.whl", hash = "sha256:f9aa93eacd865f2798b9e62f7ce4533cfff4f5fbd50c02926a78e81c74e432cd"}, - {file = "tokenizers-0.20.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:4a717dcb08f2dabbf27ae4b6b20cbbb2ad7ed78ce05a829fae100ff4b3c7ff15"}, - {file = "tokenizers-0.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3f84dad1ff1863c648d80628b1b55353d16303431283e4efbb6ab1af56a75832"}, - {file = "tokenizers-0.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:929c8f3afa16a5130a81ab5079c589226273ec618949cce79b46d96e59a84f61"}, - {file = "tokenizers-0.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d10766473954397e2d370f215ebed1cc46dcf6fd3906a2a116aa1d6219bfedc3"}, - {file = "tokenizers-0.20.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9300fac73ddc7e4b0330acbdda4efaabf74929a4a61e119a32a181f534a11b47"}, - {file = "tokenizers-0.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0ecaf7b0e39caeb1aa6dd6e0975c405716c82c1312b55ac4f716ef563a906969"}, - {file = "tokenizers-0.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5170be9ec942f3d1d317817ced8d749b3e1202670865e4fd465e35d8c259de83"}, - {file = "tokenizers-0.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef3f1ae08fa9aea5891cbd69df29913e11d3841798e0bfb1ff78b78e4e7ea0a4"}, - {file = "tokenizers-0.20.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ee86d4095d3542d73579e953c2e5e07d9321af2ffea6ecc097d16d538a2dea16"}, - {file = "tokenizers-0.20.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:86dcd08da163912e17b27bbaba5efdc71b4fbffb841530fdb74c5707f3c49216"}, - {file = "tokenizers-0.20.1-cp311-none-win32.whl", hash = "sha256:9af2dc4ee97d037bc6b05fa4429ddc87532c706316c5e11ce2f0596dfcfa77af"}, - {file = "tokenizers-0.20.1-cp311-none-win_amd64.whl", hash = "sha256:899152a78b095559c287b4c6d0099469573bb2055347bb8154db106651296f39"}, - {file = "tokenizers-0.20.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:407ab666b38e02228fa785e81f7cf79ef929f104bcccf68a64525a54a93ceac9"}, - {file = "tokenizers-0.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2f13a2d16032ebc8bd812eb8099b035ac65887d8f0c207261472803b9633cf3e"}, - {file = "tokenizers-0.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e98eee4dca22849fbb56a80acaa899eec5b72055d79637dd6aa15d5e4b8628c9"}, - {file = "tokenizers-0.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:47c1bcdd61e61136087459cb9e0b069ff23b5568b008265e5cbc927eae3387ce"}, - {file = "tokenizers-0.20.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:128c1110e950534426e2274837fc06b118ab5f2fa61c3436e60e0aada0ccfd67"}, - {file = "tokenizers-0.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2e2d47a819d2954f2c1cd0ad51bb58ffac6f53a872d5d82d65d79bf76b9896d"}, - {file = "tokenizers-0.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bdd67a0e3503a9a7cf8bc5a4a49cdde5fa5bada09a51e4c7e1c73900297539bd"}, - {file = "tokenizers-0.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:689b93d2e26d04da337ac407acec8b5d081d8d135e3e5066a88edd5bdb5aff89"}, - {file = "tokenizers-0.20.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0c6a796ddcd9a19ad13cf146997cd5895a421fe6aec8fd970d69f9117bddb45c"}, - {file = "tokenizers-0.20.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3ea919687aa7001a8ff1ba36ac64f165c4e89035f57998fa6cedcfd877be619d"}, - {file = "tokenizers-0.20.1-cp312-none-win32.whl", hash = "sha256:6d3ac5c1f48358ffe20086bf065e843c0d0a9fce0d7f0f45d5f2f9fba3609ca5"}, - {file = "tokenizers-0.20.1-cp312-none-win_amd64.whl", hash = "sha256:b0874481aea54a178f2bccc45aa2d0c99cd3f79143a0948af6a9a21dcc49173b"}, - {file = "tokenizers-0.20.1-cp37-cp37m-macosx_10_12_x86_64.whl", hash = "sha256:96af92e833bd44760fb17f23f402e07a66339c1dcbe17d79a9b55bb0cc4f038e"}, - {file = "tokenizers-0.20.1-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:65f34e5b731a262dfa562820818533c38ce32a45864437f3d9c82f26c139ca7f"}, - {file = "tokenizers-0.20.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:17f98fccb5c12ab1ce1f471731a9cd86df5d4bd2cf2880c5a66b229802d96145"}, - {file = "tokenizers-0.20.1-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b8c0fc3542cf9370bf92c932eb71bdeb33d2d4aeeb4126d9fd567b60bd04cb30"}, - {file = "tokenizers-0.20.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b39356df4575d37f9b187bb623aab5abb7b62c8cb702867a1768002f814800c"}, - {file = "tokenizers-0.20.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfdad27b0e50544f6b838895a373db6114b85112ba5c0cefadffa78d6daae563"}, - {file = "tokenizers-0.20.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:094663dd0e85ee2e573126918747bdb40044a848fde388efb5b09d57bc74c680"}, - {file = "tokenizers-0.20.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14e4cf033a2aa207d7ac790e91adca598b679999710a632c4a494aab0fc3a1b2"}, - {file = "tokenizers-0.20.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:9310951c92c9fb91660de0c19a923c432f110dbfad1a2d429fbc44fa956bf64f"}, - {file = "tokenizers-0.20.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:05e41e302c315bd2ed86c02e917bf03a6cf7d2f652c9cee1a0eb0d0f1ca0d32c"}, - {file = "tokenizers-0.20.1-cp37-none-win32.whl", hash = "sha256:212231ab7dfcdc879baf4892ca87c726259fa7c887e1688e3f3cead384d8c305"}, - {file = "tokenizers-0.20.1-cp37-none-win_amd64.whl", hash = "sha256:896195eb9dfdc85c8c052e29947169c1fcbe75a254c4b5792cdbd451587bce85"}, - {file = "tokenizers-0.20.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:741fb22788482d09d68e73ece1495cfc6d9b29a06c37b3df90564a9cfa688e6d"}, - {file = "tokenizers-0.20.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:10be14ebd8082086a342d969e17fc2d6edc856c59dbdbddd25f158fa40eaf043"}, - {file = "tokenizers-0.20.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:514cf279b22fa1ae0bc08e143458c74ad3b56cd078b319464959685a35c53d5e"}, - {file = "tokenizers-0.20.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a647c5b7cb896d6430cf3e01b4e9a2d77f719c84cefcef825d404830c2071da2"}, - {file = "tokenizers-0.20.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7cdf379219e1e1dd432091058dab325a2e6235ebb23e0aec8d0508567c90cd01"}, - {file = "tokenizers-0.20.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ba72260449e16c4c2f6f3252823b059fbf2d31b32617e582003f2b18b415c39"}, - {file = "tokenizers-0.20.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:910b96ed87316e4277b23c7bcaf667ce849c7cc379a453fa179e7e09290eeb25"}, - {file = "tokenizers-0.20.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e53975a6694428a0586534cc1354b2408d4e010a3103117f617cbb550299797c"}, - {file = "tokenizers-0.20.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:07c4b7be58da142b0730cc4e5fd66bb7bf6f57f4986ddda73833cd39efef8a01"}, - {file = "tokenizers-0.20.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b605c540753e62199bf15cf69c333e934077ef2350262af2ccada46026f83d1c"}, - {file = "tokenizers-0.20.1-cp38-none-win32.whl", hash = "sha256:88b3bc76ab4db1ab95ead623d49c95205411e26302cf9f74203e762ac7e85685"}, - {file = "tokenizers-0.20.1-cp38-none-win_amd64.whl", hash = "sha256:d412a74cf5b3f68a90c615611a5aa4478bb303d1c65961d22db45001df68afcb"}, - {file = "tokenizers-0.20.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a25dcb2f41a0a6aac31999e6c96a75e9152fa0127af8ece46c2f784f23b8197a"}, - {file = "tokenizers-0.20.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a12c3cebb8c92e9c35a23ab10d3852aee522f385c28d0b4fe48c0b7527d59762"}, - {file = "tokenizers-0.20.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02e18da58cf115b7c40de973609c35bde95856012ba42a41ee919c77935af251"}, - {file = "tokenizers-0.20.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f326a1ac51ae909b9760e34671c26cd0dfe15662f447302a9d5bb2d872bab8ab"}, - {file = "tokenizers-0.20.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0b4872647ea6f25224e2833b044b0b19084e39400e8ead3cfe751238b0802140"}, - {file = "tokenizers-0.20.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce6238a3311bb8e4c15b12600927d35c267b92a52c881ef5717a900ca14793f7"}, - {file = "tokenizers-0.20.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57b7a8880b208866508b06ce365dc631e7a2472a3faa24daa430d046fb56c885"}, - {file = "tokenizers-0.20.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a908c69c2897a68f412aa05ba38bfa87a02980df70f5a72fa8490479308b1f2d"}, - {file = "tokenizers-0.20.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:da1001aa46f4490099c82e2facc4fbc06a6a32bf7de3918ba798010954b775e0"}, - {file = "tokenizers-0.20.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:42c097390e2f0ed0a5c5d569e6669dd4e9fff7b31c6a5ce6e9c66a61687197de"}, - {file = "tokenizers-0.20.1-cp39-none-win32.whl", hash = "sha256:3d4d218573a3d8b121a1f8c801029d70444ffb6d8f129d4cca1c7b672ee4a24c"}, - {file = "tokenizers-0.20.1-cp39-none-win_amd64.whl", hash = "sha256:37d1e6f616c84fceefa7c6484a01df05caf1e207669121c66213cb5b2911d653"}, - {file = "tokenizers-0.20.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:48689da7a395df41114f516208d6550e3e905e1239cc5ad386686d9358e9cef0"}, - {file = "tokenizers-0.20.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:712f90ea33f9bd2586b4a90d697c26d56d0a22fd3c91104c5858c4b5b6489a79"}, - {file = "tokenizers-0.20.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:359eceb6a620c965988fc559cebc0a98db26713758ec4df43fb76d41486a8ed5"}, - {file = "tokenizers-0.20.1-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d3caf244ce89d24c87545aafc3448be15870096e796c703a0d68547187192e1"}, - {file = "tokenizers-0.20.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b03cf8b9a32254b1bf8a305fb95c6daf1baae0c1f93b27f2b08c9759f41dee"}, - {file = "tokenizers-0.20.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:218e5a3561561ea0f0ef1559c6d95b825308dbec23fb55b70b92589e7ff2e1e8"}, - {file = "tokenizers-0.20.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f40df5e0294a95131cc5f0e0eb91fe86d88837abfbee46b9b3610b09860195a7"}, - {file = "tokenizers-0.20.1-pp37-pypy37_pp73-macosx_10_12_x86_64.whl", hash = "sha256:08aaa0d72bb65058e8c4b0455f61b840b156c557e2aca57627056624c3a93976"}, - {file = "tokenizers-0.20.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:998700177b45f70afeb206ad22c08d9e5f3a80639dae1032bf41e8cbc4dada4b"}, - {file = "tokenizers-0.20.1-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62f7fbd3c2c38b179556d879edae442b45f68312019c3a6013e56c3947a4e648"}, - {file = "tokenizers-0.20.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31e87fca4f6bbf5cc67481b562147fe932f73d5602734de7dd18a8f2eee9c6dd"}, - {file = "tokenizers-0.20.1-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:956f21d359ae29dd51ca5726d2c9a44ffafa041c623f5aa33749da87cfa809b9"}, - {file = "tokenizers-0.20.1-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:1fbbaf17a393c78d8aedb6a334097c91cb4119a9ced4764ab8cfdc8d254dc9f9"}, - {file = "tokenizers-0.20.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ebe63e31f9c1a970c53866d814e35ec2ec26fda03097c486f82f3891cee60830"}, - {file = "tokenizers-0.20.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:81970b80b8ac126910295f8aab2d7ef962009ea39e0d86d304769493f69aaa1e"}, - {file = "tokenizers-0.20.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:130e35e76f9337ed6c31be386e75d4925ea807055acf18ca1a9b0eec03d8fe23"}, - {file = "tokenizers-0.20.1-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cd28a8614f5c82a54ab2463554e84ad79526c5184cf4573bbac2efbbbcead457"}, - {file = "tokenizers-0.20.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9041ee665d0fa7f5c4ccf0f81f5e6b7087f797f85b143c094126fc2611fec9d0"}, - {file = "tokenizers-0.20.1-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:62eb9daea2a2c06bcd8113a5824af8ef8ee7405d3a71123ba4d52c79bb3d9f1a"}, - {file = "tokenizers-0.20.1-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f861889707b54a9ab1204030b65fd6c22bdd4a95205deec7994dc22a8baa2ea4"}, - {file = "tokenizers-0.20.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:89d5c337d74ea6e5e7dc8af124cf177be843bbb9ca6e58c01f75ea103c12c8a9"}, - {file = "tokenizers-0.20.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:0b7f515c83397e73292accdbbbedc62264e070bae9682f06061e2ddce67cacaf"}, - {file = "tokenizers-0.20.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e0305fc1ec6b1e5052d30d9c1d5c807081a7bd0cae46a33d03117082e91908c"}, - {file = "tokenizers-0.20.1-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5dc611e6ac0fa00a41de19c3bf6391a05ea201d2d22b757d63f5491ec0e67faa"}, - {file = "tokenizers-0.20.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c5ffe0d7f7bfcfa3b2585776ecf11da2e01c317027c8573c78ebcb8985279e23"}, - {file = "tokenizers-0.20.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:e7edb8ec12c100d5458d15b1e47c0eb30ad606a05641f19af7563bc3d1608c14"}, - {file = "tokenizers-0.20.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:de291633fb9303555793cc544d4a86e858da529b7d0b752bcaf721ae1d74b2c9"}, - {file = "tokenizers-0.20.1.tar.gz", hash = "sha256:84edcc7cdeeee45ceedb65d518fffb77aec69311c9c8e30f77ad84da3025f002"}, -] - -[package.dependencies] -huggingface-hub = ">=0.16.4,<1.0" - -[package.extras] -dev = ["tokenizers[testing]"] -docs = ["setuptools-rust", "sphinx", "sphinx-rtd-theme"] -testing = ["black (==22.3)", "datasets", "numpy", "pytest", "requests", "ruff"] - -[[package]] -name = "tqdm" -version = "4.66.5" -description = "Fast, Extensible Progress Meter" -optional = false -python-versions = ">=3.7" -files = [ - {file = "tqdm-4.66.5-py3-none-any.whl", hash = "sha256:90279a3770753eafc9194a0364852159802111925aa30eb3f9d85b0e805ac7cd"}, - {file = "tqdm-4.66.5.tar.gz", hash = "sha256:e1020aef2e5096702d8a025ac7d16b1577279c9d63f8375b63083e9a5f0fcbad"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - -[package.extras] -dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] -notebook = ["ipywidgets (>=6)"] -slack = ["slack-sdk"] -telegram = ["requests"] - -[[package]] -name = "typing-extensions" -version = "4.12.2" -description = "Backported and Experimental Type Hints for Python 3.8+" -optional = false -python-versions = ">=3.8" -files = [ - {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, - {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, -] - -[[package]] -name = "tzdata" -version = "2024.2" -description = "Provider of IANA time zone data" -optional = false -python-versions = ">=2" -files = [ - {file = "tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd"}, - {file = "tzdata-2024.2.tar.gz", hash = "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc"}, -] - -[[package]] -name = "urllib3" -version = "2.2.3" -description = "HTTP library with thread-safe connection pooling, file post, and more." -optional = false -python-versions = ">=3.8" -files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, -] - -[package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -h2 = ["h2 (>=4,<5)"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] - -[metadata] -lock-version = "2.0" -python-versions = "3.12.7" -content-hash = "0cd33a9b851c9004033ffac02c29d9557049e46ad8fc96afacd55540cc90aa22" diff --git a/fieldExtraction/pyproject.toml b/fieldExtraction/pyproject.toml deleted file mode 100644 index 402291b..0000000 --- a/fieldExtraction/pyproject.toml +++ /dev/null @@ -1,42 +0,0 @@ -[tool.poetry] -name = "field-extraction" -version = "0.1.0" -description = "" -authors = ["Michael McGuinness "] -readme = "README.md" -package-mode = false - -[tool.poetry.dependencies] -python = "3.12.7" -anthropic = "0.36.0" -boto3 = "1.35.37" -botocore = "1.35.37" -pandas = "2.2.3" -requests = "2.32.3" - - -[tool.poetry.group.dev.dependencies] -black = "^24.10.0" -mypy = "^1.12.0" - - -[tool.poetry.group.test.dependencies] -pytest = "^8.3.3" - -[build-system] -requires = ["poetry-core"] -build-backend = "poetry.core.masonry.api" - -[tool.black] -line-length = 88 -target-version = ['py312'] - -[tool.mypy] -disable_error_code = ["import-untyped","assignment"] -install_types = true -non_interactive = true - -[tool.pytest.ini_options] -testpaths = [ - "tests" -] \ No newline at end of file diff --git a/fieldExtraction/src/bottom_up_funcs.py b/fieldExtraction/src/bottom_up_funcs.py deleted file mode 100644 index ad40dd0..0000000 --- a/fieldExtraction/src/bottom_up_funcs.py +++ /dev/null @@ -1,240 +0,0 @@ -import dict_operations -import postprocess_funcs -import prompts -import config -import claude_funcs -import utils - -import difflib - - -def run_bottom_up(filename, text_dict): - """ - Processes the text of a document using a two-tiered Bottom Up approach to extract key financial and operational information. - - This function first runs BOTTOM_UP_PRIMARY and BOTTOM_UP_SECONDARY prompts, then processes these initial results to further - refine and structure them into a dictionary form. - - Parameters: - filename (str): The name of the file being processed, used to tag output data. - text_dict (dict): A dictionary of text keyed by page numbers that contains the content to be analyzed. - - Returns: - list of dict: A list of dictionaries with each dictionary containing refined and structured information - from both primary and secondary Bottom Up analyses, all tagged with the filename. - """ - - # Bottom Up Primary - SERVICE, REIMBURSEMENT_FLAT_FEE, REIMBURSEMENT_RATE, METHODOLOGY - answer_strings = run_bottom_up_primary(text_dict, 8000) - answer_dicts = dict_operations.primary_string_to_dict(answer_strings, filename) - answer_dicts_filtered = postprocess_funcs.filter_service_column(answer_dicts) - - # Bottom Up Secondary - results_dicts = run_bottom_up_secondary(answer_dicts_filtered, text_dict, 8000) - - # Add _PG columns - results_dicts = postprocess_funcs.add_PG_columns(results_dicts) - - # Add Filename - for d in results_dicts: - d["Filename"] = filename - - return results_dicts # List of dictionaries - - -def run_bottom_up_primary(text_dict, tokens): - """ - Executes the primary Bottom Up processing for pages that contain reimbursement terms. - - This function scans through a dictionary of page texts, identifies pages containing reimbursement terms, - and processes those pages using Claude to extract relevant information. - - Parameters: - text_dict (dict): A dictionary containing text content of documents keyed by page numbers. - tokens (int): The maximum number of tokens to use in the language model invocation for generating the response. - - Returns: - dict: A dictionary where each key is a page number and the value is the response from the language model. - """ - # chunk_dict = preprocess.chunk_text(text_dict) - answer_dict = {} - # for page_number in chunk_dict.keys(): - # if '%' in chunk_dict[page_number] or '$' in chunk_dict[page_number]: - # prompt = prompts.BOTTOM_UP_PRIMARY(chunk_dict[page_number], config.CLIENT_NAME) - for page_number in text_dict.keys(): - if utils.contains_reimbursement(text_dict, page_number): - # Run Primary - prompt = prompts.BOTTOM_UP_PRIMARY( - text_dict[page_number], config.CLIENT_NAME - ) - answer = claude_funcs.invoke_claude_3(prompt, max_tokens=tokens) - answer_dict[page_number] = answer - return answer_dict - - -def run_bottom_up_secondary(answer_dicts, text_dict, tokens): - """ - Executes the secondary Bottom Up processing phase on the results obtained from the primary Bottom Up analysis. - - This function enhances the primary results with additional analyses based on configured conditions. Invokes - Claude 3 with tailored prompts to generate structured information that complements the initial results. - - Each piece of data processed possibly undergoes several rounds of checks and transformations, ensuring detailed and - comprehensive output. - - Parameters: - answer_dicts (list of dict): Initial processed data from the primary Bottom Up analysis. - text_dict (dict): Dictionary containing the original document text keyed by page numbers. - tokens (int): Token limit for language model invocations. - - Returns: - list of dict: A list of dictionaries containing enriched and finalized structured data from both the primary and - secondary analyses. - """ - # New rows for lesser of - temp_dicts = [] - for d in answer_dicts: - # Bottom Up Lesser - if config.RUN_LESSER: - lesser_object = run_bottom_up_lesser(d.copy(), text_dict.copy(), tokens) - temp_dicts.append(lesser_object[1]) # Add original object from d - if lesser_object[0]: - temp_dicts.append(lesser_object[0]) # If lesser, add lesser object - else: - temp_dicts.append(d) - - # Add additional fields to each row - final_dicts = [] - for d in temp_dicts: - if d is not None: - page_num = d["page_num"] - - # Bottom Up Methodology - if config.RUN_METHODOLOGY: - prompt = prompts.BOTTOM_UP_METHODOLOGY(d) - methodology_answer = claude_funcs.invoke_claude_3( - prompt, max_tokens=100 - ) - d["REIMBURSEMENT_METHODOLOGY"] = methodology_answer - - # # Bottom Up FS - if config.RUN_FS: - prompt = prompts.BOTTOM_UP_FS(d) - fs_answer = claude_funcs.invoke_claude_3( - prompt, model_id=config.MODEL_ID_CLAUDE3_HAIKU, max_tokens=tokens - ) - fs_dict = dict_operations.secondary_string_to_dict(fs_answer) - d.update(fs_dict) - - # # Bottom Up Exception/Escalator - if config.RUN_EXCEPTION: - prompt = prompts.BOTTOM_UP_EXCEPT_ESC(d, text_dict[page_num]) - exc_answer = claude_funcs.invoke_claude_3( - prompt, model_id=config.MODEL_ID_CLAUDE3_HAIKU, max_tokens=tokens - ) - exc_dict = dict_operations.secondary_string_to_dict(exc_answer) - d.update(exc_dict) - - # # Bottom Up Codes - if config.RUN_CODES: - prompt = prompts.BOTTOM_UP_CODES(d, text_dict[page_num]) - codes_answer = claude_funcs.invoke_claude_3(prompt, max_tokens=tokens) - codes_dict = dict_operations.secondary_string_to_dict(codes_answer) - d.update(codes_dict) - - final_dicts.append(d) - - return final_dicts - - -def run_bottom_up_lesser(d, text_dict, tokens=4000): - """ - Processes specific clauses or conditions within the document text, such as 'lesser of' or 'greater of', - using a language model to analyze and extract relevant data from the identified text segment. - - This function takes a dictionary representing initial results and a text dictionary, uses the page number from the initial - results to locate the relevant text, and generates a prompt for language model analysis. Based on the response, it - determines whether 'lesser of' or 'greater of' language is indicated, updates the results, and returns a new dictionary - for the updated data or retains the original if no such language is present. - - Parameters: - d (dict): A dictionary containing initial processing results from previous analyses, including a 'page_num' key. - text_dict (dict): A dictionary of text keyed by page numbers that contains the content to be analyzed. - tokens (int): Token limit for language model invocations, default set to 8000. - - Returns: - tuple: A tuple containing two dictionaries, the first for any identified 'lesser of' or 'greater of' data and the second - containing the original or updated data depending on the presence of such language. - """ - - prompt = prompts.BOTTOM_UP_LESSER(d, text_dict[d["page_num"]]) - lesser_of_answer = claude_funcs.invoke_claude_3(prompt, max_tokens=tokens) - lesser_of_dict_list = dict_operations.primary_string_to_dict( - {d["page_num"]: lesser_of_answer}, d["Filename"] - ) - # print(lesser_of_dict_list) - # If lesser of is Y - if len(lesser_of_dict_list) > 1: - lesser_of_dict = get_lesser_of_dict(lesser_of_dict_list, d) - else: - d["LESSER_OF_LANGUAGE_IND"] = "N" - d["GREATER_OF_LANGUAGE_IND"] = "N" - return ({}, d) - - lesser_of_dict["page_num"] = d["page_num"] - if ( - lesser_of_dict["LESSER_OF_LANGUAGE_IND"] == "Y" - or lesser_of_dict["GREATER_OF_LANGUAGE_IND"] == "Y" - ): - lesser_of_dict["SERVICE"] = d["SERVICE"] - return (lesser_of_dict, d) - else: - d["LESSER_OF_LANGUAGE_IND"] = "N" - d["GREATER_OF_LANGUAGE_IND"] = "N" - return ({}, d) - - -def get_least_similar(dict_list, original_dict, field): - # print(f"Running similarity for {field}") - - min_similarity = float("inf") - least_similar_dict = None - for dictionary in dict_list: - # Extract the methodology text - field_text = dictionary[field] - # print(f"Field text: {field_text}") - - # Compute similarity using difflib - similarity = difflib.SequenceMatcher( - None, str(field_text), str(original_dict[field]) - ).ratio() - # print(f"Simlarity: {similarity}") - - # If the similarity is less than the current minimum, update the minimum and the corresponding dictionary - if similarity < min_similarity: - min_similarity = similarity - least_similar_dict = dictionary - - return least_similar_dict - - -def get_lesser_of_dict(dict_list, original_dict): - - unique_rates = list({d["REIMBURSEMENT_RATE"] for d in dict_list}) - unique_fees = list({d["REIMBURSEMENT_FLAT_FEE"] for d in dict_list}) - - # If the rates are different, return the lesser of dict with a different rate than original - if len(unique_rates) > 1: - least_similar_dict = get_least_similar( - dict_list, original_dict, "REIMBURSEMENT_RATE" - ) - elif len(unique_fees) > 1: - least_similar_dict = get_least_similar( - dict_list, original_dict, "REIMBURSEMENT_FLAT_FEE" - ) - else: - least_similar_dict = get_least_similar( - dict_list, original_dict, "FULL_METHODOLOGY" - ) - - return least_similar_dict diff --git a/fieldExtraction/src/carveouts.py b/fieldExtraction/src/carveouts.py deleted file mode 100644 index 675cb88..0000000 --- a/fieldExtraction/src/carveouts.py +++ /dev/null @@ -1,163 +0,0 @@ -import pandas as pd -from difflib import SequenceMatcher -import re -import time - -import prompts -import claude_funcs - - -def get_closest_substring_match(val, valid_values): - """Returns the first match from valid_values using a case-insensitive substring match.""" - if pd.isna(val): - return None - val = val.strip().upper() - for valid_value in valid_values: - if valid_value.upper() in val: - return valid_value - return None - - -def get_best_carveout_from_claude(carveout_list, service): - print("using claude to get best carveout...") - prompt = f"Given the service '{service}', please choose the best matching carveout from the following list: {', '.join(carveout_list)}. ONLY SELECT ONE FROM THE LIST. DO NOT RETURN A SENTENCE" - while True: - try: - response = claude_funcs.invoke_claude_3(prompt, max_tokens=100) - return response.strip() - except Exception as e: - print(f"Error occurred: {e}. Waiting for 60 seconds before retrying...") - time.sleep(60) - - -def check_prov_type_similarity(prov_type, carveout): - print("checking similarity between prov_type and carveout with claude...") - prompt = f"Do the provider type '{prov_type}' and the carveout '{carveout}' mean the same thing or are they very similar? ONLY ANSWER WITH 'True' OR 'False'" - while True: - try: - response = claude_funcs.invoke_claude_3(prompt, max_tokens=10) - return response.strip() - except Exception as e: - print(f"Error occurred: {e}. Waiting for 60 seconds before retrying...") - time.sleep(60) - - -def label_services(filepath, carveout_list, output_filepath): - # Read the CSV file - df = pd.read_csv(filepath) - - # Select the first 50 rows of the DataFrame - df = df.head(500) - - # Define primary service terms - primary_terms = [ - "Covered Services", - "Inpatient Services", - "Outpatient Services", - "Physician Services", - "Inpatient", - "Outpatient", - "Physician", - "Medical", - "Surgical", - "Diagnostic", - "Therapeutic", - ] - - # Initialize columns for the results - df["carveout_matched"] = "" - df["label"] = "" - df["IS_CARVEOUT"] = "" - - # Initialize a nested dictionary to track occurrences for each Filename and TD_LOB - occurrence_tracker = {} - - carveout_count = 0 - - # Iterate through the rows in the DataFrame - for index, row in df.iterrows(): - service = str(row["SERVICE"]) - prov_type = str(row["PROV_TYPE"]) if pd.notna(row["PROV_TYPE"]) else "" - td_lob = row["TD_LOB"] - filename = row["Filename"] - - # Initialize the nested dictionary for the filename and TD_LOB if not present - if filename not in occurrence_tracker: - occurrence_tracker[filename] = {} - if td_lob not in occurrence_tracker[filename]: - occurrence_tracker[filename][td_lob] = {term: 0 for term in primary_terms} - - # Check if the service is a primary or similar to a primary - primary = get_closest_substring_match(service, primary_terms) - if primary: - # Ensure the primary term is initialized in the occurrence tracker - if primary not in occurrence_tracker[filename][td_lob]: - occurrence_tracker[filename][td_lob][primary] = 0 - - # Determine the label based on the count of this primary term for the given Filename and TD_LOB - count = occurrence_tracker[filename][td_lob][primary] - if count == 0: - df.at[index, "label"] = "primary" - elif count == 1: - df.at[index, "label"] = "secondary" - elif count == 2: - df.at[index, "label"] = "tertiary" - else: - df.at[index, "label"] = "additional" - occurrence_tracker[filename][td_lob][primary] += 1 - df.at[index, "IS_CARVEOUT"] = "N" - else: - # If PROV_TYPE is blank, continue with carveout determination - best_carveout_response = get_best_carveout_from_claude( - carveout_list, service - ) - matched_carveout = best_carveout_response # Use the model response directly - - df.at[index, "carveout_matched"] = matched_carveout - - if matched_carveout: - # Check similarity between PROV_TYPE and carveout - prov_type_similarity_score = SequenceMatcher( - None, prov_type, matched_carveout - ).ratio() - if prov_type_similarity_score < 0.8: - prov_type_similarity = check_prov_type_similarity( - prov_type, matched_carveout - ) - else: - prov_type_similarity = "True" - - if re.search(r"\b(True|Yes)\b", prov_type_similarity, re.IGNORECASE): - if matched_carveout not in occurrence_tracker[filename][td_lob]: - print( - "claude returned a match between provider type and service" - ) - occurrence_tracker[filename][td_lob][matched_carveout] = 0 - count = occurrence_tracker[filename][td_lob][matched_carveout] - if count == 0: - df.at[index, "label"] = "primary" - elif count == 1: - df.at[index, "label"] = "secondary" - elif count == 2: - df.at[index, "label"] = "tertiary" - else: - df.at[index, "label"] = "additional" - occurrence_tracker[filename][td_lob][matched_carveout] += 1 - df.at[index, "IS_CARVEOUT"] = "N" - else: - df.at[index, "IS_CARVEOUT"] = "Y" - else: - df.at[index, "IS_CARVEOUT"] = "Y" - - carveout_count += 1 - - # Save the updated DataFrame to a new CSV file after every 10 carveouts - if carveout_count % 10 == 0: - df.to_csv(output_filepath, index=False) - print(f"Saved progress after processing {carveout_count} carveouts.") - - # Final save of the updated DataFrame to a new CSV file - df.to_csv(output_filepath, index=False) - - -label_services("service.csv", prompts.get_carveout_list(), "carveouts50.csv") diff --git a/fieldExtraction/src/categorization.py b/fieldExtraction/src/categorization.py deleted file mode 100644 index c19b8bd..0000000 --- a/fieldExtraction/src/categorization.py +++ /dev/null @@ -1,45 +0,0 @@ -import os - -import utils -import preprocess -import table_funcs - - -def contains_reimbursement(text_dict, page): - return ( - "%" in text_dict[page] - or "$" in text_dict[page] - or "percent" in text_dict[page].lower() - ) - - -directory_path = ( - "C:\\Users\\kminhas\\Documents\\Doczy\\doczy.ai\\data\\centene_healthnet" -) -# input_dict = utils.read_input(path=folder_path) -all_files: dict[str, str] = {} -reimbursement_count = 0 -total_count = 0 -# Walk through all directories and files in the directory -for root, dirs, files in os.walk(directory_path): - for file in files: - if file.endswith(".txt"): - # Construct full file path - file_path = os.path.join(root, file) - print(file_path) - try: - with open(file_path, "r", encoding="utf-8") as file_reader: - contract_text = file_reader.read() - if ( - "%" in contract_text - or "$" in contract_text - or "percent" in contract_text.lower() - ): - reimbursement_count += 1 - total_count += 1 - except: - continue - -print( - f"For Centene HealthNet, {reimbursement_count}/{total_count} files contain potential reimbursement terms." -) diff --git a/fieldExtraction/src/claude_funcs.py b/fieldExtraction/src/claude_funcs.py deleted file mode 100644 index 75abfac..0000000 --- a/fieldExtraction/src/claude_funcs.py +++ /dev/null @@ -1,83 +0,0 @@ -import json -import anthropic - -import config - - -# Claude calls -def invoke_claude_2(prompt, max_tokens): - """ - Invokes the Claude 2 language model with specified parameters to generate a response based on the input prompt. - - This function constructs a JSON request with the prompt, modified to include pre-defined introductory and concluding - sections for consistency. It specifies the token limit and other parameters to control the generation process. The function - sends the request to the model's runtime environment and processes the response to extract and return the generated text. - - Parameters: - prompt (str): The text prompt to be processed by the Claude 2 model, describing the information or question addressed. - max_tokens (int): The maximum number of tokens that the model is allowed to generate in its response. - - Returns: - str: The text generated by the Claude 2 model in response to the input prompt. - """ - body = json.dumps( - { - "prompt": anthropic.HUMAN_PROMPT + prompt + anthropic.AI_PROMPT, - "max_tokens_to_sample": max_tokens, - "temperature": 0.0, - "top_p": 1, - "top_k": 250, - "stop_sequences": [anthropic.HUMAN_PROMPT], - } - ) - - response = config.BEDROCK_RUNTIME.invoke_model( - body=body, - modelId=config.MODEL_ID_CLAUDE2, - accept="application/json", - contentType="application/json", - ) - - response_body = json.loads(response.get("body").read()) - - response_text = response_body["completion"] - return response_text - - -def invoke_claude_3(prompt, model_id=config.MODEL_ID_CLAUDE3_SONNET, max_tokens=0): - """ - Invokes the Claude 3 language model with specified parameters to generate a response based on the input prompt. - - This function constructs a JSON request with the prompt, modified to include pre-defined introductory and concluding - sections for consistency. It specifies the token limit and other parameters to control the generation process. The function - sends the request to the model's runtime environment and processes the response to extract and return the generated text. - - Parameters: - prompt (str): The text prompt to be processed by the Claude 2 model, describing the information or question addressed. - max_tokens (int): The maximum number of tokens that the model is allowed to generate in its response. - - Returns: - str: The text generated by the Claude 2 model in response to the input prompt. - """ - prompt = prompt - body = json.dumps( - { - "anthropic_version": "bedrock-2023-05-31", - "max_tokens": max_tokens, - "temperature": 0.0, - "messages": [ - {"role": "user", "content": [{"type": "text", "text": prompt}]} - ], - } - ) - - response = config.BEDROCK_RUNTIME.invoke_model( - body=body, - modelId=model_id, - accept="application/json", - contentType="application/json", - ) - - response_body = json.loads(response.get("body").read()) - - return response_body["content"][0]["text"] diff --git a/fieldExtraction/src/columns.py b/fieldExtraction/src/columns.py deleted file mode 100644 index 2481a11..0000000 --- a/fieldExtraction/src/columns.py +++ /dev/null @@ -1,104 +0,0 @@ -VALID_COLUMNS_TEMPLATE = { - "base": [ - "Filename", - "page_num", - "SERVICE", - "REIMBURSEMENT_FLAT_FEE", - "REIMBURSEMENT_RATE", - "FULL_METHODOLOGY", - "REIMBURSEMENT_METHODOLOGY", - "REIMBURSEMENT_FEE_SCHEDULE", - "REIMBURSEMENT_FEE_SCHEDULE_VERSION", - "LESSER_OF_LANGUAGE_IND", - "GREATER_OF_LANGUAGE_IND", - "CONTRACT_LOB", - "CONTRACT_NETWORK", - "PRODUCT", - "CONTRACT_PROGRAM", - "CONTRACT_MARKETPLACE_METAL_LEVEL", - "PROV_TYPE", - "REIMBURSEMENT_PROC_CODES", - "REIMBURSEMENT_PROC_CODE_MODIFIERS", - "REIMBURSEMENT_REVENUE_CODES", - "REIMBURSEMENT_STATUS_INDICATOR_CODES", - "REIMBURSEMENT_DIAG_CODES", - "REIMBURSEMENT_GROUPER_CODES", - "REIMBURSEMENT_GROUPER", - "REIMBURSEMENT_PLACEOFSERVICE_CODES", - "REIMBURSEMENT_ADMITTYPE_CODES", - "REIMBURSEMENT_EXCEPTION_IND", - "REIMBURSEMENT_DESCRIBE_EXCEPTION", - "RATE_ESCALATOR_IND", - "RATE_ESCALATOR_BASIS", - "RATE_ESCALATOR_YEARLY_PERCENT_INCREASE", - "Corrected_LOB", - "Corrected_PROGRAM", - "Corrected_NETWORK", - ], - "priorityhealth": [ - "Filename", - "SERVICE", - "SERVICE_PG", - "REIMBURSEMENT_FLAT_FEE", - "REIMBURSEMENT_FLAT_FEE_PG", - "REIMBURSEMENT_RATE", - "REIMBURSEMENT_RATE_PG", - "FULL_METHODOLOGY", - "FULL_METHODOLOGY_PG", - "REIMBURSEMENT_TIN", - "REIMBURSEMENT_TIN_PG", - "DATE_RANGE", - "DATE_RANGE_PG", - "REIMBURSEMENT_METHODOLOGY", - "REIMBURSEMENT_METHODOLOGY_PG", - "REIMBURSEMENT_FEE_SCHEDULE", - "REIMBURSEMENT_FEE_SCHEDULE_PG", - "REIMBURSEMENT_FEE_SCHEDULE_VERSION", - "REIMBURSEMENT_FEE_SCHEDULE_VERSION_PG", - "LESSER_OF_LANGUAGE_IND", - "LESSER_OF_LANGUAGE_IND_PG", - "GREATER_OF_LANGUAGE_IND", - "GREATER_OF_LANGUAGE_IND_PG", - "CONTRACT_LOB", - "CONTRACT_LOB_PG", - "CONTRACT_MARKETPLACE_METAL_LEVEL", - "CONTRACT_MARKETPLACE_METAL_LEVEL_PG", - "CONTRACT_NETWORK", - "CONTRACT_NETWORK_PG", - "PRODUCT", - "PRODUCT_PG", - "CONTRACT_PROGRAM", - "CONTRACT_PROGRAM_PG", - "REIMBURSEMENT_PROC_CODES", - "REIMBURSEMENT_PROC_CODES_PG", - "REIMBURSEMENT_PROC_CODE_MODIFIERS", - "REIMBURSEMENT_PROC_CODE_MODIFIERS_PG", - "REIMBURSEMENT_REVENUE_CODES", - "REIMBURSEMENT_REVENUE_CODES_PG", - "REIMBURSEMENT_STATUS_INDICATOR_CODES", - "REIMBURSEMENT_STATUS_INDICATOR_CODES_PG", - "REIMBURSEMENT_DIAG_CODES", - "REIMBURSEMENT_DIAG_CODES_PG", - "REIMBURSEMENT_GROUPER_CODES", - "REIMBURSEMENT_GROUPER_CODES_PG", - "REIMBURSEMENT_GROUPER", - "REIMBURSEMENT_GROUPER_PG", - "REIMBURSEMENT_PLACEOFSERVICE_CODES", - "REIMBURSEMENT_PLACEOFSERVICE_CODES_PG", - "REIMBURSEMENT_ADMITTYPE_CODES", - "REIMBURSEMENT_ADMITTYPE_CODES_PG", - "REIMBURSEMENT_EXCEPTION_IND", - "REIMBURSEMENT_EXCEPTION_IND_PG", - "REIMBURSEMENT_DESCRIBE_EXCEPTION", - "REIMBURSEMENT_DESCRIBE_EXCEPTION_PG", - "RATE_ESCALATOR_IND", - "RATE_ESCALATOR_IND_PG", - "RATE_ESCALATOR_BASIS", - "RATE_ESCALATOR_BASIS_PG", - "RATE_ESCALATOR_YEARLY_PERCENT_INCREASE", - "RATE_ESCALATOR_YEARLY_PERCENT_INCREASE_PG", - "Corrected_LOB", - "Corrected_PROGRAM", - "Corrected_NETWORK", - ], -} diff --git a/fieldExtraction/src/config.py b/fieldExtraction/src/config.py deleted file mode 100644 index e2094a3..0000000 --- a/fieldExtraction/src/config.py +++ /dev/null @@ -1,110 +0,0 @@ -import os -import columns -from datetime import datetime -import boto3 - -# from llama_index.llms.bedrock import Bedrock -# pip install llama-index-llms-bedrock - -# General Settings -TEST = False # True to run test prompt - just for testing model connection -VERBOSE = True -CLIENT_NAME = "" -TODAY = datetime.now().strftime("%Y%m%d") - -# Valid values -VALID_LOBS = [ - "MEDICARE", - "MEDICARE ADVANTAGE", - "MEDICAID", - "MARKETPLACE", - "COMMERCIAL", - "GROUP", - "MEDICARE-MEDICAID", -] -VALID_PROGRAMS = [ - "CHIP", - "CHIP-P", - "CHIP-PERINATE", - "STAR", - "STAR+PLUS", - "MA", - "DUAL SPECIAL NEEDS PLAN", - "DSNP", - "DUAL", -] -VALID_NETWORKS = ["HMO", "PPO", "EPO", "POS", "FFS"] - -# Input Settings -READ_MODE = os.getenv("READ_MODE") -# '_LOCAL_' OR '_S3_' -FILTER_ALREADY_PROCESSED = True - -# Output Settings -WRITE_OUTPUT = ( - True # True writes csvs, False prints result in console but no output written -) -OUTPUT_DIRECTORY = "output" -CONSOLIDATED_OUTPUT_DIRECTORY = "output_consolidated" -OUTPUT_CSV_PATH = f"consolidated_output_{TODAY}.csv" -TD_RESULTS_NAME = "td_results.csv" -BU_RESULTS_NAME = "bu_results.csv" -UNPROCESSED_RESULTS_NAME = "combined_results_unprocessed.csv" -PROCESSED_RESULTS_NAME = "combined_results_post_processed.csv" - -# Multithread Settings -MAX_WORKERS = os.getenv("MAX_WORKERS", 10) - -# Prompt Debugging -RUN_PRIMARY = True # Always True -RUN_LOB = True -RUN_LESSER = True -RUN_METHODOLOGY = True -RUN_FS = True -RUN_EXCEPTION = True -RUN_CODES = True - -# Postprocessing Settings -FUZZY_MATCH_THRESHOLD = 0.8 -CLIENT = os.getenv("CLIENT", "base") -VALID_COLUMNS = columns.VALID_COLUMNS_TEMPLATE[CLIENT] - -# AWS Keys -AWS_ACCESS_KEY_ID = os.getenv("AWS_ACCESS_KEY_ID") -AWS_SECRET_ACCESS_KEY = os.getenv("AWS_SECRET_ACCESS_KEY") -AWS_SESSION_TOKEN = os.getenv("AWS_SESSION_TOKEN") - -# File Paths -LOCAL_PATH = os.getenv("LOCAL_PATH", "data/") - -# S3 Settings -S3_CLIENT = boto3.client( - "s3", - region_name="us-east-2", - aws_access_key_id=AWS_ACCESS_KEY_ID, - aws_secret_access_key=AWS_SECRET_ACCESS_KEY, - aws_session_token=AWS_SESSION_TOKEN, -) -BUCKET = os.getenv("BUCKET", "doczy-dev-infra-textract") -PREFIX = os.getenv("BUCKET_PREFIX") - -# Bedrock Settings -BEDROCK_RUNTIME = boto3.client( - service_name="bedrock-runtime", - region_name="us-east-1", - aws_access_key_id=AWS_ACCESS_KEY_ID, - aws_secret_access_key=AWS_SECRET_ACCESS_KEY, - aws_session_token=AWS_SESSION_TOKEN, -) -MODEL_ID_CLAUDE3_HAIKU = "anthropic.claude-3-haiku-20240307-v1:0" -MODEL_ID_CLAUDE3_SONNET = "anthropic.claude-3-sonnet-20240229-v1:0" -MODEL_ID_CLAUDE2 = "anthropic.claude-instant-v1" - -# LLama Model -# LLAMA_MODEL = Bedrock( -# model=MODEL_ID_CLAUDE3_HAIKU, -# aws_access_key_id=AWS_ACCESS_KEY_ID, -# aws_secret_access_key=AWS_SECRET_ACCESS_KEY, -# aws_session_token=AWS_SESSION_TOKEN, -# region_name="us-east-1" -# ) diff --git a/fieldExtraction/src/consolidate_output.py b/fieldExtraction/src/consolidate_output.py deleted file mode 100644 index ec95383..0000000 --- a/fieldExtraction/src/consolidate_output.py +++ /dev/null @@ -1,36 +0,0 @@ -import os -import pandas as pd - -import config - -# all_dfs = [] -# for file in os.listdir(config.OUTPUT_DIRECTORY): -# if config.PROCESSED_RESULTS_NAME in os.listdir(os.path.join(config.OUTPUT_DIRECTORY, file)): -# try: -# df = pd.read_csv(f'{config.OUTPUT_DIRECTORY}/{file}/{config.PROCESSED_RESULTS_NAME}') -# all_dfs.append(df) -# except: -# continue - -# final_df = pd.concat(all_dfs, ignore_index=True) -# print(final_df.shape) -# print(len(final_df.Filename.unique())) - -# final_df.to_csv(os.path.join(config.CONSOLIDATED_OUTPUT_DIRECTORY, config.OUTPUT_CSV_PATH)) - - -ac_path = "T:\\AArete Client Work\\Texas Children’s Health Plan\\Restricted\\Doczy_Output\\TX_Childrens_1-1.csv" -b_path = "T:\\AArete Client Work\\Texas Children’s Health Plan\\Restricted\\Doczy_Output\\TX_Childrens_1-N.csv" -output_path = f"T:\\AArete Client Work\\Texas Children’s Health Plan\\Restricted\\Doczy_Output\\{config.TODAY}_TX_Childrens_460_Doczy_AI_Output.csv" - -# Read the files into pandas DataFrames -ac = pd.read_csv(ac_path) -b = pd.read_csv(b_path) - -print(b.shape) - -# Merge the DataFrames on the 'Filename' column -merged_df = pd.merge(ac, b, on="Filename", how="right") -merged_df.to_csv(output_path) - -print(merged_df.shape) diff --git a/fieldExtraction/src/dict_operations.py b/fieldExtraction/src/dict_operations.py deleted file mode 100644 index 561ca17..0000000 --- a/fieldExtraction/src/dict_operations.py +++ /dev/null @@ -1,109 +0,0 @@ -import re -import json -from collections import defaultdict - - -def secondary_string_to_dict(dict_string): - """ - Converts a string representation of a dictionary into an actual dictionary object, handling potential formatting issues. - - This function cleans the string by removing specific unwanted characters and markers that may interfere with JSON parsing. - It then locates the substring that correctly forms a dictionary format, attempts to parse it as JSON, and handles common - parsing errors by replacing problematic single quotes with double quotes before re-parsing. - - Parameters: - dict_string (str): The string containing the dictionary-like content, potentially surrounded by extra text or characters. - - Returns: - dict: The dictionary obtained from parsing the cleaned and corrected string. - """ - dict_string = dict_string.replace("<<<", "") - dict_string = dict_string.replace(">>>", "") - dict_string = dict_string.replace("\n", "") # Remove new line - - start_index = dict_string.find("{") - end_index = dict_string.rfind("}") + 1 - dict_substring = dict_string[start_index:end_index] - try: - result_dict = json.loads(dict_substring) - except: - dict_substring = dict_substring.replace("'", '"') - result_dict = json.loads(dict_substring) - return result_dict - - -def primary_string_to_dict(string_dict, filename): - """ - Converts a dictionary of strings, where each string represents multiple dictionary entries, into a list of dictionaries, - augmenting each with metadata such as page number and filename. - - This function iterates over each page number's string data, extracting and converting string representations of - dictionaries into actual dictionary objects. It handles and cleans the string format to properly parse it into dictionaries. - All dictionaries are then augmented with their respective page number and the filename before being compiled into a list. - - Parameters: - string_dict (dict): A dictionary where keys are page numbers and values are strings containing multiple dictionary entries. - filename (str): The filename associated with these entries, used to tag each resulting dictionary. - - Returns: - list of dict: A list of dictionaries, each representing data extracted and converted from the input string, tagged with - their page number and filename. - """ - data = [] - pattern = r"\{.*?\}" - for page_num in string_dict.keys(): - primary_list = string_dict[page_num] - dicts = primary_list.split("[")[1] # Strip front - dicts = dicts.split("]")[0] # Strip back - dicts = dicts.replace("\n", "") # Remove new lines - dicts = dicts.replace("<<<", "") - dicts = dicts.replace(">>>", "") - dicts = re.sub(r"(? 1:\n", - " page_num = bu[\"page_num\"]\n", - " page_text = text_dict.get(page_num, \"\")\n", - " prompt = GENERATE_PROMPT(\n", - " bu, td_on_page, page_text, field_name=key, values=merged[key]\n", - " )\n", - " response = claude_funcs.invoke_claude_3(prompt, max_tokens=4000)\n", - " try:\n", - " selected_value = response.strip()\n", - " merged[key] = selected_value\n", - " except Exception as e:\n", - " print(f\"Error processing LLM response for key {key}: {e}\")\n", - " merged[key] = \", \".join(merged[key])\n", - "\n", - " merged_results.append(merged)\n", - "\n", - " return merged_results\n", - "\n", - "\n", - "def process_file(filename, input_dict):\n", - " contract_text = input_dict[filename]\n", - "\n", - " # Preprocess\n", - " contract_text = preprocess.clean_newlines(contract_text)\n", - " text_dict = preprocess.split_text(contract_text)\n", - "\n", - " # Run Top Down\n", - " td_results = prompt_funcs.run_top_down(\n", - " filename, text_dict\n", - " ) # Returns list of dictionaries for each page\n", - " print(\"TD Results:\", td_results)\n", - "\n", - " # Run Bottom Up\n", - " bu_results = prompt_funcs.run_bottom_up(\n", - " filename, text_dict\n", - " ) # Returns list of dictionaries\n", - " print(\"BU Results:\", bu_results)\n", - "\n", - " # Combine\n", - " combined_results = merge_results(clean_td(td_results), bu_results, text_dict)\n", - " print(\"Combined Results:\", combined_results)\n", - "\n", - " # Create directories\n", - " base_filename = os.path.splitext(filename)[0]\n", - " output_dir = os.path.join(\"output\", base_filename)\n", - " os.makedirs(output_dir, exist_ok=True)\n", - "\n", - " # Save results\n", - " pd.DataFrame(td_results).to_csv(\n", - " os.path.join(output_dir, \"td_results.csv\"), index=False\n", - " )\n", - " pd.DataFrame(bu_results).to_csv(\n", - " os.path.join(output_dir, \"bu_results.csv\"), index=False\n", - " )\n", - " pd.DataFrame(combined_results).to_csv(\n", - " os.path.join(output_dir, \"combined_results.csv\"), index=False\n", - " )\n", - "\n", - "\n", - "def process_all_files(input_dict):\n", - " for filename in input_dict.keys():\n", - " process_file(filename, input_dict)\n", - " print(f\"Processed {filename}\")\n", - "\n", - "\n", - "# Example usage\n", - "input_dict = utils.read_input(path=\"subset\")\n", - "process_all_files(input_dict)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Preprocessing:\n", - "clean_newlines(contract_text):\n", - "\n", - "Removes unwanted newline characters from the contract text.\n", - "split_text(contract_text):\n", - "\n", - "Splits the contract text into individual pages and stores them in a dictionary.\n", - "Top Down and Bottom Up Analysis:\n", - "run_top_down(filename, text_dict):\n", - "\n", - "Extracts data from each page of the contract text and returns a list of dictionaries.\n", - "run_bottom_up(filename, text_dict):\n", - "\n", - "Extracts data from the entire contract document and returns a list of dictionaries.\n", - "Cleaning and Combining Results:\n", - "clean_td(td_results):\n", - "\n", - "Ensures values in the Top Down results are in list format and preserves date fields.\n", - "get_unique_keys(td_results, bu_results):\n", - "\n", - "Collects all unique field names from both Top Down and Bottom Up results.\n", - "get_unique_date_fields(td_results):\n", - "\n", - "Aggregates all unique date fields from the Top Down results.\n", - "merge_results(td_results, bu_results, text_dict):\n", - "\n", - "Combines Top Down and Bottom Up results, ensuring all relevant fields are included.\n", - "Uses the LLM to resolve ambiguities and infer the most appropriate values when necessary when multiple are there.\n", - "Post-Processing:\n", - "post_process_combined(combined_df):\n", - "\n", - "Cleans and validates specific fields (CONTRACT_LOB, PRODUCT, CONTRACT_NETWORK) in the combined dataset.\n", - "Adds new columns (Corrected_LOB, Corrected_PRODUCT, Corrected_NETWORK) to the combined dataset.\n", - "Extracts and standardizes page numbers.\n", - "clean_columns_combined(df, column_name, valid_values, new_column_name):\n", - "\n", - "Cleans a column by applying an exact match check and updates it to a new column.\n", - "clean_pagenumbers(df):\n", - "\n", - "Extracts and standardizes page numbers in the combined dataset.\n", - "Saving the Results:\n", - "process_file(filename, input_dict):\n", - "\n", - "Runs the entire process for a single file, from reading and preprocessing to saving the final results.\n", - "Calls the necessary functions to extract, combine, and post-process the data.\n", - "Saves the results as CSV files in the output directory.\n", - "process_all_files(input_dict):\n", - "\n", - "Iterates through all input files and processes each one using process_file." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "TD Results: [{'CONTRACT_LOB': 'Commercial, Medicare', 'CONTRACT_PROGRAM': 'N/A', 'CONTRACT_NETWORK': 'HMO, PPO, EPO', 'PRODUCT': 'Medicare Select', 'page_num': '1', 'Filename': '2007-12-01 California Emergency Physicians AMD_MU.txt', 'CONTRACT_MARKETPLACE_METAL_LEVEL': 'N/A', 'LOB_PRICING_TERMS_EFFECTIVE_DATE': 'December 1, 2007', 'LOB_PRICING_TERMS_TERMINATION_DATE': 'December 1, 2007'}, {'CONTRACT_LOB': 'Medicare', 'CONTRACT_PROGRAM': 'N/A', 'CONTRACT_NETWORK': 'N/A', 'PRODUCT': 'Health Net', 'page_num': '2', 'Filename': '2007-12-01 California Emergency Physicians AMD_MU.txt', 'CONTRACT_MARKETPLACE_METAL_LEVEL': 'N/A', 'LOB_PRICING_TERMS_EFFECTIVE_DATE': '11/20/07', 'LOB_PRICING_TERMS_TERMINATION_DATE': '11/20/07'}]\n", - "BU Results: [{'SERVICE': 'Commercial HMO Members Contracted Services', 'REIMBURSEMENT_FLAT_FEE': 'N/A', 'REIMBURSEMENT_RATE': '241%', 'FULL_METHODOLOGY': '(a) two hundred and forty-one percent (241%) of the Medicare allowable charges based on the Medicare Resource Based Relative Value Scale (RBRVS) unit values and CMS Geographical Practice Cost Indices as published in the most current published edition of the Federal Register: or (b) one hundred percent (100%) of Physician Group allowable billed charges.', 'page_num': '1', 'Filename': '2007-12-01 California Emergency Physicians AMD_MU.txt', 'REIMBURSEMENT_METHODOLOGY': 'Medicare Fee Schedule, Billed Charges', 'REIMBURSEMENT_FEE_SCHEDULE': 'Medicare RBRVS', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION': 'Most current published edition', 'REIMBURSEMENT_EXCEPTION_IND': 'N', 'REIMBURSEMENT_DESCRIBE_EXCEPTION': 'N/A', 'RATE_ESCALATOR_IND': 'Y', 'REIMBURSEMENT_ADMITTYPE_CODES': 'N/A', 'REIMBURSEMENT_DIAG_CODES': 'N/A', 'REIMBURSEMENT_GROUPER_CODES': 'N/A', 'REIMBURSEMENT_GROUPER': 'N/A', 'REIMBURSEMENT_PLACEOFSERVICE_CODES': 'N/A', 'REIMBURSEMENT_PROC_CODES': 'N/A', 'REIMBURSEMENT_REVENUE_CODES': 'N/A', 'REIMBURSEMENT_STATUS_INDICATOR_CODES': 'N/A'}, {'LESSER_OF_LANGUAGE_IND': 'Y', 'GREATER_OF_LANGUAGE_IND': 'N', 'FULL_METHODOLOGY': '(b) one hundred percent (100%) of Physician Group allowable billed charges', 'REIMBURSEMENT_RATE': 100, 'REIMBURSEMENT_FLAT_FEE': 'N/A', 'page_num': '1', 'SERVICE': 'Commercial HMO Members Contracted Services', 'REIMBURSEMENT_METHODOLOGY': 'Billed Charges', 'REIMBURSEMENT_FEE_SCHEDULE': 'N/A', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION': 'N/A', 'REIMBURSEMENT_EXCEPTION_IND': 'N', 'REIMBURSEMENT_DESCRIBE_EXCEPTION': 'N/A', 'RATE_ESCALATOR_IND': 'Y', 'REIMBURSEMENT_ADMITTYPE_CODES': 'N/A', 'REIMBURSEMENT_DIAG_CODES': 'N/A', 'REIMBURSEMENT_GROUPER_CODES': 'N/A', 'REIMBURSEMENT_GROUPER': 'N/A', 'REIMBURSEMENT_PLACEOFSERVICE_CODES': 'N/A', 'REIMBURSEMENT_PROC_CODES': 'N/A', 'REIMBURSEMENT_REVENUE_CODES': 'N/A', 'REIMBURSEMENT_STATUS_INDICATOR_CODES': 'N/A', 'Filename': '2007-12-01 California Emergency Physicians AMD_MU.txt'}, {'SERVICE': 'Commercial HMO Members Contracted Services', 'REIMBURSEMENT_FLAT_FEE': 'N/A', 'REIMBURSEMENT_RATE': '254%', 'FULL_METHODOLOGY': 'For Commercial HMO Members, effective December 1, 2008 Physician Group shall be compensated for Contracted Services, less applicable Copayments, in an amount equal to the lesser of: (a) two hundred and fifty-four percent (254%) of the Medicare allowable charges based on the Medicare Resource based Relative Value Scalo (RBRVS) unit values and CMS Geographical Practice Cost Indices as published in the most current published edition of the Federal Register: or (b) one hundred percent (100%) of Physician Group allowable billed charges.', 'page_num': '1', 'Filename': '2007-12-01 California Emergency Physicians AMD_MU.txt', 'REIMBURSEMENT_METHODOLOGY': 'Medicare Fee Schedule, Billed Charges', 'REIMBURSEMENT_FEE_SCHEDULE': 'Medicare RBRVS', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION': 'Most current published edition', 'REIMBURSEMENT_EXCEPTION_IND': 'N', 'REIMBURSEMENT_DESCRIBE_EXCEPTION': 'N/A', 'RATE_ESCALATOR_IND': 'Y', 'REIMBURSEMENT_ADMITTYPE_CODES': 'N/A', 'REIMBURSEMENT_DIAG_CODES': 'N/A', 'REIMBURSEMENT_GROUPER_CODES': 'N/A', 'REIMBURSEMENT_GROUPER': 'N/A', 'REIMBURSEMENT_PLACEOFSERVICE_CODES': 'N/A', 'REIMBURSEMENT_PROC_CODES': 'N/A', 'REIMBURSEMENT_REVENUE_CODES': 'N/A', 'REIMBURSEMENT_STATUS_INDICATOR_CODES': 'N/A'}, {'LESSER_OF_LANGUAGE_IND': 'Y', 'GREATER_OF_LANGUAGE_IND': 'N', 'FULL_METHODOLOGY': 'one hundred percent (100%) of Physician Group allowable billed charges', 'REIMBURSEMENT_RATE': '100', 'REIMBURSEMENT_FLAT_FEE': 'N/A', 'page_num': '1', 'SERVICE': 'Commercial HMO Members Contracted Services', 'REIMBURSEMENT_METHODOLOGY': 'Billed Charges', 'REIMBURSEMENT_FEE_SCHEDULE': 'N/A', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION': 'N/A', 'REIMBURSEMENT_EXCEPTION_IND': 'N', 'REIMBURSEMENT_DESCRIBE_EXCEPTION': 'N/A', 'RATE_ESCALATOR_IND': 'N', 'REIMBURSEMENT_ADMITTYPE_CODES': 'N/A', 'REIMBURSEMENT_DIAG_CODES': 'N/A', 'REIMBURSEMENT_GROUPER_CODES': 'N/A', 'REIMBURSEMENT_GROUPER': 'N/A', 'REIMBURSEMENT_PLACEOFSERVICE_CODES': 'N/A', 'REIMBURSEMENT_PROC_CODES': 'N/A', 'REIMBURSEMENT_REVENUE_CODES': 'N/A', 'REIMBURSEMENT_STATUS_INDICATOR_CODES': 'N/A', 'Filename': '2007-12-01 California Emergency Physicians AMD_MU.txt'}, {'SERVICE': 'Medicare HMO and Medicare Select products Contracted Services', 'REIMBURSEMENT_FLAT_FEE': 'N/A', 'REIMBURSEMENT_RATE': '100%', 'FULL_METHODOLOGY': '(a) one hundred percent (100%) of the Medicare allowable charges based on the Medicare Resource Based Relative Value Scale (RBRVS) unit values and CMS Geographical Practice Cost Indices as published in the most current published edition of the Federal Register: or (b) one hundred percent (100%) of Physician Group allowable billed charges.', 'page_num': '1', 'Filename': '2007-12-01 California Emergency Physicians AMD_MU.txt', 'REIMBURSEMENT_METHODOLOGY': 'Medicare Fee Schedule, Billed Charges', 'REIMBURSEMENT_FEE_SCHEDULE': 'Medicare RBRVS', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION': 'Most current published edition', 'REIMBURSEMENT_EXCEPTION_IND': 'N', 'REIMBURSEMENT_DESCRIBE_EXCEPTION': 'N/A', 'RATE_ESCALATOR_IND': 'N', 'REIMBURSEMENT_ADMITTYPE_CODES': 'N/A', 'REIMBURSEMENT_DIAG_CODES': 'N/A', 'REIMBURSEMENT_GROUPER_CODES': 'N/A', 'REIMBURSEMENT_GROUPER': 'N/A', 'REIMBURSEMENT_PLACEOFSERVICE_CODES': 'N/A', 'REIMBURSEMENT_PROC_CODES': 'N/A', 'REIMBURSEMENT_REVENUE_CODES': 'N/A', 'REIMBURSEMENT_STATUS_INDICATOR_CODES': 'N/A'}, {'LESSER_OF_LANGUAGE_IND': 'Y', 'GREATER_OF_LANGUAGE_IND': 'N', 'FULL_METHODOLOGY': '(a) two hundred and forty-one percent (241%) of the Medicare allowable charges based on the Medicare Resource Based Relative Value Scale (RBRVS) unit values and CMS Geographical Practice Cost Indices as published in the most current published edition of the Federal Register;', 'REIMBURSEMENT_RATE': '241', 'REIMBURSEMENT_FLAT_FEE': 'N/A', 'page_num': '1', 'SERVICE': 'Medicare HMO and Medicare Select products Contracted Services', 'REIMBURSEMENT_METHODOLOGY': 'Medicare Fee Schedule', 'REIMBURSEMENT_FEE_SCHEDULE': 'Medicare RBRVS', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION': 'Most current published edition', 'REIMBURSEMENT_EXCEPTION_IND': 'N', 'REIMBURSEMENT_DESCRIBE_EXCEPTION': 'N/A', 'RATE_ESCALATOR_IND': 'N', 'REIMBURSEMENT_ADMITTYPE_CODES': 'N/A', 'REIMBURSEMENT_DIAG_CODES': 'N/A', 'REIMBURSEMENT_GROUPER_CODES': 'N/A', 'REIMBURSEMENT_GROUPER': 'N/A', 'REIMBURSEMENT_PLACEOFSERVICE_CODES': 'N/A', 'REIMBURSEMENT_PROC_CODES': 'N/A', 'REIMBURSEMENT_REVENUE_CODES': 'N/A', 'REIMBURSEMENT_STATUS_INDICATOR_CODES': 'N/A', 'Filename': '2007-12-01 California Emergency Physicians AMD_MU.txt'}, {'SERVICE': 'Preferred Provider Organization (PPO) Exclusive Provider Organization (EPO) Benefit Programs Covered Services', 'REIMBURSEMENT_FLAT_FEE': 'N/A', 'REIMBURSEMENT_RATE': '241%', 'FULL_METHODOLOGY': '(a) two hundred and forty-one percent (241%) of the Medicare allowable charges based on the Medicare Resource Based Relative Value Scale (RBRVS) unit values and CMS Geographical Practice Cost Indices as published in the most current published edition of the Federal Register; or (b) one hundred percent (100%) of Physician Group allowable billed charges.', 'page_num': '1', 'Filename': '2007-12-01 California Emergency Physicians AMD_MU.txt', 'REIMBURSEMENT_METHODOLOGY': 'Medicare Fee Schedule, Billed Charges', 'REIMBURSEMENT_FEE_SCHEDULE': 'Medicare', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION': 'RBRVS', 'REIMBURSEMENT_EXCEPTION_IND': 'N', 'REIMBURSEMENT_DESCRIBE_EXCEPTION': 'N/A', 'RATE_ESCALATOR_IND': 'Y', 'REIMBURSEMENT_ADMITTYPE_CODES': 'N/A', 'REIMBURSEMENT_DIAG_CODES': 'N/A', 'REIMBURSEMENT_GROUPER_CODES': 'N/A', 'REIMBURSEMENT_GROUPER': 'N/A', 'REIMBURSEMENT_PLACEOFSERVICE_CODES': 'N/A', 'REIMBURSEMENT_PROC_CODES': 'N/A', 'REIMBURSEMENT_REVENUE_CODES': 'N/A', 'REIMBURSEMENT_STATUS_INDICATOR_CODES': 'N/A'}, {'LESSER_OF_LANGUAGE_IND': 'Y', 'GREATER_OF_LANGUAGE_IND': 'N', 'FULL_METHODOLOGY': '(b) one hundred percent (100%) of Physician Group allowable billed charges', 'REIMBURSEMENT_RATE': 100, 'REIMBURSEMENT_FLAT_FEE': 'N/A', 'page_num': '1', 'SERVICE': 'Preferred Provider Organization (PPO) Exclusive Provider Organization (EPO) Benefit Programs Covered Services', 'REIMBURSEMENT_METHODOLOGY': 'Billed Charges', 'REIMBURSEMENT_FEE_SCHEDULE': 'N/A', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION': 'N/A', 'REIMBURSEMENT_EXCEPTION_IND': 'N', 'REIMBURSEMENT_DESCRIBE_EXCEPTION': 'N/A', 'RATE_ESCALATOR_IND': 'Y', 'REIMBURSEMENT_ADMITTYPE_CODES': 'N/A', 'REIMBURSEMENT_DIAG_CODES': 'N/A', 'REIMBURSEMENT_GROUPER_CODES': 'N/A', 'REIMBURSEMENT_GROUPER': 'N/A', 'REIMBURSEMENT_PLACEOFSERVICE_CODES': 'N/A', 'REIMBURSEMENT_PROC_CODES': 'N/A', 'REIMBURSEMENT_REVENUE_CODES': 'N/A', 'REIMBURSEMENT_STATUS_INDICATOR_CODES': 'N/A', 'Filename': '2007-12-01 California Emergency Physicians AMD_MU.txt'}, {'SERVICE': 'Preferred Provider Organization (PPO) Exclusive Provider Organization (EPO) Benefit Programs Covered Services', 'REIMBURSEMENT_FLAT_FEE': 'N/A', 'REIMBURSEMENT_RATE': '254%', 'FULL_METHODOLOGY': 'Effective December 1, 2008 Physician Group shall be compensated for Covered Services in an amount, less applicable Copayments and/or coinsurance, that is equal to the lesser of: (a) two hundred and fifty-four percent (254%) of the Medicare allowable charges based on the Medicare Resource Based Relative Value Scale (RBRVS) unit values and CMS Geographical Practice Cost Indices as published in the most current published edition of the Federal Register; or (b) one hundred percent (100%) of Physician Group allowable billed charges.', 'page_num': '1', 'Filename': '2007-12-01 California Emergency Physicians AMD_MU.txt', 'REIMBURSEMENT_METHODOLOGY': 'Medicare Fee Schedule, Billed Charges', 'REIMBURSEMENT_FEE_SCHEDULE': 'Medicare RBRVS', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION': 'Most current published edition', 'REIMBURSEMENT_EXCEPTION_IND': 'N', 'REIMBURSEMENT_DESCRIBE_EXCEPTION': 'N/A', 'RATE_ESCALATOR_IND': 'Y', 'REIMBURSEMENT_ADMITTYPE_CODES': 'N/A', 'REIMBURSEMENT_DIAG_CODES': 'N/A', 'REIMBURSEMENT_GROUPER_CODES': 'N/A', 'REIMBURSEMENT_GROUPER': 'N/A', 'REIMBURSEMENT_PLACEOFSERVICE_CODES': 'N/A', 'REIMBURSEMENT_PROC_CODES': 'N/A', 'REIMBURSEMENT_REVENUE_CODES': 'N/A', 'REIMBURSEMENT_STATUS_INDICATOR_CODES': 'N/A'}, {'LESSER_OF_LANGUAGE_IND': 'Y', 'GREATER_OF_LANGUAGE_IND': 'N', 'FULL_METHODOLOGY': 'one hundred percent (100%) of Physician Group allowable billed charges', 'REIMBURSEMENT_RATE': '100', 'REIMBURSEMENT_FLAT_FEE': 'N/A', 'page_num': '1', 'SERVICE': 'Preferred Provider Organization (PPO) Exclusive Provider Organization (EPO) Benefit Programs Covered Services', 'REIMBURSEMENT_METHODOLOGY': 'Billed Charges', 'REIMBURSEMENT_FEE_SCHEDULE': 'N/A', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION': 'N/A', 'REIMBURSEMENT_EXCEPTION_IND': 'N', 'REIMBURSEMENT_DESCRIBE_EXCEPTION': 'N/A', 'RATE_ESCALATOR_IND': 'N', 'REIMBURSEMENT_ADMITTYPE_CODES': 'N/A', 'REIMBURSEMENT_DIAG_CODES': 'N/A', 'REIMBURSEMENT_GROUPER_CODES': 'N/A', 'REIMBURSEMENT_GROUPER': 'N/A', 'REIMBURSEMENT_PLACEOFSERVICE_CODES': 'N/A', 'REIMBURSEMENT_PROC_CODES': 'N/A', 'REIMBURSEMENT_REVENUE_CODES': 'N/A', 'REIMBURSEMENT_STATUS_INDICATOR_CODES': 'N/A', 'Filename': '2007-12-01 California Emergency Physicians AMD_MU.txt'}, {'SERVICE': 'Medicare Resource Based Relative Value Scale (RBRVS)', 'REIMBURSEMENT_FLAT_FEE': 'N/A', 'REIMBURSEMENT_RATE': 'N/A', 'FULL_METHODOLOGY': 'In the event that potential CMS changes to Medicare Resource Based Relative Value Scale (RBRVS) result in an aggregate 3% change, either positively or negatively, either party may initiate a meet and confer process which will determine impact and/or potential changes to reimbursement.', 'page_num': '2', 'Filename': '2007-12-01 California Emergency Physicians AMD_MU.txt', 'LESSER_OF_LANGUAGE_IND': 'N', 'GREATER_OF_LANGUAGE_IND': 'N', 'REIMBURSEMENT_METHODOLOGY': 'Medicare Fee Schedule', 'REIMBURSEMENT_FEE_SCHEDULE': 'Medicare Resource Based Relative Value Scale (RBRVS)', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION': 'N/A', 'REIMBURSEMENT_EXCEPTION_IND': 'Y', 'REIMBURSEMENT_DESCRIBE_EXCEPTION': 'In the event that potential CMS changes to Medicare Resource Based Relative Value Scale (RBRVS) result in an aggregate 3% change, either positively or negatively, either party may initiate a meet and confer process which will determine impact and/or potential changes to reimbursement.', 'RATE_ESCALATOR_IND': 'N', 'REIMBURSEMENT_ADMITTYPE_CODES': 'N/A', 'REIMBURSEMENT_DIAG_CODES': 'N/A', 'REIMBURSEMENT_GROUPER_CODES': 'N/A', 'REIMBURSEMENT_GROUPER': 'N/A', 'REIMBURSEMENT_PLACEOFSERVICE_CODES': 'N/A', 'REIMBURSEMENT_PROC_CODES': 'N/A', 'REIMBURSEMENT_REVENUE_CODES': 'N/A', 'REIMBURSEMENT_STATUS_INDICATOR_CODES': 'N/A'}]\n", - "All Keys: {'REIMBURSEMENT_STATUS_INDICATOR_CODES', 'CONTRACT_NETWORK', 'REIMBURSEMENT_GROUPER_CODES', 'GREATER_OF_LANGUAGE_IND', 'LESSER_OF_LANGUAGE_IND', 'REIMBURSEMENT_EXCEPTION_IND', 'SERVICE', 'LOB_PRICING_TERMS_TERMINATION_DATE', 'REIMBURSEMENT_REVENUE_CODES', 'PRODUCT', 'CONTRACT_LOB', 'REIMBURSEMENT_PLACEOFSERVICE_CODES', 'REIMBURSEMENT_PROC_CODES', 'RATE_ESCALATOR_IND', 'REIMBURSEMENT_RATE', 'REIMBURSEMENT_METHODOLOGY', 'REIMBURSEMENT_FLAT_FEE', 'REIMBURSEMENT_DIAG_CODES', 'REIMBURSEMENT_GROUPER', 'REIMBURSEMENT_ADMITTYPE_CODES', 'CONTRACT_PROGRAM', 'FULL_METHODOLOGY', 'REIMBURSEMENT_DESCRIBE_EXCEPTION', 'page_num', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION', 'REIMBURSEMENT_FEE_SCHEDULE', 'CONTRACT_MARKETPLACE_METAL_LEVEL', 'LOB_PRICING_TERMS_EFFECTIVE_DATE', 'Filename'}\n", - "Date Fields: {'LOB_PRICING_TERMS_EFFECTIVE_DATE': ['11/20/07', 'December 1, 2007'], 'LOB_PRICING_TERMS_TERMINATION_DATE': ['11/20/07', 'December 1, 2007']}\n", - "Combined Results: [{'REIMBURSEMENT_STATUS_INDICATOR_CODES': 'N/A', 'CONTRACT_NETWORK': 'HMO', 'REIMBURSEMENT_GROUPER_CODES': 'N/A', 'GREATER_OF_LANGUAGE_IND': '', 'LESSER_OF_LANGUAGE_IND': '', 'REIMBURSEMENT_EXCEPTION_IND': 'N', 'SERVICE': 'Commercial HMO Members Contracted Services', 'LOB_PRICING_TERMS_TERMINATION_DATE': 'December 1, 2007', 'REIMBURSEMENT_REVENUE_CODES': 'N/A', 'PRODUCT': ['Medicare Select'], 'CONTRACT_LOB': 'Commercial', 'REIMBURSEMENT_PLACEOFSERVICE_CODES': 'N/A', 'REIMBURSEMENT_PROC_CODES': 'N/A', 'RATE_ESCALATOR_IND': 'Y', 'REIMBURSEMENT_RATE': '241%', 'REIMBURSEMENT_METHODOLOGY': 'Medicare Fee Schedule, Billed Charges', 'REIMBURSEMENT_FLAT_FEE': 'N/A', 'REIMBURSEMENT_DIAG_CODES': 'N/A', 'REIMBURSEMENT_GROUPER': 'N/A', 'REIMBURSEMENT_ADMITTYPE_CODES': 'N/A', 'CONTRACT_PROGRAM': [], 'FULL_METHODOLOGY': '(a) two hundred and forty-one percent (241%) of the Medicare allowable charges based on the Medicare Resource Based Relative Value Scale (RBRVS) unit values and CMS Geographical Practice Cost Indices as published in the most current published edition of the Federal Register: or (b) one hundred percent (100%) of Physician Group allowable billed charges.', 'REIMBURSEMENT_DESCRIBE_EXCEPTION': 'N/A', 'page_num': '1', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION': 'Most current published edition', 'REIMBURSEMENT_FEE_SCHEDULE': 'Medicare RBRVS', 'CONTRACT_MARKETPLACE_METAL_LEVEL': [], 'LOB_PRICING_TERMS_EFFECTIVE_DATE': 'December 1, 2007', 'Filename': '2007-12-01 California Emergency Physicians AMD_MU.txt'}, {'REIMBURSEMENT_STATUS_INDICATOR_CODES': 'N/A', 'CONTRACT_NETWORK': 'HMO', 'REIMBURSEMENT_GROUPER_CODES': 'N/A', 'GREATER_OF_LANGUAGE_IND': 'N', 'LESSER_OF_LANGUAGE_IND': 'Y', 'REIMBURSEMENT_EXCEPTION_IND': 'N', 'SERVICE': 'Commercial HMO Members Contracted Services', 'LOB_PRICING_TERMS_TERMINATION_DATE': 'December 1, 2007', 'REIMBURSEMENT_REVENUE_CODES': 'N/A', 'PRODUCT': ['Medicare Select'], 'CONTRACT_LOB': 'Commercial', 'REIMBURSEMENT_PLACEOFSERVICE_CODES': 'N/A', 'REIMBURSEMENT_PROC_CODES': 'N/A', 'RATE_ESCALATOR_IND': 'Y', 'REIMBURSEMENT_RATE': 100, 'REIMBURSEMENT_METHODOLOGY': 'Billed Charges', 'REIMBURSEMENT_FLAT_FEE': 'N/A', 'REIMBURSEMENT_DIAG_CODES': 'N/A', 'REIMBURSEMENT_GROUPER': 'N/A', 'REIMBURSEMENT_ADMITTYPE_CODES': 'N/A', 'CONTRACT_PROGRAM': [], 'FULL_METHODOLOGY': '(b) one hundred percent (100%) of Physician Group allowable billed charges', 'REIMBURSEMENT_DESCRIBE_EXCEPTION': 'N/A', 'page_num': '1', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION': 'N/A', 'REIMBURSEMENT_FEE_SCHEDULE': 'N/A', 'CONTRACT_MARKETPLACE_METAL_LEVEL': [], 'LOB_PRICING_TERMS_EFFECTIVE_DATE': 'December 1, 2007', 'Filename': '2007-12-01 California Emergency Physicians AMD_MU.txt'}, {'REIMBURSEMENT_STATUS_INDICATOR_CODES': 'N/A', 'CONTRACT_NETWORK': 'HMO', 'REIMBURSEMENT_GROUPER_CODES': 'N/A', 'GREATER_OF_LANGUAGE_IND': '', 'LESSER_OF_LANGUAGE_IND': '', 'REIMBURSEMENT_EXCEPTION_IND': 'N', 'SERVICE': 'Commercial HMO Members Contracted Services', 'LOB_PRICING_TERMS_TERMINATION_DATE': 'December 1, 2007', 'REIMBURSEMENT_REVENUE_CODES': 'N/A', 'PRODUCT': ['Medicare Select'], 'CONTRACT_LOB': 'Commercial', 'REIMBURSEMENT_PLACEOFSERVICE_CODES': 'N/A', 'REIMBURSEMENT_PROC_CODES': 'N/A', 'RATE_ESCALATOR_IND': 'Y', 'REIMBURSEMENT_RATE': '254%', 'REIMBURSEMENT_METHODOLOGY': 'Medicare Fee Schedule, Billed Charges', 'REIMBURSEMENT_FLAT_FEE': 'N/A', 'REIMBURSEMENT_DIAG_CODES': 'N/A', 'REIMBURSEMENT_GROUPER': 'N/A', 'REIMBURSEMENT_ADMITTYPE_CODES': 'N/A', 'CONTRACT_PROGRAM': [], 'FULL_METHODOLOGY': 'For Commercial HMO Members, effective December 1, 2008 Physician Group shall be compensated for Contracted Services, less applicable Copayments, in an amount equal to the lesser of: (a) two hundred and fifty-four percent (254%) of the Medicare allowable charges based on the Medicare Resource based Relative Value Scalo (RBRVS) unit values and CMS Geographical Practice Cost Indices as published in the most current published edition of the Federal Register: or (b) one hundred percent (100%) of Physician Group allowable billed charges.', 'REIMBURSEMENT_DESCRIBE_EXCEPTION': 'N/A', 'page_num': '1', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION': 'Most current published edition', 'REIMBURSEMENT_FEE_SCHEDULE': 'Medicare RBRVS', 'CONTRACT_MARKETPLACE_METAL_LEVEL': [], 'LOB_PRICING_TERMS_EFFECTIVE_DATE': 'December 1, 2007', 'Filename': '2007-12-01 California Emergency Physicians AMD_MU.txt'}, {'REIMBURSEMENT_STATUS_INDICATOR_CODES': 'N/A', 'CONTRACT_NETWORK': 'HMO', 'REIMBURSEMENT_GROUPER_CODES': 'N/A', 'GREATER_OF_LANGUAGE_IND': 'N', 'LESSER_OF_LANGUAGE_IND': 'Y', 'REIMBURSEMENT_EXCEPTION_IND': 'N', 'SERVICE': 'Commercial HMO Members Contracted Services', 'LOB_PRICING_TERMS_TERMINATION_DATE': 'December 1, 2007', 'REIMBURSEMENT_REVENUE_CODES': 'N/A', 'PRODUCT': ['Medicare Select'], 'CONTRACT_LOB': 'Commercial', 'REIMBURSEMENT_PLACEOFSERVICE_CODES': 'N/A', 'REIMBURSEMENT_PROC_CODES': 'N/A', 'RATE_ESCALATOR_IND': 'N', 'REIMBURSEMENT_RATE': '100', 'REIMBURSEMENT_METHODOLOGY': 'Billed Charges', 'REIMBURSEMENT_FLAT_FEE': 'N/A', 'REIMBURSEMENT_DIAG_CODES': 'N/A', 'REIMBURSEMENT_GROUPER': 'N/A', 'REIMBURSEMENT_ADMITTYPE_CODES': 'N/A', 'CONTRACT_PROGRAM': [], 'FULL_METHODOLOGY': 'one hundred percent (100%) of Physician Group allowable billed charges', 'REIMBURSEMENT_DESCRIBE_EXCEPTION': 'N/A', 'page_num': '1', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION': 'N/A', 'REIMBURSEMENT_FEE_SCHEDULE': 'N/A', 'CONTRACT_MARKETPLACE_METAL_LEVEL': [], 'LOB_PRICING_TERMS_EFFECTIVE_DATE': 'December 1, 2007', 'Filename': '2007-12-01 California Emergency Physicians AMD_MU.txt'}, {'REIMBURSEMENT_STATUS_INDICATOR_CODES': 'N/A', 'CONTRACT_NETWORK': 'HMO', 'REIMBURSEMENT_GROUPER_CODES': 'N/A', 'GREATER_OF_LANGUAGE_IND': '', 'LESSER_OF_LANGUAGE_IND': '', 'REIMBURSEMENT_EXCEPTION_IND': 'N', 'SERVICE': 'Medicare HMO and Medicare Select products Contracted Services', 'LOB_PRICING_TERMS_TERMINATION_DATE': 'December 1, 2007', 'REIMBURSEMENT_REVENUE_CODES': 'N/A', 'PRODUCT': ['Medicare Select'], 'CONTRACT_LOB': 'Commercial', 'REIMBURSEMENT_PLACEOFSERVICE_CODES': 'N/A', 'REIMBURSEMENT_PROC_CODES': 'N/A', 'RATE_ESCALATOR_IND': 'N', 'REIMBURSEMENT_RATE': '100%', 'REIMBURSEMENT_METHODOLOGY': 'Medicare Fee Schedule, Billed Charges', 'REIMBURSEMENT_FLAT_FEE': 'N/A', 'REIMBURSEMENT_DIAG_CODES': 'N/A', 'REIMBURSEMENT_GROUPER': 'N/A', 'REIMBURSEMENT_ADMITTYPE_CODES': 'N/A', 'CONTRACT_PROGRAM': [], 'FULL_METHODOLOGY': '(a) one hundred percent (100%) of the Medicare allowable charges based on the Medicare Resource Based Relative Value Scale (RBRVS) unit values and CMS Geographical Practice Cost Indices as published in the most current published edition of the Federal Register: or (b) one hundred percent (100%) of Physician Group allowable billed charges.', 'REIMBURSEMENT_DESCRIBE_EXCEPTION': 'N/A', 'page_num': '1', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION': 'Most current published edition', 'REIMBURSEMENT_FEE_SCHEDULE': 'Medicare RBRVS', 'CONTRACT_MARKETPLACE_METAL_LEVEL': [], 'LOB_PRICING_TERMS_EFFECTIVE_DATE': 'December 1, 2007', 'Filename': '2007-12-01 California Emergency Physicians AMD_MU.txt'}, {'REIMBURSEMENT_STATUS_INDICATOR_CODES': 'N/A', 'CONTRACT_NETWORK': 'HMO', 'REIMBURSEMENT_GROUPER_CODES': 'N/A', 'GREATER_OF_LANGUAGE_IND': 'N', 'LESSER_OF_LANGUAGE_IND': 'Y', 'REIMBURSEMENT_EXCEPTION_IND': 'N', 'SERVICE': 'Medicare HMO and Medicare Select products Contracted Services', 'LOB_PRICING_TERMS_TERMINATION_DATE': 'December 1, 2007', 'REIMBURSEMENT_REVENUE_CODES': 'N/A', 'PRODUCT': ['Medicare Select'], 'CONTRACT_LOB': 'Commercial', 'REIMBURSEMENT_PLACEOFSERVICE_CODES': 'N/A', 'REIMBURSEMENT_PROC_CODES': 'N/A', 'RATE_ESCALATOR_IND': 'N', 'REIMBURSEMENT_RATE': '241', 'REIMBURSEMENT_METHODOLOGY': 'Medicare Fee Schedule', 'REIMBURSEMENT_FLAT_FEE': 'N/A', 'REIMBURSEMENT_DIAG_CODES': 'N/A', 'REIMBURSEMENT_GROUPER': 'N/A', 'REIMBURSEMENT_ADMITTYPE_CODES': 'N/A', 'CONTRACT_PROGRAM': [], 'FULL_METHODOLOGY': '(a) two hundred and forty-one percent (241%) of the Medicare allowable charges based on the Medicare Resource Based Relative Value Scale (RBRVS) unit values and CMS Geographical Practice Cost Indices as published in the most current published edition of the Federal Register;', 'REIMBURSEMENT_DESCRIBE_EXCEPTION': 'N/A', 'page_num': '1', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION': 'Most current published edition', 'REIMBURSEMENT_FEE_SCHEDULE': 'Medicare RBRVS', 'CONTRACT_MARKETPLACE_METAL_LEVEL': [], 'LOB_PRICING_TERMS_EFFECTIVE_DATE': 'December 1, 2007', 'Filename': '2007-12-01 California Emergency Physicians AMD_MU.txt'}, {'REIMBURSEMENT_STATUS_INDICATOR_CODES': 'N/A', 'CONTRACT_NETWORK': 'HMO', 'REIMBURSEMENT_GROUPER_CODES': 'N/A', 'GREATER_OF_LANGUAGE_IND': '', 'LESSER_OF_LANGUAGE_IND': '', 'REIMBURSEMENT_EXCEPTION_IND': 'N', 'SERVICE': 'Preferred Provider Organization (PPO) Exclusive Provider Organization (EPO) Benefit Programs Covered Services', 'LOB_PRICING_TERMS_TERMINATION_DATE': 'December 1, 2007', 'REIMBURSEMENT_REVENUE_CODES': 'N/A', 'PRODUCT': ['Medicare Select'], 'CONTRACT_LOB': 'Commercial', 'REIMBURSEMENT_PLACEOFSERVICE_CODES': 'N/A', 'REIMBURSEMENT_PROC_CODES': 'N/A', 'RATE_ESCALATOR_IND': 'Y', 'REIMBURSEMENT_RATE': '241%', 'REIMBURSEMENT_METHODOLOGY': 'Medicare Fee Schedule, Billed Charges', 'REIMBURSEMENT_FLAT_FEE': 'N/A', 'REIMBURSEMENT_DIAG_CODES': 'N/A', 'REIMBURSEMENT_GROUPER': 'N/A', 'REIMBURSEMENT_ADMITTYPE_CODES': 'N/A', 'CONTRACT_PROGRAM': [], 'FULL_METHODOLOGY': '(a) two hundred and forty-one percent (241%) of the Medicare allowable charges based on the Medicare Resource Based Relative Value Scale (RBRVS) unit values and CMS Geographical Practice Cost Indices as published in the most current published edition of the Federal Register; or (b) one hundred percent (100%) of Physician Group allowable billed charges.', 'REIMBURSEMENT_DESCRIBE_EXCEPTION': 'N/A', 'page_num': '1', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION': 'RBRVS', 'REIMBURSEMENT_FEE_SCHEDULE': 'Medicare', 'CONTRACT_MARKETPLACE_METAL_LEVEL': [], 'LOB_PRICING_TERMS_EFFECTIVE_DATE': 'December 1, 2007', 'Filename': '2007-12-01 California Emergency Physicians AMD_MU.txt'}, {'REIMBURSEMENT_STATUS_INDICATOR_CODES': 'N/A', 'CONTRACT_NETWORK': 'HMO', 'REIMBURSEMENT_GROUPER_CODES': 'N/A', 'GREATER_OF_LANGUAGE_IND': 'N', 'LESSER_OF_LANGUAGE_IND': 'Y', 'REIMBURSEMENT_EXCEPTION_IND': 'N', 'SERVICE': 'Preferred Provider Organization (PPO) Exclusive Provider Organization (EPO) Benefit Programs Covered Services', 'LOB_PRICING_TERMS_TERMINATION_DATE': 'December 1, 2007', 'REIMBURSEMENT_REVENUE_CODES': 'N/A', 'PRODUCT': ['Medicare Select'], 'CONTRACT_LOB': 'Commercial', 'REIMBURSEMENT_PLACEOFSERVICE_CODES': 'N/A', 'REIMBURSEMENT_PROC_CODES': 'N/A', 'RATE_ESCALATOR_IND': 'Y', 'REIMBURSEMENT_RATE': 100, 'REIMBURSEMENT_METHODOLOGY': 'Billed Charges', 'REIMBURSEMENT_FLAT_FEE': 'N/A', 'REIMBURSEMENT_DIAG_CODES': 'N/A', 'REIMBURSEMENT_GROUPER': 'N/A', 'REIMBURSEMENT_ADMITTYPE_CODES': 'N/A', 'CONTRACT_PROGRAM': [], 'FULL_METHODOLOGY': '(b) one hundred percent (100%) of Physician Group allowable billed charges', 'REIMBURSEMENT_DESCRIBE_EXCEPTION': 'N/A', 'page_num': '1', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION': 'N/A', 'REIMBURSEMENT_FEE_SCHEDULE': 'N/A', 'CONTRACT_MARKETPLACE_METAL_LEVEL': [], 'LOB_PRICING_TERMS_EFFECTIVE_DATE': 'December 1, 2007', 'Filename': '2007-12-01 California Emergency Physicians AMD_MU.txt'}, {'REIMBURSEMENT_STATUS_INDICATOR_CODES': 'N/A', 'CONTRACT_NETWORK': 'HMO', 'REIMBURSEMENT_GROUPER_CODES': 'N/A', 'GREATER_OF_LANGUAGE_IND': '', 'LESSER_OF_LANGUAGE_IND': '', 'REIMBURSEMENT_EXCEPTION_IND': 'N', 'SERVICE': 'Preferred Provider Organization (PPO) Exclusive Provider Organization (EPO) Benefit Programs Covered Services', 'LOB_PRICING_TERMS_TERMINATION_DATE': 'December 1, 2007', 'REIMBURSEMENT_REVENUE_CODES': 'N/A', 'PRODUCT': ['Medicare Select'], 'CONTRACT_LOB': 'Commercial', 'REIMBURSEMENT_PLACEOFSERVICE_CODES': 'N/A', 'REIMBURSEMENT_PROC_CODES': 'N/A', 'RATE_ESCALATOR_IND': 'Y', 'REIMBURSEMENT_RATE': '254%', 'REIMBURSEMENT_METHODOLOGY': 'Medicare Fee Schedule, Billed Charges', 'REIMBURSEMENT_FLAT_FEE': 'N/A', 'REIMBURSEMENT_DIAG_CODES': 'N/A', 'REIMBURSEMENT_GROUPER': 'N/A', 'REIMBURSEMENT_ADMITTYPE_CODES': 'N/A', 'CONTRACT_PROGRAM': [], 'FULL_METHODOLOGY': 'Effective December 1, 2008 Physician Group shall be compensated for Covered Services in an amount, less applicable Copayments and/or coinsurance, that is equal to the lesser of: (a) two hundred and fifty-four percent (254%) of the Medicare allowable charges based on the Medicare Resource Based Relative Value Scale (RBRVS) unit values and CMS Geographical Practice Cost Indices as published in the most current published edition of the Federal Register; or (b) one hundred percent (100%) of Physician Group allowable billed charges.', 'REIMBURSEMENT_DESCRIBE_EXCEPTION': 'N/A', 'page_num': '1', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION': 'Most current published edition', 'REIMBURSEMENT_FEE_SCHEDULE': 'Medicare RBRVS', 'CONTRACT_MARKETPLACE_METAL_LEVEL': [], 'LOB_PRICING_TERMS_EFFECTIVE_DATE': 'December 1, 2007', 'Filename': '2007-12-01 California Emergency Physicians AMD_MU.txt'}, {'REIMBURSEMENT_STATUS_INDICATOR_CODES': 'N/A', 'CONTRACT_NETWORK': 'HMO', 'REIMBURSEMENT_GROUPER_CODES': 'N/A', 'GREATER_OF_LANGUAGE_IND': 'N', 'LESSER_OF_LANGUAGE_IND': 'Y', 'REIMBURSEMENT_EXCEPTION_IND': 'N', 'SERVICE': 'Preferred Provider Organization (PPO) Exclusive Provider Organization (EPO) Benefit Programs Covered Services', 'LOB_PRICING_TERMS_TERMINATION_DATE': 'December 1, 2007', 'REIMBURSEMENT_REVENUE_CODES': 'N/A', 'PRODUCT': ['Medicare Select'], 'CONTRACT_LOB': 'Commercial', 'REIMBURSEMENT_PLACEOFSERVICE_CODES': 'N/A', 'REIMBURSEMENT_PROC_CODES': 'N/A', 'RATE_ESCALATOR_IND': 'N', 'REIMBURSEMENT_RATE': '100', 'REIMBURSEMENT_METHODOLOGY': 'Billed Charges', 'REIMBURSEMENT_FLAT_FEE': 'N/A', 'REIMBURSEMENT_DIAG_CODES': 'N/A', 'REIMBURSEMENT_GROUPER': 'N/A', 'REIMBURSEMENT_ADMITTYPE_CODES': 'N/A', 'CONTRACT_PROGRAM': [], 'FULL_METHODOLOGY': 'one hundred percent (100%) of Physician Group allowable billed charges', 'REIMBURSEMENT_DESCRIBE_EXCEPTION': 'N/A', 'page_num': '1', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION': 'N/A', 'REIMBURSEMENT_FEE_SCHEDULE': 'N/A', 'CONTRACT_MARKETPLACE_METAL_LEVEL': [], 'LOB_PRICING_TERMS_EFFECTIVE_DATE': 'December 1, 2007', 'Filename': '2007-12-01 California Emergency Physicians AMD_MU.txt'}, {'REIMBURSEMENT_STATUS_INDICATOR_CODES': 'N/A', 'CONTRACT_NETWORK': [], 'REIMBURSEMENT_GROUPER_CODES': 'N/A', 'GREATER_OF_LANGUAGE_IND': 'N', 'LESSER_OF_LANGUAGE_IND': 'N', 'REIMBURSEMENT_EXCEPTION_IND': 'Y', 'SERVICE': 'Medicare Resource Based Relative Value Scale (RBRVS)', 'LOB_PRICING_TERMS_TERMINATION_DATE': '11/20/07', 'REIMBURSEMENT_REVENUE_CODES': 'N/A', 'PRODUCT': ['Health Net'], 'CONTRACT_LOB': ['Medicare'], 'REIMBURSEMENT_PLACEOFSERVICE_CODES': 'N/A', 'REIMBURSEMENT_PROC_CODES': 'N/A', 'RATE_ESCALATOR_IND': 'N', 'REIMBURSEMENT_RATE': 'N/A', 'REIMBURSEMENT_METHODOLOGY': 'Medicare Fee Schedule', 'REIMBURSEMENT_FLAT_FEE': 'N/A', 'REIMBURSEMENT_DIAG_CODES': 'N/A', 'REIMBURSEMENT_GROUPER': 'N/A', 'REIMBURSEMENT_ADMITTYPE_CODES': 'N/A', 'CONTRACT_PROGRAM': [], 'FULL_METHODOLOGY': 'In the event that potential CMS changes to Medicare Resource Based Relative Value Scale (RBRVS) result in an aggregate 3% change, either positively or negatively, either party may initiate a meet and confer process which will determine impact and/or potential changes to reimbursement.', 'REIMBURSEMENT_DESCRIBE_EXCEPTION': 'In the event that potential CMS changes to Medicare Resource Based Relative Value Scale (RBRVS) result in an aggregate 3% change, either positively or negatively, either party may initiate a meet and confer process which will determine impact and/or potential changes to reimbursement.', 'page_num': '2', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION': 'N/A', 'REIMBURSEMENT_FEE_SCHEDULE': 'Medicare Resource Based Relative Value Scale (RBRVS)', 'CONTRACT_MARKETPLACE_METAL_LEVEL': [], 'LOB_PRICING_TERMS_EFFECTIVE_DATE': '11/20/07', 'Filename': '2007-12-01 California Emergency Physicians AMD_MU.txt'}]\n", - "Processed 2007-12-01 California Emergency Physicians AMD_MU.txt\n", - "TD Results: [{'CONTRACT_LOB': 'N/A', 'CONTRACT_PROGRAM': 'N/A', 'CONTRACT_NETWORK': 'N/A', 'PRODUCT': 'moda IMAGING SERVICES', 'page_num': '1', 'Filename': '2013-01-01 Amendment MA FE PeaceHealth TIN 931251530 & 800537724.txt', 'CONTRACT_MARKETPLACE_METAL_LEVEL': 'N/A', 'LOB_PRICING_TERMS_EFFECTIVE_DATE': 'N/A', 'LOB_PRICING_TERMS_TERMINATION_DATE': 'N/A'}, {'CONTRACT_LOB': 'N/A', 'CONTRACT_PROGRAM': 'N/A', 'CONTRACT_NETWORK': 'N/A', 'PRODUCT': 'N/A', 'page_num': '2', 'Filename': '2013-01-01 Amendment MA FE PeaceHealth TIN 931251530 & 800537724.txt', 'CONTRACT_MARKETPLACE_METAL_LEVEL': 'N/A', 'LOB_PRICING_TERMS_EFFECTIVE_DATE': 'N/A', 'LOB_PRICING_TERMS_TERMINATION_DATE': 'N/A'}, {'CONTRACT_LOB': 'Medicare Advantage', 'CONTRACT_PROGRAM': 'N/A', 'CONTRACT_NETWORK': 'N/A', 'PRODUCT': 'N/A', 'page_num': '3', 'Filename': '2013-01-01 Amendment MA FE PeaceHealth TIN 931251530 & 800537724.txt', 'CONTRACT_MARKETPLACE_METAL_LEVEL': 'N/A', 'LOB_PRICING_TERMS_EFFECTIVE_DATE': 'January 1, 2013', 'LOB_PRICING_TERMS_TERMINATION_DATE': 'January 1, 2013'}, {'CONTRACT_LOB': 'Medicare Advantage', 'CONTRACT_PROGRAM': 'N/A', 'CONTRACT_NETWORK': 'N/A', 'PRODUCT': 'N/A', 'page_num': '4', 'Filename': '2013-01-01 Amendment MA FE PeaceHealth TIN 931251530 & 800537724.txt', 'CONTRACT_MARKETPLACE_METAL_LEVEL': 'N/A', 'LOB_PRICING_TERMS_EFFECTIVE_DATE': 'January 1, 2013', 'LOB_PRICING_TERMS_TERMINATION_DATE': 'January 1, 2013'}, {'CONTRACT_LOB': 'Medicare, Medicaid', 'CONTRACT_PROGRAM': 'N/A', 'CONTRACT_NETWORK': 'ODS Plus Network, ODS PPO Advantage', 'PRODUCT': 'Oregon Community Health, Inc., ODS Health Plan, Inc.', 'page_num': '5', 'Filename': '2013-01-01 Amendment MA FE PeaceHealth TIN 931251530 & 800537724.txt', 'CONTRACT_MARKETPLACE_METAL_LEVEL': 'N/A', 'LOB_PRICING_TERMS_EFFECTIVE_DATE': 'N/A', 'LOB_PRICING_TERMS_TERMINATION_DATE': 'N/A'}]\n", - "BU Results: [{'SERVICE': 'Rural Health Clinic (RHC) services', 'REIMBURSEMENT_FLAT_FEE': '79.17', 'REIMBURSEMENT_RATE': 'N/A', 'FULL_METHODOLOGY': 'For services billed on a UB-04 (including any future editions) will be reimbursed at the RHC per visit rate of $79.17.', 'page_num': '3', 'Filename': '2013-01-01 Amendment MA FE PeaceHealth TIN 931251530 & 800537724.txt', 'LESSER_OF_LANGUAGE_IND': 'N', 'GREATER_OF_LANGUAGE_IND': 'N', 'REIMBURSEMENT_METHODOLOGY': 'Per Visit', 'REIMBURSEMENT_FEE_SCHEDULE': 'N/A', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION': 'N/A', 'REIMBURSEMENT_EXCEPTION_IND': 'N', 'REIMBURSEMENT_DESCRIBE_EXCEPTION': 'N/A', 'RATE_ESCALATOR_IND': 'N', 'REIMBURSEMENT_ADMITTYPE_CODES': 'N/A', 'REIMBURSEMENT_DIAG_CODES': 'N/A', 'REIMBURSEMENT_GROUPER_CODES': 'N/A', 'REIMBURSEMENT_GROUPER': 'N/A', 'REIMBURSEMENT_PLACEOFSERVICE_CODES': 'N/A', 'REIMBURSEMENT_PROC_CODES': ['G0009', '90669', '90670', '90732', 'G0008', '90655-90663'], 'REIMBURSEMENT_REVENUE_CODES': 'N/A', 'REIMBURSEMENT_STATUS_INDICATOR_CODES': 'N/A'}, {'SERVICE': 'Pneumococcal and influenza vaccinations', 'REIMBURSEMENT_FLAT_FEE': '87.83', 'REIMBURSEMENT_RATE': 'N/A', 'FULL_METHODOLOGY': 'For services billed on a CMS 1500 (including any future editions) for pneumococcal and influenza vaccinations will be allowed as follows: G0009, 90669, 90670, 90732 $87.83', 'page_num': '3', 'Filename': '2013-01-01 Amendment MA FE PeaceHealth TIN 931251530 & 800537724.txt', 'LESSER_OF_LANGUAGE_IND': 'N', 'GREATER_OF_LANGUAGE_IND': 'N', 'REIMBURSEMENT_METHODOLOGY': 'Medicare Fee Schedule', 'REIMBURSEMENT_FEE_SCHEDULE': 'CMS', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION': 'N/A', 'REIMBURSEMENT_EXCEPTION_IND': 'N', 'REIMBURSEMENT_DESCRIBE_EXCEPTION': 'N/A', 'RATE_ESCALATOR_IND': 'N', 'REIMBURSEMENT_ADMITTYPE_CODES': 'N/A', 'REIMBURSEMENT_DIAG_CODES': 'N/A', 'REIMBURSEMENT_GROUPER_CODES': 'N/A', 'REIMBURSEMENT_GROUPER': 'N/A', 'REIMBURSEMENT_PLACEOFSERVICE_CODES': 'N/A', 'REIMBURSEMENT_PROC_CODES': ['G0009', '90669', '90670', '90732'], 'REIMBURSEMENT_REVENUE_CODES': 'N/A', 'REIMBURSEMENT_STATUS_INDICATOR_CODES': 'N/A'}, {'SERVICE': 'Vaccinations', 'REIMBURSEMENT_FLAT_FEE': '47.09', 'REIMBURSEMENT_RATE': 'N/A', 'FULL_METHODOLOGY': 'For services billed on a CMS 1500 (including any future editions) for pneumococcal and influenza vaccinations will be allowed as follows: G0008, 90655-90663 $47.09', 'page_num': '3', 'Filename': '2013-01-01 Amendment MA FE PeaceHealth TIN 931251530 & 800537724.txt', 'LESSER_OF_LANGUAGE_IND': 'N', 'GREATER_OF_LANGUAGE_IND': 'N', 'REIMBURSEMENT_METHODOLOGY': 'Medicare Fee Schedule', 'REIMBURSEMENT_FEE_SCHEDULE': 'CMS', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION': 'N/A', 'REIMBURSEMENT_EXCEPTION_IND': 'N', 'REIMBURSEMENT_DESCRIBE_EXCEPTION': 'N/A', 'RATE_ESCALATOR_IND': 'N', 'REIMBURSEMENT_ADMITTYPE_CODES': 'N/A', 'REIMBURSEMENT_DIAG_CODES': 'N/A', 'REIMBURSEMENT_GROUPER_CODES': 'N/A', 'REIMBURSEMENT_GROUPER': 'N/A', 'REIMBURSEMENT_PLACEOFSERVICE_CODES': 'N/A', 'REIMBURSEMENT_PROC_CODES': ['G0008', '90655-90663'], 'REIMBURSEMENT_REVENUE_CODES': 'N/A', 'REIMBURSEMENT_STATUS_INDICATOR_CODES': 'N/A'}, {'SERVICE': 'Rural Health Clinic services billed on UB-04', 'REIMBURSEMENT_FLAT_FEE': '79.17', 'REIMBURSEMENT_RATE': 'N/A', 'FULL_METHODOLOGY': 'For services billed on a UB-04 (including any future editions) will be reimbursed at the RHC per visit rate of $79.17.', 'page_num': '4', 'Filename': '2013-01-01 Amendment MA FE PeaceHealth TIN 931251530 & 800537724.txt', 'LESSER_OF_LANGUAGE_IND': 'N', 'GREATER_OF_LANGUAGE_IND': 'N', 'REIMBURSEMENT_METHODOLOGY': 'Per Visit', 'REIMBURSEMENT_FEE_SCHEDULE': 'N/A', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION': 'N/A', 'REIMBURSEMENT_EXCEPTION_IND': 'N', 'REIMBURSEMENT_DESCRIBE_EXCEPTION': 'N/A', 'RATE_ESCALATOR_IND': 'N', 'REIMBURSEMENT_ADMITTYPE_CODES': 'N/A', 'REIMBURSEMENT_DIAG_CODES': 'N/A', 'REIMBURSEMENT_GROUPER_CODES': 'N/A', 'REIMBURSEMENT_GROUPER': 'N/A', 'REIMBURSEMENT_PLACEOFSERVICE_CODES': 'N/A', 'REIMBURSEMENT_PROC_CODES': 'G0009, 90669, 90670, 90732, G0008, 90655-90663', 'REIMBURSEMENT_REVENUE_CODES': 'N/A', 'REIMBURSEMENT_STATUS_INDICATOR_CODES': 'N/A'}, {'SERVICE': 'Pneumococcal and influenza vaccinations billed on CMS 1500', 'REIMBURSEMENT_FLAT_FEE': '87.83', 'REIMBURSEMENT_RATE': 'N/A', 'FULL_METHODOLOGY': 'For services billed on a CMS 1500 (including any future editions) for pneumococcal and influenza vaccinations will be allowed as follows: G0009, 90669, 90670, 90732 $87.83', 'page_num': '4', 'Filename': '2013-01-01 Amendment MA FE PeaceHealth TIN 931251530 & 800537724.txt', 'LESSER_OF_LANGUAGE_IND': 'N', 'GREATER_OF_LANGUAGE_IND': 'N', 'REIMBURSEMENT_METHODOLOGY': 'Medicare Fee Schedule', 'REIMBURSEMENT_FEE_SCHEDULE': 'CMS', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION': 'N/A', 'REIMBURSEMENT_EXCEPTION_IND': 'N', 'REIMBURSEMENT_DESCRIBE_EXCEPTION': 'N/A', 'RATE_ESCALATOR_IND': 'N', 'REIMBURSEMENT_ADMITTYPE_CODES': 'N/A', 'REIMBURSEMENT_DIAG_CODES': 'N/A', 'REIMBURSEMENT_GROUPER_CODES': 'N/A', 'REIMBURSEMENT_GROUPER': 'N/A', 'REIMBURSEMENT_PLACEOFSERVICE_CODES': 'N/A', 'REIMBURSEMENT_PROC_CODES': ['G0009', '90669', '90670', '90732'], 'REIMBURSEMENT_REVENUE_CODES': 'N/A', 'REIMBURSEMENT_STATUS_INDICATOR_CODES': 'N/A'}, {'SERVICE': 'Other vaccinations billed on CMS 1500', 'REIMBURSEMENT_FLAT_FEE': '47.09', 'REIMBURSEMENT_RATE': 'N/A', 'FULL_METHODOLOGY': 'For services billed on a CMS 1500 (including any future editions) for pneumococcal and influenza vaccinations will be allowed as follows: G0008, 90655-90663 $47.09', 'page_num': '4', 'Filename': '2013-01-01 Amendment MA FE PeaceHealth TIN 931251530 & 800537724.txt', 'LESSER_OF_LANGUAGE_IND': 'N', 'GREATER_OF_LANGUAGE_IND': 'N', 'REIMBURSEMENT_METHODOLOGY': 'Medicare Fee Schedule', 'REIMBURSEMENT_FEE_SCHEDULE': 'CMS', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION': 'N/A', 'REIMBURSEMENT_EXCEPTION_IND': 'N', 'REIMBURSEMENT_DESCRIBE_EXCEPTION': 'N/A', 'RATE_ESCALATOR_IND': 'N', 'REIMBURSEMENT_ADMITTYPE_CODES': 'N/A', 'REIMBURSEMENT_DIAG_CODES': 'N/A', 'REIMBURSEMENT_GROUPER_CODES': 'N/A', 'REIMBURSEMENT_GROUPER': 'N/A', 'REIMBURSEMENT_PLACEOFSERVICE_CODES': 'N/A', 'REIMBURSEMENT_PROC_CODES': ['G0008', '90655-90663'], 'REIMBURSEMENT_REVENUE_CODES': 'N/A', 'REIMBURSEMENT_STATUS_INDICATOR_CODES': 'N/A'}]\n", - "All Keys: {'REIMBURSEMENT_STATUS_INDICATOR_CODES', 'CONTRACT_NETWORK', 'REIMBURSEMENT_GROUPER_CODES', 'GREATER_OF_LANGUAGE_IND', 'LESSER_OF_LANGUAGE_IND', 'REIMBURSEMENT_EXCEPTION_IND', 'SERVICE', 'LOB_PRICING_TERMS_TERMINATION_DATE', 'REIMBURSEMENT_REVENUE_CODES', 'PRODUCT', 'CONTRACT_LOB', 'REIMBURSEMENT_PLACEOFSERVICE_CODES', 'REIMBURSEMENT_PROC_CODES', 'RATE_ESCALATOR_IND', 'REIMBURSEMENT_RATE', 'REIMBURSEMENT_METHODOLOGY', 'REIMBURSEMENT_FLAT_FEE', 'REIMBURSEMENT_DIAG_CODES', 'REIMBURSEMENT_GROUPER', 'REIMBURSEMENT_ADMITTYPE_CODES', 'CONTRACT_PROGRAM', 'FULL_METHODOLOGY', 'REIMBURSEMENT_DESCRIBE_EXCEPTION', 'page_num', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION', 'REIMBURSEMENT_FEE_SCHEDULE', 'CONTRACT_MARKETPLACE_METAL_LEVEL', 'LOB_PRICING_TERMS_EFFECTIVE_DATE', 'Filename'}\n", - "Date Fields: {'LOB_PRICING_TERMS_EFFECTIVE_DATE': ['N/A', 'January 1, 2013'], 'LOB_PRICING_TERMS_TERMINATION_DATE': ['N/A', 'January 1, 2013']}\n", - "Combined Results: [{'REIMBURSEMENT_STATUS_INDICATOR_CODES': 'N/A', 'CONTRACT_NETWORK': [], 'REIMBURSEMENT_GROUPER_CODES': 'N/A', 'GREATER_OF_LANGUAGE_IND': 'N', 'LESSER_OF_LANGUAGE_IND': 'N', 'REIMBURSEMENT_EXCEPTION_IND': 'N', 'SERVICE': 'Rural Health Clinic (RHC) services', 'LOB_PRICING_TERMS_TERMINATION_DATE': 'January 1, 2013', 'REIMBURSEMENT_REVENUE_CODES': 'N/A', 'PRODUCT': [], 'CONTRACT_LOB': ['Medicare Advantage'], 'REIMBURSEMENT_PLACEOFSERVICE_CODES': 'N/A', 'REIMBURSEMENT_PROC_CODES': 'G0009, 90669, 90670, 90732', 'RATE_ESCALATOR_IND': 'N', 'REIMBURSEMENT_RATE': 'N/A', 'REIMBURSEMENT_METHODOLOGY': 'Per Visit', 'REIMBURSEMENT_FLAT_FEE': '79.17', 'REIMBURSEMENT_DIAG_CODES': 'N/A', 'REIMBURSEMENT_GROUPER': 'N/A', 'REIMBURSEMENT_ADMITTYPE_CODES': 'N/A', 'CONTRACT_PROGRAM': [], 'FULL_METHODOLOGY': 'For services billed on a UB-04 (including any future editions) will be reimbursed at the RHC per visit rate of $79.17.', 'REIMBURSEMENT_DESCRIBE_EXCEPTION': 'N/A', 'page_num': '3', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION': 'N/A', 'REIMBURSEMENT_FEE_SCHEDULE': 'N/A', 'CONTRACT_MARKETPLACE_METAL_LEVEL': [], 'LOB_PRICING_TERMS_EFFECTIVE_DATE': 'January 1, 2013', 'Filename': '2013-01-01 Amendment MA FE PeaceHealth TIN 931251530 & 800537724.txt'}, {'REIMBURSEMENT_STATUS_INDICATOR_CODES': 'N/A', 'CONTRACT_NETWORK': [], 'REIMBURSEMENT_GROUPER_CODES': 'N/A', 'GREATER_OF_LANGUAGE_IND': 'N', 'LESSER_OF_LANGUAGE_IND': 'N', 'REIMBURSEMENT_EXCEPTION_IND': 'N', 'SERVICE': 'Pneumococcal and influenza vaccinations', 'LOB_PRICING_TERMS_TERMINATION_DATE': 'January 1, 2013', 'REIMBURSEMENT_REVENUE_CODES': 'N/A', 'PRODUCT': [], 'CONTRACT_LOB': ['Medicare Advantage'], 'REIMBURSEMENT_PLACEOFSERVICE_CODES': 'N/A', 'REIMBURSEMENT_PROC_CODES': '90732', 'RATE_ESCALATOR_IND': 'N', 'REIMBURSEMENT_RATE': 'N/A', 'REIMBURSEMENT_METHODOLOGY': 'Medicare Fee Schedule', 'REIMBURSEMENT_FLAT_FEE': '87.83', 'REIMBURSEMENT_DIAG_CODES': 'N/A', 'REIMBURSEMENT_GROUPER': 'N/A', 'REIMBURSEMENT_ADMITTYPE_CODES': 'N/A', 'CONTRACT_PROGRAM': [], 'FULL_METHODOLOGY': 'For services billed on a CMS 1500 (including any future editions) for pneumococcal and influenza vaccinations will be allowed as follows: G0009, 90669, 90670, 90732 $87.83', 'REIMBURSEMENT_DESCRIBE_EXCEPTION': 'N/A', 'page_num': '3', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION': 'N/A', 'REIMBURSEMENT_FEE_SCHEDULE': 'CMS', 'CONTRACT_MARKETPLACE_METAL_LEVEL': [], 'LOB_PRICING_TERMS_EFFECTIVE_DATE': 'January 1, 2013', 'Filename': '2013-01-01 Amendment MA FE PeaceHealth TIN 931251530 & 800537724.txt'}, {'REIMBURSEMENT_STATUS_INDICATOR_CODES': 'N/A', 'CONTRACT_NETWORK': [], 'REIMBURSEMENT_GROUPER_CODES': 'N/A', 'GREATER_OF_LANGUAGE_IND': 'N', 'LESSER_OF_LANGUAGE_IND': 'N', 'REIMBURSEMENT_EXCEPTION_IND': 'N', 'SERVICE': 'Vaccinations', 'LOB_PRICING_TERMS_TERMINATION_DATE': 'January 1, 2013', 'REIMBURSEMENT_REVENUE_CODES': 'N/A', 'PRODUCT': [], 'CONTRACT_LOB': ['Medicare Advantage'], 'REIMBURSEMENT_PLACEOFSERVICE_CODES': 'N/A', 'REIMBURSEMENT_PROC_CODES': '90655-90663', 'RATE_ESCALATOR_IND': 'N', 'REIMBURSEMENT_RATE': 'N/A', 'REIMBURSEMENT_METHODOLOGY': 'Medicare Fee Schedule', 'REIMBURSEMENT_FLAT_FEE': '47.09', 'REIMBURSEMENT_DIAG_CODES': 'N/A', 'REIMBURSEMENT_GROUPER': 'N/A', 'REIMBURSEMENT_ADMITTYPE_CODES': 'N/A', 'CONTRACT_PROGRAM': [], 'FULL_METHODOLOGY': 'For services billed on a CMS 1500 (including any future editions) for pneumococcal and influenza vaccinations will be allowed as follows: G0008, 90655-90663 $47.09', 'REIMBURSEMENT_DESCRIBE_EXCEPTION': 'N/A', 'page_num': '3', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION': 'N/A', 'REIMBURSEMENT_FEE_SCHEDULE': 'CMS', 'CONTRACT_MARKETPLACE_METAL_LEVEL': [], 'LOB_PRICING_TERMS_EFFECTIVE_DATE': 'January 1, 2013', 'Filename': '2013-01-01 Amendment MA FE PeaceHealth TIN 931251530 & 800537724.txt'}, {'REIMBURSEMENT_STATUS_INDICATOR_CODES': 'N/A', 'CONTRACT_NETWORK': [], 'REIMBURSEMENT_GROUPER_CODES': 'N/A', 'GREATER_OF_LANGUAGE_IND': 'N', 'LESSER_OF_LANGUAGE_IND': 'N', 'REIMBURSEMENT_EXCEPTION_IND': 'N', 'SERVICE': 'Rural Health Clinic services billed on UB-04', 'LOB_PRICING_TERMS_TERMINATION_DATE': 'January 1, 2013', 'REIMBURSEMENT_REVENUE_CODES': 'N/A', 'PRODUCT': [], 'CONTRACT_LOB': ['Medicare Advantage'], 'REIMBURSEMENT_PLACEOFSERVICE_CODES': 'N/A', 'REIMBURSEMENT_PROC_CODES': 'G0009, 90669, 90670, 90732, G0008, 90655-90663', 'RATE_ESCALATOR_IND': 'N', 'REIMBURSEMENT_RATE': 'N/A', 'REIMBURSEMENT_METHODOLOGY': 'Per Visit', 'REIMBURSEMENT_FLAT_FEE': '79.17', 'REIMBURSEMENT_DIAG_CODES': 'N/A', 'REIMBURSEMENT_GROUPER': 'N/A', 'REIMBURSEMENT_ADMITTYPE_CODES': 'N/A', 'CONTRACT_PROGRAM': [], 'FULL_METHODOLOGY': 'For services billed on a UB-04 (including any future editions) will be reimbursed at the RHC per visit rate of $79.17.', 'REIMBURSEMENT_DESCRIBE_EXCEPTION': 'N/A', 'page_num': '4', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION': 'N/A', 'REIMBURSEMENT_FEE_SCHEDULE': 'N/A', 'CONTRACT_MARKETPLACE_METAL_LEVEL': [], 'LOB_PRICING_TERMS_EFFECTIVE_DATE': 'January 1, 2013', 'Filename': '2013-01-01 Amendment MA FE PeaceHealth TIN 931251530 & 800537724.txt'}, {'REIMBURSEMENT_STATUS_INDICATOR_CODES': 'N/A', 'CONTRACT_NETWORK': [], 'REIMBURSEMENT_GROUPER_CODES': 'N/A', 'GREATER_OF_LANGUAGE_IND': 'N', 'LESSER_OF_LANGUAGE_IND': 'N', 'REIMBURSEMENT_EXCEPTION_IND': 'N', 'SERVICE': 'Pneumococcal and influenza vaccinations billed on CMS 1500', 'LOB_PRICING_TERMS_TERMINATION_DATE': 'January 1, 2013', 'REIMBURSEMENT_REVENUE_CODES': 'N/A', 'PRODUCT': [], 'CONTRACT_LOB': ['Medicare Advantage'], 'REIMBURSEMENT_PLACEOFSERVICE_CODES': 'N/A', 'REIMBURSEMENT_PROC_CODES': '90732', 'RATE_ESCALATOR_IND': 'N', 'REIMBURSEMENT_RATE': 'N/A', 'REIMBURSEMENT_METHODOLOGY': 'Medicare Fee Schedule', 'REIMBURSEMENT_FLAT_FEE': '87.83', 'REIMBURSEMENT_DIAG_CODES': 'N/A', 'REIMBURSEMENT_GROUPER': 'N/A', 'REIMBURSEMENT_ADMITTYPE_CODES': 'N/A', 'CONTRACT_PROGRAM': [], 'FULL_METHODOLOGY': 'For services billed on a CMS 1500 (including any future editions) for pneumococcal and influenza vaccinations will be allowed as follows: G0009, 90669, 90670, 90732 $87.83', 'REIMBURSEMENT_DESCRIBE_EXCEPTION': 'N/A', 'page_num': '4', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION': 'N/A', 'REIMBURSEMENT_FEE_SCHEDULE': 'CMS', 'CONTRACT_MARKETPLACE_METAL_LEVEL': [], 'LOB_PRICING_TERMS_EFFECTIVE_DATE': 'January 1, 2013', 'Filename': '2013-01-01 Amendment MA FE PeaceHealth TIN 931251530 & 800537724.txt'}, {'REIMBURSEMENT_STATUS_INDICATOR_CODES': 'N/A', 'CONTRACT_NETWORK': [], 'REIMBURSEMENT_GROUPER_CODES': 'N/A', 'GREATER_OF_LANGUAGE_IND': 'N', 'LESSER_OF_LANGUAGE_IND': 'N', 'REIMBURSEMENT_EXCEPTION_IND': 'N', 'SERVICE': 'Other vaccinations billed on CMS 1500', 'LOB_PRICING_TERMS_TERMINATION_DATE': 'January 1, 2013', 'REIMBURSEMENT_REVENUE_CODES': 'N/A', 'PRODUCT': [], 'CONTRACT_LOB': ['Medicare Advantage'], 'REIMBURSEMENT_PLACEOFSERVICE_CODES': 'N/A', 'REIMBURSEMENT_PROC_CODES': '90655-90663', 'RATE_ESCALATOR_IND': 'N', 'REIMBURSEMENT_RATE': 'N/A', 'REIMBURSEMENT_METHODOLOGY': 'Medicare Fee Schedule', 'REIMBURSEMENT_FLAT_FEE': '47.09', 'REIMBURSEMENT_DIAG_CODES': 'N/A', 'REIMBURSEMENT_GROUPER': 'N/A', 'REIMBURSEMENT_ADMITTYPE_CODES': 'N/A', 'CONTRACT_PROGRAM': [], 'FULL_METHODOLOGY': 'For services billed on a CMS 1500 (including any future editions) for pneumococcal and influenza vaccinations will be allowed as follows: G0008, 90655-90663 $47.09', 'REIMBURSEMENT_DESCRIBE_EXCEPTION': 'N/A', 'page_num': '4', 'REIMBURSEMENT_FEE_SCHEDULE_VERSION': 'N/A', 'REIMBURSEMENT_FEE_SCHEDULE': 'CMS', 'CONTRACT_MARKETPLACE_METAL_LEVEL': [], 'LOB_PRICING_TERMS_EFFECTIVE_DATE': 'January 1, 2013', 'Filename': '2013-01-01 Amendment MA FE PeaceHealth TIN 931251530 & 800537724.txt'}]\n", - "Processed 2013-01-01 Amendment MA FE PeaceHealth TIN 931251530 & 800537724.txt\n" - ] - } - ], - "source": [ - "import os\n", - "import pandas as pd\n", - "import postprocess\n", - "import utils\n", - "\n", - "\n", - "def clean_td(td):\n", - " td_clean = []\n", - " for d in td:\n", - " new_d = {}\n", - " for k, v in d.items():\n", - " if \"DATE\" in k:\n", - " new_d[k] = v if isinstance(v, list) else [v]\n", - " elif k not in [\"page_num\", \"Filename\"]:\n", - " if isinstance(v, str) and \",\" in v:\n", - " new_d[k] = [item.strip() for item in v.split(\",\")]\n", - " elif v == \"N/A\":\n", - " new_d[k] = []\n", - " else:\n", - " new_d[k] = [v] if isinstance(v, str) else v\n", - " else:\n", - " new_d[k] = v\n", - " td_clean.append(new_d)\n", - " return td_clean\n", - "\n", - "\n", - "def get_unique_keys(dicts):\n", - " keys = set()\n", - " for d in dicts:\n", - " keys.update(d.keys())\n", - " return keys\n", - "\n", - "\n", - "def get_unique_date_fields(td_results):\n", - " unique_date_fields = {}\n", - " for td in td_results:\n", - " for key, value in td.items():\n", - " if \"DATE\" in key:\n", - " if key not in unique_date_fields:\n", - " unique_date_fields[key] = set()\n", - " unique_date_fields[key].update(\n", - " value if isinstance(value, list) else [value]\n", - " )\n", - " for key in unique_date_fields:\n", - " unique_date_fields[key] = list(unique_date_fields[key])\n", - " return unique_date_fields\n", - "\n", - "\n", - "def GENERATE_PROMPT(bu_dict, td_dicts, page, field_name=None, values=None):\n", - " if field_name and values:\n", - " return f\"\"\"### PAGE START ### {page} ### PAGE END\n", - " \n", - "Field: {field_name}\n", - "Values: {values}\n", - "\n", - "Listed above is a page of a contract, as well as the potential values for the {field_name} field.\n", - "Your job is to identify which of these values is the most appropriate based on the page content.\n", - "\n", - "Write ONLY the value that is most appropriate. Do not return any additional text beyond the value itself.\n", - "\"\"\"\n", - " else:\n", - " return f\"\"\"### PAGE START ### {page} ### PAGE END\n", - " \n", - "Service: {bu_dict['SERVICE']}\n", - "Methodology: {bu_dict['FULL_METHODOLOGY']}\n", - "\n", - "Listed above is a page of a contract, as well as a Service and Methodology found on this page. \n", - "Your job is to identify which of the following entities this specific Service is associated with. \n", - "\n", - "----Change Below----\n", - "\n", - "Here are the entities, represented as dictionary objects:\n", - "\n", - "{td_dicts}\n", - "\n", - "Write ONLY the number of the dictionary that is most associated with the Service and Methodology of interest. Do not return any additional text beyond the digit itself. \n", - "\"\"\"\n", - "\n", - "\n", - "def merge_results(td_results, bu_results, text_dict):\n", - " all_keys = get_unique_keys(td_results) | get_unique_keys(bu_results)\n", - " print(\"All Keys:\", all_keys)\n", - "\n", - " date_fields = get_unique_date_fields(td_results)\n", - " print(\"Date Fields:\", date_fields)\n", - "\n", - " merged_results = []\n", - " for bu in bu_results:\n", - " merged = {key: bu.get(key, \"\") for key in all_keys}\n", - " td_on_page = [td for td in td_results if td[\"page_num\"] == bu[\"page_num\"]]\n", - "\n", - " for td in td_on_page:\n", - " for key, value in td.items():\n", - " if not merged[key]:\n", - " merged[key] = value\n", - " elif (\n", - " isinstance(value, list)\n", - " and value\n", - " and not isinstance(merged[key], list)\n", - " ):\n", - " merged[key] = value\n", - " elif isinstance(value, list) and value:\n", - " merged[key].extend(value)\n", - "\n", - " for date_key, date_values in date_fields.items():\n", - " if date_key not in merged or not merged[date_key]:\n", - " merged[date_key] = date_values\n", - " else:\n", - " merged[date_key].extend(\n", - " [val for val in date_values if val not in merged[date_key]]\n", - " )\n", - "\n", - " for key in all_keys:\n", - " if isinstance(merged[key], list) and len(merged[key]) > 1:\n", - " page_num = bu[\"page_num\"]\n", - " page_text = text_dict.get(page_num, \"\")\n", - " prompt = GENERATE_PROMPT(\n", - " bu, td_on_page, page_text, field_name=key, values=merged[key]\n", - " )\n", - " response = claude_funcs.invoke_claude_3(prompt, max_tokens=4000)\n", - " try:\n", - " selected_value = response.strip()\n", - " merged[key] = selected_value\n", - " except Exception as e:\n", - " print(f\"Error processing LLM response for key {key}: {e}\")\n", - " merged[key] = \", \".join(merged[key])\n", - "\n", - " merged_results.append(merged)\n", - "\n", - " return merged_results\n", - "\n", - "\n", - "def process_file(filename, input_dict):\n", - " contract_text = input_dict[filename]\n", - "\n", - " # Preprocess\n", - " contract_text = preprocess.clean_newlines(contract_text)\n", - " text_dict = preprocess.split_text(contract_text)\n", - "\n", - " # Run Top Down\n", - " td_results = prompt_funcs.run_top_down(\n", - " filename, text_dict\n", - " ) # Returns list of dictionaries for each page\n", - " print(\"TD Results:\", td_results)\n", - "\n", - " # Run Bottom Up\n", - " bu_results = prompt_funcs.run_bottom_up(\n", - " filename, text_dict\n", - " ) # Returns list of dictionaries\n", - " print(\"BU Results:\", bu_results)\n", - "\n", - " # Combine\n", - " combined_results = merge_results(clean_td(td_results), bu_results, text_dict)\n", - " print(\"Combined Results:\", combined_results)\n", - "\n", - " # Convert to DataFrame\n", - " combined_df = pd.DataFrame(combined_results)\n", - "\n", - " # Post-process combined results\n", - " # post_processed_combined_df = postprocess.postprocess_results(combined_df)\n", - " # print(\"Post-processed Results:\", post_processed_combined_df)\n", - "\n", - " # Create directories\n", - " base_filename = os.path.splitext(filename)[0]\n", - " output_dir = os.path.join(\"output\", base_filename)\n", - " os.makedirs(output_dir, exist_ok=True)\n", - "\n", - " # Save results\n", - " pd.DataFrame(td_results).to_csv(\n", - " os.path.join(output_dir, \"td_results.csv\"), index=False\n", - " )\n", - " pd.DataFrame(bu_results).to_csv(\n", - " os.path.join(output_dir, \"bu_results.csv\"), index=False\n", - " )\n", - " combined_df.to_csv(os.path.join(output_dir, \"combined_results.csv\"), index=False)\n", - " # post_processed_combined_df.to_csv(os.path.join(output_dir, 'combined_results.csv'), index=False)\n", - "\n", - "\n", - "def process_all_files(input_dict):\n", - " for filename in input_dict.keys():\n", - " process_file(filename, input_dict)\n", - " print(f\"Processed {filename}\")\n", - "\n", - "\n", - "# Example usage\n", - "input_dict = utils.read_input(path=\"../data/\")\n", - "process_all_files(input_dict)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Usage example:\n", - "# save_combined_to_csv(combined, 'combined_output.csv')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "utils.consolidate_individual(input_folder=\"../results/\", output_folder=\"../output/\")" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.3" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/fieldExtraction/src/main.py b/fieldExtraction/src/main.py deleted file mode 100644 index ac43128..0000000 --- a/fieldExtraction/src/main.py +++ /dev/null @@ -1,84 +0,0 @@ -""" main.py -Doczy AI - Pricing Before Carveouts: Main Execution Module - -This module is the main entry point for the Priority B: Pricing Before Carveouts section of Doczy AI. - -Functional Overview: -- In test mode, a simple Claude 3 model invocation is demonstrated. -- In normal mode, the module reads input documents, processes each document concurrently, - and manages exceptions and errors during processing. -- The processed results can be optionally consolidated into a single CSV file. -""" - -# Imports -import pandas as pd -import os - -import utils -import config -import claude_funcs -import file_processing - - -def main(): - if config.TEST: - print( - claude_funcs.invoke_claude_3("Write 'test', nothing more.", max_tokens=10) - ) - else: - # Read contract txt - input_dict = utils.read_input() - - if config.FILTER_ALREADY_PROCESSED: - input_dict = utils.filter_already_processed(input_dict) - - def process_item(item): - key, value = item - if utils.contains_reimbursement(item[1], 0): - try: - file_processing.process_file(item) - # prompt_funcs.bottom_up(item) - except Exception as e: - # Print the error message and traceback - print(f"Error processing item {key}: {e}") - traceback.print_exc() - - with concurrent.futures.ThreadPoolExecutor( - max_workers=config.MAX_WORKERS - ) as executor: - # Process each item individually - futures = [ - executor.submit(process_item, item) for item in input_dict.items() - ] - - # Wait for all futures to complete - for future in concurrent.futures.as_completed(futures): - # Retrieve any exceptions raised by the thread - try: - future.result() - except Exception as e: - print(f"Error: {e}") - - # Write Consolidated Output - if config.WRITE_OUTPUT: - all_results_df = pd.concat(all_results).reset_index(drop=True) - all_results_df.drop("page_num", axis=1, inplace=True) - - # Reorder columns - final_df = all_results_df[ - [col for col in config.VALID_COLUMNS if col in all_results_df.columns] - + [ - col - for col in all_results_df.columns - if col not in config.VALID_COLUMNS - ] - ] - final_df.to_csv( - os.path.join( - config.CONSOLIDATED_OUTPUT_DIRECTORY, config.OUTPUT_CSV_PATH - ) - ) - - -if __name__ == "__main__": - main() diff --git a/fieldExtraction/src/merge_funcs.py b/fieldExtraction/src/merge_funcs.py deleted file mode 100644 index bb18a6a..0000000 --- a/fieldExtraction/src/merge_funcs.py +++ /dev/null @@ -1,59 +0,0 @@ -import prompts -import claude_funcs - - -def prompt_select_multiple(key, value, bu_dict, page): - prompt = prompts.MERGE_SELECT_PROMPT(key, value, bu_dict, page) - answer = claude_funcs.invoke_claude_3(prompt, max_tokens=4000) - return answer - - -def merge_results(td_results, bu_results, text_dict): - def find_td_dict(page_num): - """Helper function to find dictionary in td_results with matching page_num""" - for td in td_results: - if td["page_num"] == page_num: - return td - return None - - def get_value(td_dict, key, page_num, text_dict): - """Helper function to handle value selection based on the rules specified.""" - if td_dict is None: - # If there's no matching page, use recursion to look one page earlier - if int(page_num) > 1: - return get_value( - find_td_dict(int(page_num) - 1), key, int(page_num) - 1, text_dict - ), str(int(page_num) - 1) - else: - return "N/A", "N/A" # Base case if no previous pages exist - else: - value = td_dict.get(key, "N/A") - if value == "N/A" or value == "": - # If value is 'N/A' or empty, use recursion to look one page earlier - return get_value( - find_td_dict(int(page_num) - 1), key, int(page_num) - 1, text_dict - ), str(int(page_num) - 1) - elif "," in value and "DATE" not in key: - # Randomly select one of the comma-separated values - return prompt_select_multiple( - key, value, bu_dict, text_dict[page_num] - ), str(int(page_num)) - else: - return value, page_num - - merged_results = [] - for bu_dict in bu_results: - page_num = bu_dict["page_num"] - td_dict = find_td_dict(page_num) - - new_dict = bu_dict.copy() # Start with the bu_dict's data - # Add or overwrite keys from td_dict - if td_dict: - for key, value in td_dict.items(): - if key not in ["Filename", "page_num"]: - new_dict[key], new_dict[f"{key}_PG"] = get_value( - td_dict, key, page_num, text_dict - ) - - merged_results.append(new_dict) - return merged_results diff --git a/fieldExtraction/src/postprocess.py b/fieldExtraction/src/postprocess.py deleted file mode 100644 index e8168b7..0000000 --- a/fieldExtraction/src/postprocess.py +++ /dev/null @@ -1,84 +0,0 @@ -import pandas as pd -import re - -import postprocess_funcs -import config - - -def postprocess_results(combined_df): - - # Define valid values dictionary - valid_values_dict = { - "CONTRACT_LOB": config.VALID_LOBS, - "CONTRACT_PROGRAM": config.VALID_PROGRAMS, - "CONTRACT_NETWORK": config.VALID_NETWORKS, - } - - # Sanitize the combined data - try: - df = postprocess_funcs.sanitize_combined(combined_df) - except Exception as e: - print(f"Postprocessing Error - santize_combined : {e}") - - # Clean specific columns for exact matches - for field_list in [ - ["CONTRACT_LOB", "Corrected_LOB", config.VALID_LOBS], - ["CONTRACT_PROGRAM", "Corrected_PROGRAM", config.VALID_PROGRAMS], - ["CONTRACT_NETWORK", "Corrected_NETWORK", config.VALID_NETWORKS], - ]: - try: - postprocess_funcs.clean_columns_combined( - df, field_list[0], field_list[2], field_list[1] - ) - except Exception as e: - print(f"Postprocessing Error - clean_columns_combined : {e}") - - try: - postprocess_funcs.clean_columns_combined_fuzzy( - df, field_list[0], field_list[2], config.FUZZY_MATCH_THRESHOLD - ) - except Exception as e: - print(f"Postprocessing Error - clean_columns_combined_fuzzy : {e}") - - # Correct misplaced values across columns - try: - df = postprocess_funcs.correct_misplaced_values( - df, - ["CONTRACT_LOB", "CONTRACT_PROGRAM", "CONTRACT_NETWORK"], - valid_values_dict, - ) - except Exception as e: - print(f"Postprocessing Error - correct_misplaced_values : {e}") - - # Move percentages and large numbers to correct columns - try: - df = postprocess_funcs.move_percentage_to_rate(df) - except Exception as e: - print(f"Postprocessing Error - move_percentage_to_rate : {e}") - - # Replace N/As in "Not Covered" with 0% - try: - df = postprocess_funcs.set_rate_to_zero_if_not_covered(df) - except Exception as e: - print(f"Postprocessing Error - set_rate_to_zero_if_not_covered : {e}") - - # Adjust for adding or subtracting - try: - df = postprocess_funcs.adjust_reimbursement_rate(df) - except Exception as e: - print(f"Postprocessing Error - adjust_reimbursement_rate : {e}") - - # -- Deprecated -- - # Clean dates so that Termination and Effective aren't the same - # try: - # df = postprocessing_funcs.clean_dates(df) - # except Exception as e: - # print(f"Postprocessing Error - clean_dates : {e}") - - # Re order columns - column_order = [col for col in config.VALID_COLUMNS if col in df.columns] + [ - col for col in df.columns if col not in config.VALID_COLUMNS - ] - df = df[column_order] - - return df diff --git a/fieldExtraction/src/postprocess_funcs.py b/fieldExtraction/src/postprocess_funcs.py deleted file mode 100644 index e803cf2..0000000 --- a/fieldExtraction/src/postprocess_funcs.py +++ /dev/null @@ -1,523 +0,0 @@ -import pandas as pd -import re -import difflib - -import config - - -def sanitize_value(value): - """ - Sanitizes a given value by handling nulls, lists, and strings to ensure consistency in formatting. - - This function performs several cleanliness checks and transformations: - - It leaves null (NaN) values unchanged. - - Converts lists into comma-separated strings. - - Strips unnecessary characters from strings and handles strings that represent lists, ensuring individual elements are properly formatted. - - Parameters: - value (varied types): The value to be sanitized, which can be of any type including nulls, lists, or strings. - - Returns: - varied types: The sanitized value, which can be a string or the original type if no changes were needed. - """ - try: - if isinstance(value, list): - return ", ".join(str(v) for v in value) - elif isinstance(value, str): - value = value.strip("[]") - return ", ".join([item.strip(" '") for item in value.split(",")]) - elif pd.isna(value): - return "N/A" - except: - return value - - -def exact_match(val, valid_values): - """ - Compares a given string value against a list of valid values to determine if there is an exact match, case-insensitively. - - This function processes the input value by trimming whitespace and converting to uppercase for a case-insensitive comparison. - It then checks each item in the list of valid values (also treated case-insensitively) to find an exact match. If a match is found, - the function returns the valid value in its original form as specified in the list. If no match is found, it returns None. - - Parameters: - val (str): The value to be checked for an exact match. - valid_values (list of str): A list of valid values against which the input value is compared. - - Returns: - str or None: The matching valid value if found, or None if no exact match is found. - """ - val = val.strip().upper() - for valid_val in valid_values: - if val == valid_val.upper(): - return valid_val - return None - - -def clean_columns_combined(df, column_name, valid_values, new_column_name): - """ - Cleans and standardizes entries in a specified column of a DataFrame based on a list of valid values, creating a new column with standardized values. - - This function first sanitizes the values in the specified column. It then examines each entry in that column, - looking for any sub-values (separated by commas) that exactly match any of the provided valid values. If a match is found, - it is recorded in a new column. The function also tracks changes and compares the original and cleaned unique values. - - Parameters: - df (pandas.DataFrame): The DataFrame containing the data to be cleaned. - column_name (str): The name of the column to be cleaned. - valid_values (list of str): A list of valid values to be used for checking the entries in the specified column. - new_column_name (str): The name of the new column where cleaned, standardized values will be stored. - - Returns: - tuple: Contains arrays of original unique values, cleaned unique values, and a dictionary of changes from original to new values. - """ - changes = {} - df[column_name] = df[column_name].apply(sanitize_value) - original_values = df[column_name].unique() - - def update_column(entry): - if pd.notna(entry): - terms = entry.split(",") - for term in terms: - match = exact_match(term, valid_values) - if match: - return match - return None - - df[new_column_name] = df[column_name].apply(update_column) - cleaned_values = df[new_column_name].unique() - return original_values, cleaned_values, changes - - -def get_closest_match(val, valid_values, similarity_threshold=0.7): - """ - Finds the closest match for a given string from a list of valid values, using a similarity threshold. - - This function cleans the input value and compares it to each cleaned value in the valid values list using a fuzzy - matching technique. It returns the closest match that meets or exceeds the specified similarity threshold. If no - matches meet the threshold, the function returns None. - - Parameters: - val (str): The value to be matched. - valid_yvalues (list of str): A list of valid values against which the input value is compared. - similarity_threshold (float): The cutoff similarity score (between 0 and 1) below which matches are not considered. - - Returns: - str or None: The closest valid value if a match is found; otherwise, None. - """ - if pd.isna(val): - return None - val = val.strip().upper() - matches = difflib.get_close_matches( - val, [v.upper() for v in valid_values], n=1, cutoff=similarity_threshold - ) - return matches[0] if matches else None - - -def clean_columns_combined_fuzzy(df, column_name, valid_values, threshold): - """ - Applies fuzzy matching to entries in a specified column of a DataFrame to standardize them according to a list of valid values, - using a defined similarity threshold to determine matches. - - The function sanitizes the column values and then processes each entry, splitting it into sub-values if multiple are present. - Each sub-value is compared against the valid values list using a fuzzy matching algorithm. If a close match is found (above the - threshold), it replaces the original sub-value. The function logs any changes made for tracking and verification purposes. - - Parameters: - df (pandas.DataFrame): The DataFrame containing the column to be cleaned. - column_name (str): The name of the column to be cleaned. - valid_values (list of str): A list of valid values used for fuzzy matching. - threshold (float): The similarity threshold for accepting matches. - - Returns: - tuple: Contains arrays of original unique values, cleaned unique values, and a dictionary of changes (original to new values). - """ - changes = {} - df[column_name] = df[column_name].apply(sanitize_value) - original_values = df[column_name].unique() - - def log_and_clean(entry): - if pd.notna(entry): - words = entry.split(",") - cleaned_words = [] - for word in words: - cleaned_word = get_closest_match( - word.strip(), valid_values, similarity_threshold=threshold - ) - if cleaned_word and word.strip().upper() != cleaned_word: - changes[word.strip()] = cleaned_word - cleaned_words.append(cleaned_word if cleaned_word else word.strip()) - return ", ".join(cleaned_words) - return None - - df[column_name] = df[column_name].apply(log_and_clean) - cleaned_values = df[column_name].unique() - return original_values, cleaned_values, changes - - -def correct_misplaced_values(df, columns, valid_values_dict): - """ - Corrects misplaced values within specified columns of a DataFrame based on a dictionary of valid values for each column. - - This function iterates through each row of the DataFrame and checks the values of specified columns. If a value - is found that matches valid entries for a different column (based on the valid_values_dict), it moves the value to - the appropriate column. If the target column already contains a value, it uses fuzzy matching to determine if the - misplaced value should replace the existing one. If a replacement isn't suitable, it logs the correction attempt. - - Parameters: - df (pandas.DataFrame): The DataFrame containing the data to be corrected. - columns (list of str): The columns to check for misplaced values. - valid_values_dict (dict): A dictionary mapping column names to lists of valid values for those columns. - - Returns: - pandas.DataFrame: The DataFrame with corrected placements of values across the specified columns. - """ - for index, row in df.iterrows(): - for col in columns: - if pd.notna(row[col]): - terms = row[col].split(",") - for term in terms: - term = term.strip() - for target_col, valid_values in valid_values_dict.items(): - if target_col != col: - match = exact_match(term, valid_values) - if match: - if ( - pd.isna(row[target_col]) - or not row[target_col].strip() - ): - df.at[index, target_col] = match - df.at[index, col] = None - else: - current_value = row[target_col].strip() - if ( - get_closest_match( - match, - [current_value], - config.FUZZY_MATCH_THRESHOLD, - ) - is None - ): - df.at[index, "Corrected_" + target_col] = ( - f"Found {term} in {col} cell" - ) - df.at[index, col] = None - return df - - -def filter_service_column(d): - """ - Filters out items in a list of dictionaries based on specified keywords within the 'SERVICE' key. - - This function uses a list of predefined keywords associated with non-service related terms like 'LIABILITY' or 'RISK'. - It constructs a regular expression pattern from these keywords and removes any dictionary items where the 'SERVICE' key contains - any of these keywords, effectively filtering the list to exclude items that are likely to be irrelevant or misclassified - as services when they pertain to other contractual obligations or conditions. - - Parameters: - d (list): A list of dictionaries, each containing a 'SERVICE' key among others. - - Returns: - list: A new list of dictionaries with items containing specified keywords in the 'SERVICE' key removed. - """ - keywords = [ - "LIABILITY", - "RISK", - "LOBBYING", - "DAMAGES", - "CONFIDENTIALITY", - "ARBITRATION", - "FALSE CLAIMS ACT", - "UNSPECIFIED", - "AUDIT", - "INTEREST", - "N/A", - "BUSINESS", - "COMPLIANCE", - "Medical Assistance Program", - "MATERIAL SUBCONTRACT", - "GIFTS", - "GRATUITIES", - ] - pattern = "|".join(keywords) - regex = re.compile(pattern, re.IGNORECASE) - - filtered_list = [item for item in d if not regex.search(item.get("SERVICE", ""))] - - return filtered_list - - -def move_percentage_to_rate(df): - """ - Moves percentage values from the 'REIMBURSEMENT_FLAT_FEE' column to the 'REIMBURSEMENT_RATE' column in a DataFrame. - - This function identifies entries in the 'REIMBURSEMENT_FLAT_FEE' column that contain a percentage sign, indicating they are - incorrectly placed. It then transfers these percentage values to the 'REIMBURSEMENT_RATE' column. The original 'REIMBURSEMENT_FLAT_FEE' - entries from which percentages are moved are set to None, correcting the placement of data within the DataFrame. - - Parameters: - df (pandas.DataFrame): The DataFrame containing the reimbursement data to be adjusted. - - Returns: - pandas.DataFrame: The DataFrame with percentage values moved from the 'REIMBURSEMENT_FLAT_FEE' to the 'REIMBURSEMENT_RATE' column. - """ - - def move_percentage(value): - if isinstance(value, str) and "%" in value: - return True - return False - - df["REIMBURSEMENT_RATE"] = df.apply( - lambda row: ( - row["REIMBURSEMENT_FLAT_FEE"] - if move_percentage(row["REIMBURSEMENT_FLAT_FEE"]) - else row["REIMBURSEMENT_RATE"] - ), - axis=1, - ) - df["REIMBURSEMENT_FLAT_FEE"] = df.apply( - lambda row: ( - None - if move_percentage(row["REIMBURSEMENT_FLAT_FEE"]) - else row["REIMBURSEMENT_FLAT_FEE"] - ), - axis=1, - ) - return df - - -def set_rate_to_zero_if_not_covered(df): - """ - Sets the 'REIMBURSEMENT_RATE' to zero for entries in the DataFrame where the service is explicitly not covered, - as indicated by the content of the 'FULL_METHODOLOGY' column. - - This function checks each row's 'FULL_METHODOLOGY' column for phrases indicating that the service is not covered - (e.g., "not covered"). If such a phrase is found, the 'REIMBURSEMENT_RATE' for that row is set to zero to reflect that - there is no financial reimbursement for these services. This helps ensure that the data accurately represents the terms - of service coverage. - - Parameters: - df (pandas.DataFrame): The DataFrame containing the reimbursement and methodology data. - - Returns: - pandas.DataFrame: The updated DataFrame with adjusted 'REIMURSEMENT_RATE' values where applicable. - """ - - def check_and_set_rate(row): - if pd.notna(row["FULL_METHODOLOGY"]) and re.search( - r"not covered", row["FULL_METHODOLOGY"], re.IGNORECASE - ): - return 0 - return row["REIMBURSEMENT_RATE"] - - df["REIMBURSEMENT_RATE"] = df.apply(check_and_set_rate, axis=1) - return df - - -def adjust_reimbursement_rate(df): - """ - Adjusts the 'REIMBURSEMENT_RATE' in the DataFrame based on specific conditions mentioned in the 'FULL_METHODOLOGY' column. - - This function reviews each row's 'FULL_METHODOLOGY' column for mentions of being "case insensitive" as a part of the methodology. - If this condition is noted and the 'REIMBURSEMENT_RATE' is a numerical value, it adjusts the rate by subtracting it from 100, - effectively transforming the rate into a complementary percentage. This modification is intended to correct or recalibrate - reimbursement rates under specific contractual terms. - - Parameters: - df (pandas.DataFrame): The DataFrame containing the methodology and reimbursement rate data. - - Returns: - pandas.DataFrame: The updated DataFrame with recalibrated 'REIMBURSEMENT_RATE' values based on the specified methodology condition. - """ - - def adjust_rate(row): - if pd.notna(row["FULL_METHODOLOGY"]) and re.search( - r"case insensitive", row["FULL_METHODOLOGY"], re.IGNORECASE - ): - if pd.notna(row["REIMBURSEMENT_RATE"]) and isinstance( - row["REIMBURSEMENT_RATE"], (int, float) - ): - return 100 - row["REIMBURSEMENT_RATE"] - return row["REIMBURSEMENT_RATE"] - - df["REIMBURSEMENT_RATE"] = df.apply(adjust_rate, axis=1) - return df - - -def clean_td(td): - """ - Cleans the data structure returned from a 'Top Down' analysis by normalizing and formatting its values. - - This function iterates through each entry in the list of dictionaries returned from the top down analysis, - modifying data based on specific criteria: - - Dates are converted to lists if not already in list form. - - Comma-separated strings are split into lists. - - 'N/A' values are replaced with empty lists. - - Preserves specific keys as they are (e.g., 'page_num', 'Filename'). - - Parameters: - td (list of dict): The list of dictionaries containing the results from top down analysis. - - Returns: - list of dict: A new list of dictionaries with the cleaned and normalized data. - """ - td_clean = [] - for d in td: - new_d = {} - for k, v in d.items(): - if "DATE" in k: - new_d[k] = v if isinstance(v, list) else [v] - elif k not in ["page_num", "Filename"]: - if isinstance(v, str) and "," in v: - new_d[k] = [item.strip() for item in v.split(",")] - elif v == "N/A": - new_d[k] = [] - else: - new_d[k] = [v] if isinstance(v, str) else v - else: - new_d[k] = v - td_clean.append(new_d) - return td_clean - - -def sanitize_combined(df): - """ - Sanitizes all columns in a DataFrame by applying a predefined sanitization function to each value. - - This function iterates over each column in the DataFrame, applying a sanitization function to each element. - The sanitization function is designed to clean or adjust the data in a way that makes it more consistent or appropriate - for further processing or analysis. This could include operations like trimming whitespace, correcting formats, - or removing unwanted characters. - - Parameters: - df (pandas.DataFrame): The DataFrame to be sanitized. - - Returns: - pandas.DataFrame: The sanitized DataFrame, with the same structure but cleaned data. - """ - for column in df.columns: - df[column] = df[column].apply(sanitize_value) - return df - - -def extract_codes_CPT(value): - """ - Extracts and formats CPT codes from a given input value. - - This function searches for patterns that match CPT codes within the provided input. CPT codes typically consist - of a letter followed by four digits, or just five digits, and may include a two-letter state code as a suffix. - The function handles cases where the range of codes is specified using 'through' by converting it to a hyphen. - If any codes are found, they are returned as a comma-separated string. If no codes are found or the input is null, - an appropriate value (empty string or null) is returned. - - Parameters: - value (str or NaN): The value from which to extract CPT codes, which could potentially be a string or NaN. - - Returns: - str: A comma-separated string of the extracted CPT codes, or an empty string if none are found. - If the input is NaN, the function returns the input as is. - """ - if pd.isna(value): - return value - - value = re.sub(r"\bthrough\b", "-", str(value), flags=re.IGNORECASE) - - pattern = r"\b([A-Z]\d{4}|\d{5})(-[A-Z]{2})?\b" - matches = re.findall(pattern, value) - if matches: - return ", ".join(["".join(match) for match in matches]) - else: - return "" - - -def extract_codes_Diagnosis(value): - """ - Extracts and formats diagnosis codes from a given input value, typically adhering to ICD (International Classification of Diseases) formats. - - This function identifies patterns consistent with ICD diagnosis codes, which are generally a letter followed by numbers - and may include additional alphanumeric characters and a period for further specification. The function handles null inputs - gracefully, returning the input itself if null. If valid diagnosis codes are found, they are returned as a comma-separated - string. If no codes are found, the function returns an empty string. - - Parameters: - value (str or NaN): The input value from which to extract diagnosis codes, which could be a string or NaN. - - Returns: - str: A comma-separated string of the extracted diagnosis codes, or an empty string if none are found. - If the input is NaN, the function returns the input as is. - """ - if pd.isna(value): - return value - - pattern = r"\b[A-Z][0-9][A-Z0-9]{1,4}(\.[A-Z0-9]{1,4})?\b" - matches = re.findall(pattern, value) - if matches: - return ", ".join(matches) - else: - return "" - - -def extract_codes_Revenue(value): - """ - Extracts revenue codes from a given input value. Revenue codes are typically numerical codes of three to four digits. - - This function searches for patterns that match revenue codes in the input provided. It handles cases where the input might be null (NaN), - returning the input itself in such cases. If any valid revenue codes are found, they are formatted into a comma-separated string. - If no codes are found, the function returns an empty string, indicating the absence of recognizable codes in the input. - - Parameters: - value (str or NaN): The input value from which to extract revenue codes, which could be a string or NaN. - - Returns: - str: A comma-separated string of the extracted revenue codes, or an empty string if none are found. - If the input is NaN, the function returns the input as is. - """ - if pd.isna(value): - return value - - pattern = r"\b\d{3,4}\b" - matches = re.findall(pattern, value) - if matches: - return ", ".join(matches) - else: - return "" - - -def clean_code_column(df, column_name, extract_function): - """ - Applies a specified function to clean and extract codes from a specific column in a DataFrame. - - This function takes a DataFrame and applies a given extraction function to each element of a specified column. - The extraction function is expected to format or extract codes (e.g., CPT, ICD, Revenue codes) from the column's values. - This cleaned and extracted data replaces the original values in the column. The function is flexible and can be used - with any function designed to process and return cleaned values from a single input. - - Parameters: - df (pandas.DataFrame): The DataFrame containing the data to be cleaned. - column_name (str): The name of the column to be cleaned. - extract_function (function): The function to apply to each value in the specified column, which processes and returns the cleaned value. - - Returns: - pandas.DataFrame: The DataFrame with the specified column updated with cleaned and processed codes. - """ - df[column_name] = df[column_name].apply(extract_function) - return df - - -def clean_dates(df): - for idx, row in df.iterrows(): - if ( - row["LOB_PRICING_TERMS_EFFECTIVE_DATE"] - == row["LOB_PRICING_TERMS_TERMINATION_DATE"] - ): - df.loc[idx, "LOB_PRICING_TERMS_TERMINATION_DATE"] = "N/A" - - return df - - -def add_PG_columns(results_dicts): - for key in list(results_dicts[0].keys()): - if key != "page_num": - for d in results_dicts: - d[f"{key}_PG"] = d["page_num"] - return results_dicts diff --git a/fieldExtraction/src/preprocess.py b/fieldExtraction/src/preprocess.py deleted file mode 100644 index 77a60f2..0000000 --- a/fieldExtraction/src/preprocess.py +++ /dev/null @@ -1,166 +0,0 @@ -from itertools import groupby, count -import re - - -def clean_newlines(contract_text): - """ - Cleans up isolated newlines in a contract text, converting them into spaces to ensure text continuity. - - This function uses a regular expression to identify standalone newlines (those not part of a paragraph break, which - typically consists of consecutive newlines) and replaces them with a single space. This process helps in preserving - the flow of text and making it more readable and processable, particularly for text extraction and analysis tasks that - might be sensitive to abrupt breaks in the text. - - Parameters: - contract_text (str): The text of the contract that may contain sporadic newlines. - - Returns: - str: The cleaned contract text with isolated newlines replaced by spaces. - """ - cleaned_text = re.sub(r"(?>>' and '<<<' to highlight them. The modified text for each page - is then updated in the dictionary, allowing for easier identification and processing of rate-related terms in subsequent analyses. - - Parameters: - text_dict (dict): A dictionary where keys are page numbers and values are the text content of those pages. - - Returns: - dict: The updated dictionary with rate-related terms highlighted in the text of each page. - """ - for page, text in text_dict.items(): - words = text.split() - highlighted_words = [] - for word in words: - if "%" in word or "$" in word: - word = f">>>{word}<<<" - highlighted_words.append(word) - text_dict[page] = " ".join(highlighted_words) - return text_dict - - -def chunk_text(text_dict): - """ - Creates text chunks from a dictionary of page texts, focusing on pages with special characters (percentages and dollar amounts). - - This function identifies pages that contain '%' or '$' signs and includes those pages along with their immediate neighbors - (previous and next pages) to form chunks. The chunks are then grouped and concatenated into single text blocks for easier - processing. Each chunk is stored in a new dictionary where the keys represent the range of pages included in the chunk. - - Parameters: - text_dict (dict): A dictionary where keys are page numbers (as strings) and values are the text content of those pages. - - Returns: - dict: A new dictionary where each key is a string representing the range of pages in a chunk, and each value is the concatenated text of those pages. - """ - special_pages = { - int(page): text - for page, text in text_dict.items() - if (("%" in text) or ("$" in text) or ("percent" in text)) - } - page_numbers = sorted(special_pages.keys()) - chunk_page_numbers = [] - for page in page_numbers: - chunk_page_numbers.append(page - 1) - chunk_page_numbers.append(page) - chunk_page_numbers.append(page + 1) - chunk_page_numbers = list(set(chunk_page_numbers)) - chunk_page_numbers = [ - page for page in chunk_page_numbers if str(page) in text_dict.keys() - ] - chunks = [ - list(group) - for key, group in groupby(chunk_page_numbers, lambda x, c=count(): x - next(c)) - ] - chunk_dict = {} - for item in chunks: - dict_key = f"{min(item)}-{max(item)}" - text = "".join([text_dict[str(page)] for page in item]) - chunk_dict[dict_key] = text - return chunk_dict - - -def clean_billed_charges(contract_text): - """ - Cleans occurrences of 'billed charges' in a text by replacing them with '100% of billed charges' unless preceded by a percentage. - - This function uses a regular expression to find all instances of the phrase 'billed charges'. For each match, it checks the preceding - text (up to 15 characters before the match) for a percentage sign ('%'). If a percentage is found, it leaves the match unchanged. - Otherwise, it replaces 'billed charges' with '100% of billed charges'. - - Parameters: - text (str): The input text to be cleaned. - - Returns: - str: The cleaned text with appropriate replacements made for 'billed charges'. - """ - - substrings = [ - "Physician's Billed Charges", - "Provider's Billed Charges", - "Allowable Billed Charges", - "Hospital's Billed Charges", - "Physician's Charges", - "Provider's Charges", - "Allowable Charges", - "Hospital's Charges", - "Billed Charges", - "the rates set forth in this Exhibit", - "the rutes set forth in this Exhibit", - "Provider's usual and customary charge", - ] - max_substring_length = max([len(s) for s in substrings]) - - def find_substring_indices(contract_text, s): - indices = [] - lower_contract_text = contract_text.lower() - lower_s = s.lower() - index = lower_contract_text.find(lower_s) - while index != -1: - indices.append(index) - index = lower_contract_text.find(lower_s, index + 1) - return indices - - for s in substrings: - indices = find_substring_indices(contract_text, s) - index_adder = 0 - if indices: - for i in indices: - index = i + index_adder - end_index = index + max_substring_length - match_part = contract_text[index:end_index] - previous = contract_text[max(0, index - 30) : index] - if "%" not in previous: - contract_text = ( - contract_text[0:index] - + f" 100% of {match_part}" - + contract_text[end_index:] - ) - index_adder += 9 - return contract_text.replace(" ", " ") diff --git a/fieldExtraction/src/prompts.py b/fieldExtraction/src/prompts.py deleted file mode 100644 index c410498..0000000 --- a/fieldExtraction/src/prompts.py +++ /dev/null @@ -1,603 +0,0 @@ -def GENERATE_PROMPT(bu_dict, td_dicts, page, field_name=None, values=None): - if field_name and values: - return f"""### PAGE START ### {page} ### PAGE END - -Field: {field_name} -Values: {values} - -Listed above is a page of a contract, as well as the potential values for the {field_name} field. -Your job is to identify which of these values is the most appropriate based on the page content. - -Write ONLY the value that is most appropriate. Do not return any additional text beyond the value itself. -""" - else: - return f"""### PAGE START ### {page} ### PAGE END - -Service: {bu_dict['SERVICE']} -Methodology: {bu_dict['FULL_METHODOLOGY']} - -Listed above is a page of a contract, as well as a Service and Methodology found on this page. -Your job is to identify which of the following entities this specific Service is associated with. - -Here are the entities, represented as dictionary objects: - -{td_dicts} - -Write ONLY the number of the dictionary that is most associated with the Service and Methodology of interest. Do not return any additional text beyond the digit itself. -""" - - -def MERGE_SELECT_PROMPT(key, value, bu_dict, page): - return f"""### PAGE START ### {page} ### PAGE END - -Service: {bu_dict['SERVICE']} -Methodology: {bu_dict['FULL_METHODOLOGY']} - -Listed above is a page of a contract, as well as a specific Service and Methodology that may be found on this page. -Your job is to identify which of the following {key}s this specific Service is associated with. - -Here is a comma-separated list of options: - -{value} - -Write ONLY the value or values in the list that DIRECTLY applies to the Service and Methodology listed above. If none of the values apply, write 'N/A'. -If the Service and Methodology are not found on the page, write the LAST item in the list. Do not write any other commentary or explanation. -""" - - -def BOTTOM_UP_PRIMARY(page, payer): - return f""" -### PAGE START ### {page} ### PAGE END - -The preceding text is one page of a contract between Payer {payer} and a provider in their network. Your job is to extract attributes related to the reimbursement of different services and specialties. - -The reimbursement values will be identified with >>> <<< indicators (e.g. >>>105%<<<). Make sure there is at least one dictionary object for EVERY reimbursement value seen (either % or $). - -Some values are found in sections explicitly identified as examples - these must be omitted from output. Other values might be related to liability - these must also be excluded. - -If any of the attributes are not found, return N/A. For all attributes, only write what is written on the page. Do not make up new phrases or words. - -Return at least one json object for each combination of attributes seen. It is possible that a page will not have any attributes. When this is the case, return an empty list. - -Here are the attributes to be included in each dictionary, and instructions on how to correctly answer: -'SERVICE' : What is the Service that is being reimbursed? Use your best judgement and knowledge of the healthcare industry to answer. Use only exact text from the document. Do not leave this field N/A. -'REIMBURSEMENT_FLAT_FEE' : If the listed reimbursement is dollar value, return only that dollar value. There can only be one answer for each object. If more than one rate is found, create additional objects for them. -'REIMBURSEMENT_RATE' : If the listed reimbursement is a percent of something, return only that percent. There can only be one answer for each object. If more than one rate is found, create additional objects for them. Do NOT include multiple percentages in this value. -'FULL_METHODOLOGY' : If the listed reimbursement is a percent of something, what is it the percent of? If the listed reimbursement is a direct dollar value, how is that dollar value paid (per diem, per unit, etc)? Write the full sentence in text describing the payment methodology. -'DATE_RANGE' : If the listed reimbursement only applies to a specific date range, write that range here. Write only the exact text. Write only the range. If there is none, write 'N/A'. -'REIMBURSEMENT_TIN' : If the listed reimbursement only applies to a specific TIN, write only the TIN here. If not, write 'N/A' - -Note that only one of REIMBURSEMENT_FLAT_FEE or REIMBURSEMENT_RATE should be populated in each dictionary. Ensure all 4 keys are in the dictionary. - -Only return the list, with no other commentary or explanation. Ensure you abide by proper JSON formatting. -""" - - -def BOTTOM_UP_LESSER(d, page): - return f""" -### PAGE START ### {page} ### PAGE END - -The above text contains a number of reimbursement terms. For the rest of this request, focus only on the specific term listed below: -Original_Dictionary: -- Original_Service: {d['SERVICE']} -- Original_Rate: {d['REIMBURSEMENT_RATE']} -- Original_Flat_Fee: {d['REIMBURSEMENT_FLAT_FEE']} -- Original_Methodology: {d['FULL_METHODOLOGY']} - -Your job is to identify if there is any 'lesser of' language or 'greater of' language that pertains to the specific service and methodology above. - -Note that a 'lesser of'/'greater of' statement may not be directly written for a given Service, but that does not necessarily mean that it doesn't apply. - -Read and analyze the page, then populate two JSON dictionaries with the following fields (descriptions provided): -'LESSER_OF_LANGUAGE_IND' : Write 'Y' if there is 'lesser of' language somewhere on the page that applies to the Service and Original_Methodology. Write 'N' if not. -'GREATER_OF_LANGUAGE_IND' : Write 'Y' if there is 'greater of' language somewhere on the page that applies to the Service and Original_Methodology. Write 'N' if not. -'FULL_METHODOLOGY' : If either of the above are 'Y', what is the reimbursement the lesser or greater of? Do not write the full sentence. -'REIMBURSEMENT_RATE' : If the Lesser/Greater Of Methodology is a percent of something, write just the numeric percent value here. Only include percentages. If not, write N/A. -'REIMBURSEMENT_FLAT_FEE' : If the Lesser/Greater Of Methodology is a dollar value, write just the numeric value here. Only include dollar values. If not, write N/A. - -If either LESSER_OF_LANGUAGE_IND or GREATER_OF_LANGUAGE_IND is 'Y', then both dictionaries must be populated. One of the dictionaries will have REIMBURSEMENT_RATE, REIMBURSEMENT_FLAT_FEE, and FULL_METHODOLOGY values equal to the Original term. -Fill the first dictionary with the values corresponding to the LEFT half of the Lesser/Greater Of Statement, and the second dictionary with the RIGHT half of the Lesser/Greater Of Statement. - -If both LESSER_OF_LANGUAGE_IND and GREATER_OF_LANGUAGE_IND are 'N', return a list with just the original dictionary. - -Only return the list of dictionaries, with no other commentary or explanation. Ensure you abide by proper JSON formatting. -""" - - -def BOTTOM_UP_EXCEPT_ESC(d, page): - return f"""### PAGE START ### {page} ### PAGE END - -The above text contains a number of reimbursement terms. For the rest of this request, focus only on the specific term listed below: -Service: {d['SERVICE']} -Methodology: {d['FULL_METHODOLOGY']} - -Your job is to identify if the listed reimbursement contains some sort of exception (like for certain codes, hospitals, or other situations) or an escalation - -Read and analyze the page, then populate a JSON dictionary with the following fields (descriptions provided): -REIMBURSEMENT_EXCEPTION_IND: If the listed reimbursement contains some sort of exception (like for certain codes, hospitals, or other situations), return 'Y'. Otherwise, 'N' -REIMBURSEMENT_DESCRIBE_EXCEPTION: If the listed reimbursement contains some sort of exception, describe it here. Try to use exact words from the text only. If there is none, just write 'N/A' -RATE_ESCALATOR_IND: Does the listed reimbursement include annual rate escalators for year-over-year rate increases? If yes, return 'Y'. Otherwise, 'N'. -RATE_ESCALATOR_BASIS: If contract does include annual rate escalators, on what are they based? Do not be overly verbose in your answer. -RATE_ESCALATOR_YEARLY_PERCENT_INCREASE: What is the percent value of increase or decrease year-over-year? If a decrease, return a negative percentage. - -Only return the dictionary, with no other commentary or explanation. Ensure you abide by proper JSON formatting. -""" - - -def BOTTOM_UP_FS(d): - return f"""Analyze the reimbursement terms listed below: -Service: {d['SERVICE']} -Methodology: {d['FULL_METHODOLOGY']} - -Your job is to identify if the reimbursement is based on a Fee Schedule. - -Read and analyze the Methodology, then populate a JSON dictionary with the following fields (descriptions provided): -REIMBURSEMENT_FEE_SCHEDULE : If the Methodology is based on a Fee Schedule, what is the name of the fee schedule on which it is based? It could be something like Medicaid, Medicare, CMS, DRG, AWP, ASP, or similar. Do not answer with a complete sentence. If the Methodology is not based on a Fee Schedule, just return 'N/A' -REIMBURSEMENT_FEE_SCHEDULE_VERSION : If the Methodology is based on a Fee Schedule, what specific version of the Fee Schedule is it based on. It could be something like 'Current', 'Prevailing', 'at the date of service', a specific year, or similar. If there is no answer, return 'N/A' - -Only return the dictionary, with no other commentary or explanation. Ensure you abide by proper JSON formatting. -""" - - -def BOTTOM_UP_METHODOLOGY(d): - return f"""Analyze the full methodology text listed below: -{d['FULL_METHODOLOGY']} - -Your job is to identify what the concise methodology is based on the full methodology. - -Choose the closest option from the following: -Allowed Amount, Allowable Charges, Fee Schedule, Medicare Fee Schedule, Medicare Allowed Amount, Medicaid Fee Schedule, Medicaid Allowed Amount, Provider's Charges, Billed Charges, Normal fee for such service, IME/DME Amount, Cost to Charge Ratio, Cost plus %, MSRP, Per Unit, Per Diem, Per Visit, Per Member, Per Member Per Month, Per Hour, Case Rate, Contracted Rate - -For 'Allowed Amount' and 'Fee Schedule', use the more specific answer (Medicare/Medicaid) if applicable. -For the 'Per ___' values, note that this list is not necessarily exhaustive. It could be anything like 'Per ___'. - -Return only the answer, without using complete sentences. If there is nothing close to the above options in the full methodology text, simply return 'N/A' -""" - - -def BOTTOM_UP_CODES(d, page): - return f"""### PAGE START ### {page} ### PAGE END - -The above text contains a number of reimbursement terms. For the rest of this request, focus only on the specific term listed below: -Service: {d['SERVICE']} -Methodology: {d['FULL_METHODOLOGY']} - -Your job is to identify codes associated with this specific term. - -Read and analyze the page, then populate a JSON dictionary with the following code types if they are associated with the given Service and Methodology (descriptions provided): -'REIMBURSEMENT_ADMITTYPE_CODES' : Single-digit codes that indicate the type of admission to a facility. -'REIMBURSEMENT_DIAG_CODES' : Multi-digit alphanumeric codes related to diagnosis. They may contain a '.' after the first 3 characters. These may be labelled as ICD-10 or ICD-10-CM codes. -'REIMBURSEMENT_GROUPER_CODES' : 3- or 4-digit codes that may be labelled DRG or or similar. -'REIMBURSEMENT_GROUPER' : If there are grouper codes, what type are they? They could be MSDRG, APDRG, APRDRG, APC, APG, or EAPG. Choose only from these options. -'REIMBURSEMENT_PLACEOFSERVICE_CODES' : 2-digit codes related to the place of service. -'REIMBURSEMENT_PROC_CODES' : 5-digit numeric or alphanumeric codes. They may be labelled as CPT or HCPCS codes. These are related to specific procedures. -'REIMBURSEMENT_REVENUE_CODES' : 3- or 4-digit numeric or alphanumeric codes related to revenue. They may be labelled as 'Rev' codes. -'REIMBURSEMENT_STATUS_INDICATOR_CODES' : 1- or 2-digit alphanumeric codes indicating the payment status. - -Return a value for each type of code - return N/A for any values not found. Multiple codes for each type may be found. In this case, return them all. They may also present as a range. If so, return the range. - -Note that some PROC_CODES may have 'Modifiers' listed as well. These are 2-character strings. If Modifiers are present, include them. - -Ensure you ONLY return codes if they are associated directly with the Service listed. Codes referring to other services should not be included. - -Only return the dictionary, with no other commentary or explanation. Ensure you abide by proper JSON formatting. -""" - - -def TOP_DOWN_PRIMARY(page): - return f"""### PAGE START ### {page} ### PAGE END - -The preceding text is one page of a contract between a Payer and a provider in their network. Your job is to extract the names of certain entities listed in the contract and return a single dictionary with the values below: - -Here are the attributes to be included in each dictionary, and instructions on how to correctly answer: -'CONTRACT_LOB' : List any Line of Business mentioned on the page. Choose ONLY from the following: Commercial, Group, Marketplace, Marketplace/Exchange, Medicaid, Medicaid-Medicare, Medicare, Medicare Advantage, Medicare Supplemental, Veterans Affairs. If none of these are found on the page, simply write 'N/A' for this answer. -'CONTRACT_PROGRAM' : List any Programs mentioned on the page. Some examples of Programs are: CHIP, CHIP-P, CHIP-Perinate, STAR, STAR+PLUS. Do your best to infer the program from this page. -'CONTRACT_NETWORK' : List any Networks mentioned on the page. Networks are types of managed care organizations involved in the delivery of healthcare services. Some examples of Networks are: HMO, PPO, EMO, POS, FFS. Do your best to infer the network from this page. If it says anywhere that they are out of network then only return "OUT OF NETWORK" as your answer. -'PRODUCT' : List any Products listed on the page. These are typically the brand name of a health plan. You may also use this field as a catch-all for entities that you are unsure of. -'PROV_TYPE' : List any Provider Types listed on the page. This can be something like Inpatient, Outpatient, Ancillary, ASC, DME, Hospital, Home Health, Hospice, or similar. - -If any of the attributes are not found, return N/A. If there are multiple answers for a given attribute, return the answers in a comma-separated list. - -For all attributes, only write what is written on the page. Do not make up new phrases or words. - -Only return the dictionary, with no other commentary or explanation. Ensure you abide by proper JSON formatting. -""" - - -def LOB_CHECK(bu_dict, td_dicts, page): - return f"""### PAGE START ### {page} ### PAGE END - -Service: {bu_dict['SERVICE']} -Methodology: {bu_dict['FULL_METHODOLOGY']} - -Listed above is page of a contract, as well as a Service and Methodology found on this page. -Your job is to identify which of the following entities this specific Service is associated with. - -----Change Below---- - -Here are the entities, represented as dictionary objects: - -{td_dicts} - -Write ONLY the number of the dictionary that is most associated with the Service and Methodology of interest. Do not return any additional text beyond the digit itself. -""" - - -def TOP_DOWN_METAL_LEVEL(LOB, page): - return f"""### PAGE START ### {page} ### PAGE END - -The above page was identified as applying to a Commercial or Marketplace Line of Business. - -What is the metal level(s) of the line of business. It might be Bronze, Silver, Gold, or Platinum. If multiple are found, return them all in a comma-separated list. If no metal level is found, return 'N/A'. - -Only write what is written on the page. Do not make up new phrases or words. - -ONLY return the metal level, with no other commentary or explanation. -""" - - -def TOP_DOWN_DATE(type_, d, page): - return f"""### PAGE START ### {page} ### PAGE END - -Above is a page of a contract. Identify the {type_} Date associated with the information below: - -{d} - -Only write what is written on the page. Do not make up new phrases or words. If no {type_} date is listed, return 'N/A'. - -Ensure that you do not mistake EFFECTIVE date for TERMINATION date, or vice versa. They are not the same thing. -The TERMINATION date will NOT be labelled as the EFFECTIVE date, and the EFFECTIVE date will NOT be labelled as the TERMINATION date. This is very important, so pay extra close attention. - -ONLY return the answer, with no other commentary or explanation. -""" - - -def get_carveout_list(): - return [ - "Emergency Department/Emergency Room", - "Emergency Department", - "Emergency Room", - "Observation", - "Surgery", - "General Surgery", - "Ambulatory Surgery", - "Intensive Care", - "Trauma", - "HIV", - "Human Immunodeficiency Virus", - "Major Joint Replacement", - "Transplant", - "OBGYN", - "Obstetrician/Gynecologist", - "Obstetrician", - "Gynecologist", - "Opthalmology & Vision", - "Opthalmology", - "Vision", - "Never Events", - "Medically Unnecessary", - "Medically Unnecessary Procedures", - "Not Medically Necessary", - "Not Medically Necessary Procedures", - "Experimental", - "Investigational", - "Unlisted Codes", - "Durable Medical Equipment", - "DME", - "Prosthetics & Orthotics", - "Prosthetics", - "Orthotics", - "Implants", - "Hearing Aids", - "Hearing", - "Anesthesia", - "Anesthesiology", - "Medical Pharmacy", - "Physician Administered Drugs", - "Global", - "Bundled or Unbundled Codes", - "Bundled Codes", - "Unbundled Codes", - "Multiple Procedure Reductions", - "Second Surgery", - "Subsequent Surgeries", - "Non-Behavioral Health Mid-Level Professionals", - "Physician Assistant", - "PA", - "Nurse Practicioner", - "NP", - "Non-Physician", - "Non-Physician Health Professionals", - "Technical Component", - "Professional Component", - "Laboratory", - "Pathology", - "Lab", - "Path", - "Lab/Path", - "Laboratory/Pathology", - "Radiology", - "Imaging", - "Radiology/Imaging", - "Mammography", - "Diagnostic", - "Pre-Admission Procedures", - "Post-Discharge Procedures", - "Readmission", - "Status Indicators", - "Stop Loss", - "Emergency Medical", - "EMS", - "NICU", - "Neonatal Intensive Care Unit", - "Vaccine for Children", - "VFC", - "Surgical Assistant", - "Physicians/Clinical Psychologists", - "Doctor of Nursing Practice", - "Osteopathic Medicine", - "Clinical Psychology", - "Audiologist", - "Chiropractors", - "Registered Dietician", - "AUD", - "DC", - "RD", - "Board Certified Behavioral Analysis", - "Behavioral Analysis", - "BCBA", - "Independent Licensures", - "Licensed Professional Counselor", - "Marriage and Family Therapist", - "Substance Abuse Counselor", - "Clinical Social Worker", - "Behavioral Health Outpatient Clinic", - "Physical Therapist", - "Occupational Therapist", - "Speech Therapist", - "PT", - "OT", - "ST", - "Transportation", - "Primary Care", - "Primary Care Behavioral Health", - "Behavioral Physician", - "Clinical Psychologist", - "Mid-Level Practicioner", - "Dentist", - "Dental", - "Supplies and Devices", - "Supplies", - "Devices", - "Immunizations", - "Obstetrical Epidural", - "Pediatric Subspecialties", - "Orthopedic Surgery", - "All Other Specialists", - "Specialty Care Physician", - "Pediatric Primary Care", - "Nurse Anesthetist", - "Early Periodic Screening, Diagnostic, and Treatment", - "EPSDT", - "Ancillary", - "Oncology", - "Cancer", - "Inpatient Physical Rehabilitation", - "Inpatient Rehabilitation", - "Outpatient Rehabilitation", - "Rehabilitation", - "Non-Behavioral Health Rehabilitation", - "Extracorporeal Shock Wave Lithotripsy", - "Cardiac", - "Special Care Unit", - "Skilled Nursing", - "Infusion", - "Specialty Care", - "Specialty Care Physician", - "Organ Acquisition", - "Blood Products", - "Blood Products Outpatient", - "Blood Products Inpatient", - "High Cost Drugs", - "Sleep Studies", - "NICU", - "Newborn Intensive Care Unit", - "Extracorporeal Membrane Oxygenation", - "Burns", - "Kyphoplasty", - "Cryosurgical Ablation of the Prostate", - "Transurethral Thermal Ablation", - "TUMT", - "Transurethral Needle Ablation", - "TUNA", - "Hyperbaric Treatment", - "Clinic Visit", - "Boarder Baby", - "Pediatric Intensive Care Unit", - "PICU", - "Psychiatric", - "Mental Health", - "Behavioral Health", - "Substance Abuse", - "Behavioral Health and Substance Abuse", - "Sub-Acute Facility Care", - "Unrouped Inpatient", - "All Other Acute", - "Neurology", - "Neurology Subspecialties", - "Automatic Implantable Cardioverter Defibrillator", - "Percutaneous Transluminal Coronary Angioplasty", - "Non-Coronary Angioplasty", - "Cardiac Catheters", - "Cardiovascular Surgery", - "Cardiac Surgery", - "Cesarean Birth", - "Cesarean Section", - "C-Section", - "Gamma-Knife Radio-Surgery Outpatient", - "DaVinci Robotic Assisted Surgery", - "Outpatient Electrophysiology with Ablation", - "Outpatient Electrophysiology", - "Magnetic Resonance Image", - "MRI", - "Computed Tomography Scan", - "CT Scan", - "Radiation Therapy", - "Dialysis", - "Gastric Bypass", - "Lap Band", - "Obesity", - "Laparoscopic Cholecystectomy", - "Lap Chole", - "Laparoscopic Hysterectomy", - "Laparoscopic Prostatectomy", - "Laparoscopic Hysteroscopy", - "Treatment Room", - "Wound Care", - "Cardiac Computed Tomograpy & Angiography", - "Positron Emission Tomography Scan", - "PET Scan", - "Hematology", - ] - - -def prompt_contract_lob(page): - return f"""### PAGE START ### {page} ### PAGE END - - Extract all instances of the Line of Business (LOB) mentioned on the page. - Identify each distinct LOB and return them as separate objects. Possible values include: - - Commercial - - Commercial/Group - - MARKETPLACE - - MEDICAID - - MEDICARE - - Marketplace/Exchange - - Medicaid/Medicare - - Medicare Advantage - - Medicare Supplemental - - Veterans Affairs (VA) - - Civilian Health and Medical Program of the Department of Veterans Affairs (CHAMPVA) - - Tricare (health care program for uniformed service members, retirees, and their families around the world) - If no LOB is found, return 'N/A'. - - IT IS NOT GOING TO BE THINGS LIKE HMO, PPO, CHIP, STAR, ETC - It will not be anything related to a 'Plan', so do not return anything like that. - Return the results. If there are multiple identified then return seperated by commas. Only return the extracted information and no other text or sentences or explanations. Only the final values. """ - - -def prompt_product(page): - return f"""### PAGE START ### {page} ### PAGE END - - Identify and list all instances of the Plan or Product names mentioned on the page. In the context of health insurance, 'Plan' or 'Product' names are typically brand names of health plans provided by insurers. These names often reflect the type of coverage offered, its scope, or the insurer's branding. Examples of the types of coverage include 'Medical', 'Prescription Drug', 'Mental/Behavioral Health (MH/BH)', 'Substance Abuse (SA)', 'Hearing', 'Dental', and 'Vision'. - - To recognize these names, look for capitalized terms or phrases often preceded by words like 'plan', 'coverage', 'program', or directly followed by 'network'. These names can be unique to the insurer or widely recognized in the industry. For instance, names like 'HealthPlus Medical Plan', 'VisionCare Network', or 'DentalSelect Coverage' are typical examples. - - Extract and list all identified plan or product names. If multiple names are found, return them separated by commas. If no specific plan name is found, return 'N/A'. Only return the extracted information and no other text or sentences or explanations. Only the final values. - """ - - -def prompt_network_name(page): - # MODIFY TO DICTS FOR MAPPING - return f"""### PAGE START ### {page} ### PAGE END - - Extract all network names mentioned on the page. A 'network name' in the context of health insurance refers to the type of managed care organization involved in the delivery of healthcare services. These names often indicate the structure or model of care delivery, which may define the relationships between insurers, healthcare providers, and insured individuals. - - Key identifiers of network types include terms that suggest managed care arrangements such as 'Health Maintenance Organization (HMO)', 'Preferred Provider Organization (PPO)', 'Exclusive Provider Organization (EPO)', 'Point of Service (POS)', and 'Indemnity or Fee for Service (FFS)'. Other descriptors might include 'Open Access', 'Exclusive Provider', 'Integrated Delivery Network', and 'Tiered Network'. - - Methodically scan the text for any terms that align with these descriptions. Return all found network names separated by commas if multiple. If no network names are found in the text, return 'N/A'. Only return the extracted information and no other text or sentences or explanations. Only the final values. - """ - - -def prompt_service_area(page): - return f"""### PAGE START ### {page} ### PAGE END - - Extract the type of service area mentioned on the page. A 'Service Area' refers to the specific geographic or demographic region type where the health plan provides coverage or services. This could include specific states, counties, cities, or distinctions between urban and rural areas. - Select from the following options: Urban, Rural, State, County, City, ZIP, Address - - Extract and return all found attributes separated by commas in a single string. If no specific service areas are mentioned in the text, return 'N/A'. only return the extracted information and no other text or sentences or explanations. Only the final values. - """ - - -def prompt_effective_date(page): - return f"""### PAGE START ### {page} ### PAGE END - - Identify all instances of Effective Dates mentioned within the context of specific compensation exhibits or contracts. - The date format should be MM/DD/YYYY. - Return all dates seperated by commas. If no effective dates are found, return 'N/A'. only return the extracted information and no other text or sentences or explanations. Only the final values.' - DO NOT REPEAT THE SAME DATE MULTIPLE TIMES. - """ - - -def prompt_termination_date(page): - return f"""### PAGE START ### {page} ### PAGE END - - Extract all termination dates mentioned in the text, specifically those related to the end of a compensation period or agreement. Termination dates specify when a contract or policy provision ceases to be effective. - - To identify termination dates, look for dates associated with terms like 'end', 'expiration', 'termination', or similar phrases that indicate the conclusion of an agreement. These dates are typically formatted in MM/DD/YYYY. - - Carefully scan the text for these indications and extract any dates that conform to this format. List each date and return them separated by commas if multiple are found. If no termination dates are found, return 'N/A'. only return the extracted information and no other text or sentences or explanations. Only the final values. - DO NOT REPEAT THE SAME DATE MULTIPLE TIMES. - """ - - -def prompt_metal_level(page): - return f"""### PAGE START ### {page} ### PAGE END - - If the Line of Business is identified as Marketplace, extract all instances of metal levels such as Platinum, Gold, Silver, or Bronze. - List each metal level. If no metal levels are found or if the LOB is not Marketplace, return 'N/A'. only return the extracted information and no other text or sentences or explanations. Only the final values seperated by commas.""" - - -def prompt_claim_discount_ind(lob): - return f"For this line of business: {lob}, return with a 'Y' or 'NO' only whether the claim for this LOB is discounted. Only return as 'Y' or 'NO'." - - -def prompt_claim_discount_percent_rate(lob): - return f"For this LOB only: {lob}, extract the claim discount percent rate." - - -def prompt_claim_discount_start_date(lob): - return f"For this LOB only: {lob}, extract the claim discount start date." - - -def prompt_claim_discount_termination_date(lob): - return f"For this LOB only: {lob}, extract the claim discount termination date." - - -def prompt_premium_ind(lob): - return f"""For this Line of Business{lob}, indicate with a 'Y' or 'N' only whether the premium for this LOB is subject to any adjustments. Return only 'Y' or 'N'.""" - - -def prompt_premium_percent(lob): - return f"""For this Line of Business{lob}, extract the percentage rate of premium adjustment if applicable. Provide the percentage as a numerical value only.""" - - -def prompt_premium_start_date(lob): - return f"""For this Line of Business{lob}, identify the start date of the premium adjustments. Return the date in MM/DD/YYYY format only.""" - - -def prompt_premium_termination_date(): - return """For this Line of Business, determine the termination date of the premium adjustments. Provide the date in MM/DD/YYYY format only.""" - - -def prompt_sequestration_ind(): - return """For this Line of Business, indicate with a 'Y' or 'N' whether there is any sequestration applied. Return only 'Y' or 'N'.""" - - -def prompt_sequestration_rate(): - return """For this Line of Business, extract the rate of sequestration as a percentage. Return the rate as a numerical value only.""" - - -def prompt_sequestration_start_date(): - return """For this Line of Business, determine the start date for sequestration. Return the date in MM/DD/YYYY format only.""" - - -def prompt_sequestration_termination_date(): - return """For this Line of Business, identify the termination date for sequestration. Provide the date in MM/DD/YYYY format only.""" - - -def prompt_penalties_ind(): - return """For this Line of Business, indicate with a 'Y' or 'N' only whether there are any penalties applied. Return only 'Y' or 'N'.""" - - -def prompt_penalties_rate(): - return """For this Line of Business, extract the rate of any penalties applied as a percentage. Provide the rate as a numerical value only.""" diff --git a/fieldExtraction/src/table_funcs.py b/fieldExtraction/src/table_funcs.py deleted file mode 100644 index af762f0..0000000 --- a/fieldExtraction/src/table_funcs.py +++ /dev/null @@ -1,172 +0,0 @@ -import re -import ast - - -def clean_tables(text): - def replace_colon(text): - # Define a function to use in re.sub to check the context of the match - def replacer(match): - # Extract the character after ':' to check if it's '[' - following_text = match.group(1) - if following_text.strip().startswith("["): - return match.group( - 0 - ) # Return the original match (':' and whatever follows) - else: - return "" + match.group(1) # Replace ':' with ';' and return the rest - - # Use a regular expression to find ':' and the text that follows - pattern = r":(\s*.)" - replaced_text = re.sub(pattern, replacer, text) - return replaced_text - - def remove_unquoted_brackets(text): - # Define a function to check the content between brackets - def replacer(match): - content = match.group(1) - if "'" not in content and (len(content) > 0): - return content # Return just the content without brackets - else: - return match.group( - 0 - ) # Return the original match if it contains a quote - - # Use a regular expression to find brackets and the text within - pattern = r"\[([^\[\]]*?)\]" - cleaned_text = re.sub(pattern, replacer, text) - return cleaned_text - - # Clean tables - text = text.strip("{}") # Remove brackets - text = replace_colon(text) - text = remove_unquoted_brackets(text) - return text - - -def convert_to_dict(table_text): - """ - Converts a formatted table text into a dictionary where each key maps to a list of values. - - This function processes a string representation of a table, extracting key-value pairs and converting them into a dictionary. - Each key maps to a list of values parsed from the input string. The function also returns the number of elements in each list. - - Parameters: - table_text (str): The input string representing the table, formatted with keys and values. - - Returns: - tuple: A dictionary with keys mapping to lists of values, and an integer representing the number of elements in each list. - """ - table_text = clean_tables(table_text) - # print(table_text, '\n') - table_text_list = table_text.split("]") - table_text_list = [item for item in table_text_list if len(item) > 0] - - final_dict = {} - num_elements = 0 - for key_value_text in table_text_list: - key = key_value_text.split(":")[0].strip(", '") - try: - value = ":".join(key_value_text.split(":")[1:]).strip() + "]" - # print(value, '\n') - if len(value) > 1: - value_list = ast.literal_eval(value) - final_dict[key] = value_list - num_elements = len(value_list) - except: - value = ":".join(key_value_text.split(":")[1:]).strip() + "']" - # print(value, '\n') - if len(value) > 1: - value_list = ast.literal_eval(value) - final_dict[key] = value_list - num_elements = len(value_list) - - return final_dict, num_elements - - -def format_table(table_json, table_size): - """ - Formats a dictionary of table data into a string representation of the table. - - This function takes a dictionary where each key maps to a list of values and converts it into a formatted string. - The keys are used as headers, and each row is constructed by iterating through the lists up to the specified table size. - The resulting string separates headers and values with ' : ' and includes newline characters to delineate rows. - - Parameters: - table_json (dict): The dictionary containing the table data, with keys as column headers and lists as column values. - table_size (int): The number of rows in the table. - - Returns: - str: The formatted string representation of the table. - """ - table_text = "" - keys = [key for key in table_json.keys()] - table_text += " : ".join(keys) + "\n" - for i in range(table_size): - for key in keys: - if table_json[key][i]: - # table_text += key + ': ' + table_json[key][i] + ', ' - table_text += table_json[key][i] + " : " - table_text += r"\n" - return table_text - - -def align_and_format_tables(text_dict): - """ - Aligns and formats tables within the text of each page in a dictionary. - - This function searches for table text within the input text of each page, marked by 'Table Start' and 'Table End' tags. - It extracts, converts, and formats these tables, then replaces the original table text with the formatted version while - maintaining the alignment with surrounding text. The cleaned and formatted text for each page is then stored in a new dictionary. - - Parameters: - text_dict (dict): A dictionary where keys are page numbers and values are the text content of those pages, potentially containing tables. - - Returns: - dict: A new dictionary with aligned and formatted tables in the text for each page. - """ - aligned_text_dict = {} - for key, text in text_dict.items(): - aligned_text = text - if "Table Start" in text: - table_texts = re.findall( - r"-------Table Start--------(.*?)-------Table End--------", - text, - re.DOTALL, - ) - for table_text in table_texts: - # print(table_text, '\n') - - try: - # Extract pretable text - pretable = table_text.split("{")[0].strip() - # Extract and format table text - # table_only = "{" + table_text.split('{', 1)[1].rsplit('}', 1)[0].replace("'", '"') + "}" - table_only = ( - "{" + table_text.split("{", 1)[1].rsplit("}", 1)[0] + "}" - ) - - table, table_size = convert_to_dict(table_only) - table_formatted = format_table(table, table_size) - except: - table_formatted = table_text - - # Align - if text.count(pretable) == 2: # One table - # Remove original table - aligned_text = text.replace(table_text, "") - # Align new table - aligned_text = aligned_text.replace( - pretable, pretable + table_formatted - ) - - else: - aligned_text = aligned_text.replace( - table_text, pretable + " " + table_formatted - ) - aligned_text_dict[key] = aligned_text.replace( - "-------Table Start--------", "" - ).replace("-------Table End--------", "") - else: - aligned_text_dict[key] = text - - return aligned_text_dict diff --git a/fieldExtraction/src/test.py b/fieldExtraction/src/test.py deleted file mode 100644 index ebc0ea8..0000000 --- a/fieldExtraction/src/test.py +++ /dev/null @@ -1,85 +0,0 @@ -import utils -import preprocess -import table_funcs -import prompts -import claude_funcs -import config - -import pandas as pd -import os -import shutil - - -# input_dict = utils.read_input() - -# filename = list(input_dict.keys())[0] -# contract_text = input_dict[filename] - -# contract_text = preprocess.clean_newlines(contract_text) -# contract_text = preprocess.clean_billed_charges(contract_text) -# text_dict = preprocess.split_text(contract_text) -# text_dict = table_funcs.align_and_format_tables(text_dict) -# text_dict = preprocess.highlight_rates(text_dict) - -# def BOTTOM_UP_PRIMARY(page, payer): -# return f""" -# ### PAGE START ### {page} ### PAGE END - -# The preceding text is one page of a contract between Payer {payer} and a provider in their network. Your job is to extract attributes related to the reimbursement of different services and specialties. - -# The reimbursement values will be identified with >>> <<< indicators (e.g. >>>105%<<<). Make sure there is at least one dictionary object for EVERY reimbursement value seen (either % or $). - -# Some values are found in sections explicitly identified as examples - these must be omitted from output. Other values might be related to liability - these must also be excluded. - -# If any of the attributes are not found, return N/A. For all attributes, only write what is written on the page. Do not make up new phrases or words. - -# Return at least one json object for each combination of attributes seen. It is possible that a page will not have any attributes. When this is the case, return an empty list. - -# Here are the attributes to be included in each dictionary, and instructions on how to correctly answer: -# 'SERVICE' : What is the Service that is being reimbursed? Use your best judgement and knowledge of the healthcare industry to answer. Use only exact text from the document. Do not leave this field N/A. -# 'REIMBURSEMENT_FLAT_FEE' : If the listed reimbursement is dollar value, return only that dollar value. There can only be one answer for each object. If more than one rate is found, create additional objects for them. -# 'REIMBURSEMENT_RATE' : If the listed reimbursement is a percent of something, return only that percent. There can only be one answer for each object. If more than one rate is found, create additional objects for them. Do NOT include multiple percentages in this value. -# 'FULL_METHODOLOGY' : If the listed reimbursement is a percent of something, what is it the percent of? If the listed reimbursement is a direct dollar value, how is that dollar value paid (per diem, per unit, etc)? Write the full sentence in text describing the payment methodology. -# 'DATE_RANGE' : If the listed reimbursement only applies to a specific date range, write that range here. Write only the exact text. Write only the range. If there is none, write 'N/A'. -# 'REIMBURSEMENT_TIN' : If the listed reimbursement only applies to a specific TIN, write only the TIN here. If not, write 'N/A' - -# Note that only one of REIMBURSEMENT_FLAT_FEE or REIMBURSEMENT_RATE should be populated in each dictionary. Ensure all 4 keys are in the dictionary. - -# Only return the list, with no other commentary or explanation. Ensure you abide by proper JSON formatting. -# """ -# answer_dict = {} -# for page_number in text_dict.keys(): -# if utils.contains_reimbursement(text_dict, page_number): -# # Run Primary -# prompt = BOTTOM_UP_PRIMARY(text_dict[page_number], config.CLIENT_NAME) -# answer = claude_funcs.invoke_claude_3(prompt, max_tokens=4000) -# answer_dict[page_number] = answer - -# for page_num in answer_dict.keys(): -# print(f"Page {page_num}\n") -# print(answer_dict[page_num]) - - -batch1_files = pd.read_excel( - "C:\\Users\\kminhas\\Documents\\Doczy\\Facility TINs_DOCZY AI_DOCUMENT EXTRACTION_ASSIGNMENT_7.1.2024.xlsx", - sheet_name="DOCZY AI", -) -batch1_files = batch1_files["File Name"] -# print(list(batch1_files)) - -tdrive_path = "T:\\AArete Client Work\\Centene\\Restricted\\HealthNet\\Doczy Contract Metadata\\1. Contracts\\05232024\\Extracted" -batch_path = os.path.join(tdrive_path, "Batch0") -try: - os.mkdir(batch_path) -except: - pass - -for file in os.listdir(tdrive_path): - if file.endswith(".Pdf") and file.split(".Pdf")[0] in list(batch1_files): - try: - source_path = os.path.join(tdrive_path, file) - destination_path = os.path.join(batch_path, file) - shutil.move(source_path, destination_path) - print(f"Moved file: {file}") - except: - pass diff --git a/fieldExtraction/src/textract_template.py b/fieldExtraction/src/textract_template.py deleted file mode 100644 index 9a4ef6a..0000000 --- a/fieldExtraction/src/textract_template.py +++ /dev/null @@ -1,223 +0,0 @@ -""" -This script was written to extract .txt files from pdf for adhoc client runs. -Ensure you have permissions for API gateway, S3, Lambda function and SQS to execute this (DEVELOPER & above roles in DEV & UAT for Doczy should suffice) -If you have Analyst / Test roles and need the permissions to be elevated or policies to be updated then please ask Sannan Iqbal to make the changes. - -The flow to execute the pipeline is: -Create batch using api req -Add files to the newly created batch along with the batch id as the tag -Construct payload to trigger pipeline -Post request to trigger pipeline with payload -The output text file can be found in the client_bucket/contract_text_file/batch_123456 -And the final LLM parsed outputs can be found in client_bucket/final_output/batch_123456 -""" - -import os -import boto3 -import requests -import json -import boto3 -from datetime import datetime -import os -from botocore.auth import SigV4Auth -from botocore.awsrequest import AWSRequest -from botocore.credentials import get_credentials -from botocore.session import Session -import time - - -# Function to upload files to S3 -def upload_files_to_s3(directory, bucket, batch_id): - contract_list = [] - for filename in os.listdir(directory): - if filename.endswith(".pdf"): - file_path = os.path.join(directory, filename) - s3_key = f"contracts-landing-zone/{batch_id}/{filename}" - - # Upload file to S3 - s3_client.upload_file(file_path, bucket, s3_key) - print(f"Uploaded {filename} to S3 bucket\n") - - # Add tags to the uploaded file - s3_client.put_object_tagging( - Bucket=bucket, - Key=s3_key, - Tagging={"TagSet": [{"Key": "BatchId", "Value": batch_id}]}, - ) - print(f"Added tags to {filename}\n") - # Add file details to contract list - # For now we can leave it as is since only A, C have been operationalized - contract_list.append( - { - "contract_name": filename, - "groups": [ - "A", # This needs to be dynamic in UI 1 based on what group has been selected - "C", - ], - "contract_source_path": s3_key, - } - ) - return contract_list - - -def create_batch(client_bucket, create_batch_url): - myobj = {"client-bucket-name": client_bucket} - - # Call create batch API endpoint - response = requests.post(create_batch_url, json=myobj) - if response.status_code >= 200 and response.status_code < 300: - try: - new_batch_id = json.loads(json.loads(response.text)["body"])["batch_id"] - landing_zone = json.loads(json.loads(response.text)["body"])["landing_zone"] - except: - print(myobj) - print(response.text) - new_batch_id = "failed_cases" - landing_zone = "contracts_landing_zone" - else: - print(response.text) - new_batch_id = "failed_cases" - landing_zone = "contracts_landing_zone" - return new_batch_id, landing_zone - - -def list_filtered_files(bucket_name, prefix, start_date, end_date, profile_name): - """ - List all files in an S3 bucket filtered by date range. - - Parameters: - - bucket_name: str, the name of the S3 bucket - - prefix: str, the prefix (folder) in the S3 bucket - - start_date: str, the start date in ISO 8601 format - - end_date: str, the end date in ISO 8601 format - - profile_name: str, the AWS profile name - - Returns: - - list of str: the keys of the filtered files - """ - # Parse the dates - start_date = datetime.fromisoformat(start_date.replace("Z", "+00:00")) - end_date = datetime.fromisoformat(end_date.replace("Z", "+00:00")) - - # Initialize a session using the specified profile - session = boto3.Session(profile_name=profile_name) - s3_client = session.client("s3") - - # List objects in the bucket with the specified prefix - paginator = s3_client.get_paginator("list_objects_v2") - page_iterator = paginator.paginate(Bucket=bucket_name, Prefix=prefix) - - # Filter files by date - filtered_files = [] - for page in page_iterator: - if "Contents" in page: - for obj in page["Contents"]: - last_modified = obj["LastModified"] - if start_date <= last_modified <= end_date: - filtered_files.append(obj["Key"]) - - return filtered_files - - -def download_files(bucket_name, file_keys, profile_name, local_directory): - """ - Download files from an S3 bucket. - - Parameters: - - bucket_name: str, the name of the S3 bucket - - file_keys: list of str, the keys of the files to download - - profile_name: str, the AWS profile name - - local_directory: str, the local directory to download files to - """ - # Initialize a session using the specified profile - session = boto3.Session(profile_name=profile_name) - s3_client = session.client("s3") - - # Ensure the local directory exists - if not os.path.exists(local_directory): - os.makedirs(local_directory) - - # Download each file - for key in file_keys: - file_name = os.path.basename(key) # Get only the file name from the key - local_file_path = os.path.join(local_directory, file_name) - print(f"Downloading {key} to {local_file_path}") - s3_client.download_file(bucket_name, key, local_file_path) - - print("Download completed.") - - -if __name__ == "__main__": - # Define your variables - s3_bucket = "doczyai-use2-u-cn1-s3-textract-processing-001" - # batch_id = 'batch_100524101551' - client_name = "Priority Health" - username = "ADHOC USER" - - # These endpoints are in UAT, please change them to DEV if there are access issues with UAT - api_endpoint = ( - "https://29gm8cek03.execute-api.us-east-2.amazonaws.com/dev/trigger-pipeline" - ) - create_batch_url = ( - "https://29gm8cek03.execute-api.us-east-2.amazonaws.com/dev/create-batch" - ) - - session = boto3.Session( - profile_name="temp_cred" - ) # Change the profile name to the one you have in your .aws/credentials file - s3_client = session.client("s3") - - # Use current directory as PDF directory - pdf_directory = "C:\\Doczy\\Priority Health\\For_Textract\\For_Textract\\UAT- test East Paris Surgical Center copy" - - # Create batch - batch_id, landing_zone = create_batch(s3_bucket, create_batch_url) - print(f"Batch ID: {batch_id}") - print(f"Landing Zone: {landing_zone}") - # batch_id = 'batch_110624213433' - # landing_zone = 'contracts_landing_zone/batch_110624213433/' - - if batch_id == "failed_cases": - print("Batch creation failed. Exiting...") - exit() - # Upload files and get contract list - contract_list = upload_files_to_s3(pdf_directory, s3_bucket, batch_id) - - # Create JSON object - data = { - "s3_bucket": s3_bucket, - "batch_id": batch_id, - "client_name": client_name, - "username": username, - "contract_list": contract_list, - } - - # Make POST request to API - response = requests.post(api_endpoint, json=data) - - # Print response - print(response.status_code) - print(response.json()) - - ################## - # Get text files - - prefix = f"contract-text-file/{batch_id}/" # if you have a specific prefix (folder) in your bucket - - # These dates are to filter the contracts in case there are older contracts in the same batch - start_date = "2024-06-04T00:00:00Z" # ISO 8601 format - end_date = "2024-06-14T23:59:59Z" # ISO 8601 format - profile_name = "temp_cred" - local_directory = "C:\\Doczy\\Priority Health\\For_Textract\\For_Textract\\text otuput" # local directory to save files - - # List filtered files - time.sleep( - 30 - ) # Waiting for the text files to be generated, this may take longer and files may not be available after 30 seconds sometimes - filtered_files = list_filtered_files( - s3_bucket, prefix, start_date, end_date, profile_name - ) - print(f"Filtered files: {len(filtered_files)}") - - # Download files - download_files(s3_bucket, filtered_files, profile_name, local_directory) diff --git a/fieldExtraction/src/top_down_funcs.py b/fieldExtraction/src/top_down_funcs.py deleted file mode 100644 index 505e1e2..0000000 --- a/fieldExtraction/src/top_down_funcs.py +++ /dev/null @@ -1,127 +0,0 @@ -import prompts -import claude_funcs -import utils - -import json - - -def run_top_down(filename, text_dict): - """ - Executes the Top Down processing strategy on a provided dictionary of text pages, extracting structured data based on specified prompts. - - The function first filters and processes each page of text that is correctly numbered, using a primary analysis prompt. The results - from this analysis are then parsed into dictionaries, tagged with their respective page numbers and filename, and collected. - After the initial processing, a secondary Top Down analysis is conducted to refine and possibly expand the extracted data. - - Parameters: - filename (str): The filename associated with the text, used to tag the output data. - text_dict (dict): A dictionary where keys are page numbers and values are the text on those pages. - - Returns: - list of dict: A list of dictionaries where each dictionary contains structured results from both primary and secondary - Top Down analyses, associated with a specific page and the overall document. - """ - - all_results = [] - - # Primary - for page_num, page_text in text_dict.items(): - if not page_num.isdigit(): - continue - prompt = prompts.TOP_DOWN_PRIMARY(page_text) - answer = claude_funcs.invoke_claude_3(prompt, max_tokens=4000) - answer_dict = json.loads(answer) - answer_dict.update({"page_num": page_num, "Filename": filename}) - # answer_dicts = dict_operations.primary_string_to_dict({page_num : answer}, filename) # Convert to dictionaries - all_results.append(answer_dict) - - # td_primary = [i for d in all_results for i in d] # Consolidate to one list - # print(td_primary) - - # Secondaries - td_final = top_down_secondary(all_results, text_dict) - - return td_final # List of list of dictionaries - - -def top_down_secondary(td_results, text_dict): - """ - Conducts secondary processing on results obtained from the primary Top Down analysis of document text, enhancing detail and accuracy. - - This function iteratively enhances each dictionary result from the initial analysis by adding or refining information related to: - - Market metal levels by running a specific function to determine the contract marketplace metal level. - - Effective dates by analyzing the context around specific keywords in the text and extracting these dates. - - Termination dates, similarly extracted based on the presence and context of specific keywords. - - Parameters: - td_results (list of dict): Initial dictionaries from the primary Top Down processing containing basic extracted data. - text_dict (dict): Dictionary keyed by page numbers, providing the full text for corresponding analysis and extraction tasks. - - Returns: - list of dict: Updated list of dictionaries, each enhanced with additional detailed attributes like metal level and date specifics. - """ - updated_dicts = [] - for d in td_results: - # Run Metal Level - d["CONTRACT_MARKETPLACE_METAL_LEVEL"] = run_top_down_metal_level( - d, text_dict[d["page_num"]] - ) - - # Dates - # d['LOB_PRICING_TERMS_EFFECTIVE_DATE'] = run_top_down_date('EFFECTIVE' , d, text_dict[d['page_num']]) - - # # if auto_renewal == N: else: 'N/A' - # d['LOB_PRICING_TERMS_TERMINATION_DATE'] = run_top_down_date('TERMINATION', d, text_dict[d['page_num']]) - - updated_dicts.append(d) - return updated_dicts - - -def run_top_down_metal_level(d, page): - """ - Identifies and extracts the metal level of a contract within a specific line of business (LOB) from the provided page text. - - This function determines whether the contract's LOB is associated with marketplace or commercial sectors by examining the - 'CONTRACT_LOB' key in the dictionary. If relevant, it constructs and sends a specific prompt to a language model to extract the - metal level (e.g., Bronze, Silver, Gold, Platinum). If the LOB is not relevant, it directly assigns 'N/A'. - - Parameters: - d (dict): A dictionary containing extracted information from primary Top Down analysis, specifically the 'CONTRACT_LOB' key. - page (str): The text content of the page that is being analyzed for metal level information. - - Returns: - str: The metal level of the contract as determined by the analysis, or 'N/A' if the contract LOB is not applicable. - """ - - if ( - "MARKETPLACE" in str(d["CONTRACT_LOB"]).upper() - or "COMMERCIAL" in str(d["CONTRACT_LOB"]).upper() - ): - prompt = prompts.TOP_DOWN_METAL_LEVEL(d["CONTRACT_LOB"], page) - answer = claude_funcs.invoke_claude_3(prompt, max_tokens=4000) - else: - answer = "N/A" - return answer - - -def run_top_down_date(type_, d, page): - """DEPRECATED - Extracts specific date-related information from a page of text using a Top Down processing approach. - - This function tailors the extraction to focus on either 'EFFECTIVE' or 'TERMINATION' dates by constructing - a prompt that directs a language model to search for and interpret date information relevant to the provided type. - It formats the input data to fit the processing needs, sends it along with the page text to the model, and captures - the model's response. - - Parameters: - type_ (str): Specifies the type of date to extract, 'EFFECTIVE' or 'TERMINATION'. - d (dict): A dictionary containing preliminary data extracted from the text, which may include metadata like filename or page number. - page (str): The text content of the page from which to extract the date. - - Returns: - str: The extracted date as a string, based on the model's interpretation of the input prompt and text context. - """ - formatted_d = utils.format_td_check([d], ["Filename", "page_num"]) - prompt = prompts.TOP_DOWN_DATE("EFFECTIVE", formatted_d, page) - answer = claude_funcs.invoke_claude_3(prompt, max_tokens=4000) - return answer diff --git a/fieldExtraction/src/utils.py b/fieldExtraction/src/utils.py deleted file mode 100644 index da28983..0000000 --- a/fieldExtraction/src/utils.py +++ /dev/null @@ -1,172 +0,0 @@ -import os -import re -import pandas as pd -import shutil - -import config - - -def read_local(file_path): - # Check if the file is a text file - if os.path.isfile(file_path) and file_path.endswith(".txt"): - try: - # First attempt to open the file with UTF-8 encoding - with open(file_path, "r", encoding="utf-8") as file: - file_contents = file.read() - return file_contents - except UnicodeDecodeError: - # If UTF-8 fails, try reading the file with ANSI encoding - try: - with open(file_path, "r", encoding="cp1252") as file: - file_contents = file.read() - return file_contents - except UnicodeDecodeError: - # If ANSI also fails, log an error message or handle it accordingly - print(f"Failed to decode {file_path} with UTF-8 and cp1252 encodings.") - - -def read_s3(): - s3_client = config.S3_CLIENT - objects = s3_client.list_objects_v2(Bucket=config.BUCKET, Prefix=config.PREFIX) - file_list = [] - for obj in objects["Contents"]: - if not obj["Key"].endswith("/"): - file_list.append(obj["Key"]) - contract_list = sorted(file_list) - files = {} - for contract in contract_list: - data = s3_client.get_object(Bucket=config.BUCKET, Key=contract) - contents = data["Body"].read() - context = contents.decode("utf-8") - path, filename = os.path.split(contract) - files[filename] = context - return files - - -def read_input(path=config.LOCAL_PATH, mode=config.READ_MODE): - if mode == "_LOCAL_": - files = {} - for file in os.listdir(path): - full_path = os.path.join(path, file) - file_text = read_local(full_path) - files[file] = file_text - return files - elif mode == "_S3_": - return read_s3() - - -def consolidate_individual(input_folder="results", output_folder="output"): - dfs = [] - for filename in os.listdir(input_folder): - if filename.endswith(".csv"): - filepath = os.path.join(input_folder, filename) - dfs.append(pd.read_csv(filepath)) - - # Remove temp folder - if input_folder == "temp" and os.path.exists(input_folder): - shutil.rmtree(input_folder) - - consolidated_df = pd.concat(dfs, ignore_index=True) - - # Write output - version = 1 - existing_files = [ - filename - for filename in os.listdir(output_folder) - if filename.startswith(f"consolidated_results_{config.TODAY}") - ] - if existing_files: - versions = [ - int(file.split("_v")[1].split(".")[0]) - for file in existing_files - if "_v" in file - ] - if versions: - version = max(versions) + 1 - filename = f"consolidated_results_{config.TODAY}_v{version}.csv" - consolidated_df.to_csv(os.path.join(output_folder, filename)) - - -def preprocess_text_file(file_path): - # Attempt to open the file with UTF-8 encoding first - try: - with open(file_path, "r", encoding="utf-8") as file: - text = file.read() - except UnicodeDecodeError: - # If UTF-8 fails, try reading the file with ANSI (cp1252) encoding - try: - with open(file_path, "r", encoding="cp1252") as file: - text = file.read() - except UnicodeDecodeError: - # If ANSI also fails, log an error message or handle it accordingly - print(f"Failed to decode {file_path} with UTF-8 and cp1252 encodings.") - return [] - - # Split the text into pages based on a specific marker - pages = re.split(r"Start of Page No\. = \d+", text) - return pages - - -def format_td_check(td_dicts, dont_include_list): - final_str = "" - dict_count = 1 - for td_dict in td_dicts: - final_str += str(dict_count) + ". " - for k in td_dict.keys(): - if k not in dont_include_list: - final_str += k + ": " + td_dict[k] + ", " - final_str += "\n" - dict_count += 1 - return final_str - - -def consolidate_csvs( - output_dir=config.CONSOLIDATED_OUTPUT_DIRECTORY, output_file=config.OUTPUT_CSV_PATH -): - os.makedirs(output_dir, exist_ok=True) - - df_list = [] - # Walk through each folder in the output directory - for root, dirs, files in os.walk(output_dir): - for dir_name in dirs: - dir_path = os.path.join(root, dir_name) - file_path = os.path.join(dir_path, config.PROCESSED_RESULTS_NAME) - if os.path.isfile(file_path): - try: - df = pd.read_csv(file_path) - df_list.append(df) - except: - pass - - concatenated_df = pd.concat(df_list, ignore_index=True) - concatenated_df.to_csv( - os.path.join(config.CONSOLIDATED_OUTPUT_DIRECTORY, output_file), index=False - ) - print(f"All CSV files have been consolidated into {output_file}") - - -def contains_reimbursement(text, page): - if isinstance(text, dict): - return page.isdigit() and ( - "%" in text[page] or "$" in text[page] or "percent" in text[page].lower() - ) - elif isinstance(text, str): - return "%" in text or "$" in text or "percent" in text.lower() - else: - print("contains_reimbursement - Invalid data type") - - -def filter_already_processed(input_dict): - already_processed = [] - for folder_name in os.listdir(config.OUTPUT_DIRECTORY): - if config.PROCESSED_RESULTS_NAME in os.listdir( - os.path.join(config.OUTPUT_DIRECTORY, folder_name) - ): - already_processed.append(folder_name + ".txt") - - input_dict = { - key: input_dict[key] - for key in input_dict.keys() - if key not in already_processed - } - return input_dict diff --git a/fieldExtraction/tests/example_test.py b/fieldExtraction/tests/example_test.py deleted file mode 100644 index 3b79f3d..0000000 --- a/fieldExtraction/tests/example_test.py +++ /dev/null @@ -1,2 +0,0 @@ -def test_always_passes(): - assert True