diff --git a/.github/workflows/momento-local-tests.yml b/.github/workflows/momento-local-tests.yml index 2fe2a134..d7a03888 100644 --- a/.github/workflows/momento-local-tests.yml +++ b/.github/workflows/momento-local-tests.yml @@ -13,7 +13,9 @@ jobs: runs-on: ${{ matrix.os }} env: - TEST_API_KEY: ${{ secrets.ALPHA_TEST_AUTH_TOKEN }} + MOMENTO_API_KEY: ${{ secrets.ALPHA_API_KEY_V2 }} + MOMENTO_ENDPOINT: "cell-alpha-dev.preprod.a.momentohq.com" + V1_API_KEY: ${{ secrets.ALPHA_TEST_AUTH_TOKEN }} TEST_CACHE_NAME: python-integration-test-${{ matrix.python-version }}-${{ matrix.new-python-protobuf }}-${{ github.sha }} steps: diff --git a/.github/workflows/on-pull-request.yml b/.github/workflows/on-pull-request.yml index 6b15d5aa..a379f4c7 100644 --- a/.github/workflows/on-pull-request.yml +++ b/.github/workflows/on-pull-request.yml @@ -4,6 +4,11 @@ on: pull_request: branches: [main] +env: + V1_API_KEY: ${{ secrets.ALPHA_TEST_AUTH_TOKEN }} + MOMENTO_API_KEY: ${{ secrets.ALPHA_API_KEY_V2 }} + MOMENTO_ENDPOINT: "cell-alpha-dev.preprod.a.momentohq.com" + jobs: test: strategy: @@ -15,7 +20,6 @@ jobs: runs-on: ${{ matrix.os }} env: - TEST_API_KEY: ${{ secrets.ALPHA_TEST_AUTH_TOKEN }} TEST_CACHE_NAME: python-integration-test-${{ matrix.python-version }}-${{ matrix.new-python-protobuf }}-${{ github.sha }} steps: @@ -78,10 +82,6 @@ jobs: # the cache for one job in another job. max-parallel: 1 - env: - # TODO: remove token stored as secret in favor of using a - # momento-local instance that can be spun up for testing - MOMENTO_API_KEY: ${{ secrets.ALPHA_TEST_AUTH_TOKEN }} steps: - uses: actions/checkout@v3 @@ -139,6 +139,7 @@ jobs: poetry run python -m ${{ matrix.package }}.quickstart poetry run python -m ${{ matrix.package }}.example poetry run python -m ${{ matrix.package }}.example_async + poetry run python -m ${{ matrix.package }}.topic_publish - name: Run docs samples for python >= 3.10 id: docs-ex-validation diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3eaa4f0a..f68a3fd8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -169,13 +169,13 @@ poetry run isort . ## Tests :zap: -Integration tests require an api key for testing. Set the env var `TEST_API_KEY` to +Integration tests require an api key for testing. Set the env vars `MOMENTO_API_KEY` and `MOMENTO_ENDPOINT` to provide it. The env `TEST_CACHE_NAME` is also required, but for now any string value works. Example of running tests against all python versions: ``` -TEST_API_KEY= TEST_CACHE_NAME= poetry run pytest +MOMENTO_API_KEY= MOMENTO_ENDPOINT= TEST_CACHE_NAME= poetry run pytest ``` ### For M1 Users @@ -188,7 +188,7 @@ a github issue with us to let us know. And in the meantime you can work around issue by installing Rosetta 2 and re-running with: ``` -arch -x86_64 TEST_API_KEY= TEST_CACHE_NAME= poetry run pytest +arch -x86_64 MOMENTO_API_KEY= MOMENTO_ENDPOINT= TEST_CACHE_NAME= poetry run pytest ``` ### Developing new test cases? diff --git a/examples/README.md b/examples/README.md index 4c2cc2c4..0e92b63d 100644 --- a/examples/README.md +++ b/examples/README.md @@ -9,6 +9,7 @@ _Read this in other languages_: [日本語](README.ja.md) - [Python 3.7 or above is required](https://www.python.org/downloads/) - To get started with Momento you will need a Momento API key. You can get one from the [Momento Console](https://console.gomomento.com). +- A Momento service endpoint is required. You can find a [list of them here](https://docs.momentohq.com/platform/regions) - Developer libraries (gcc/python dev headers) installed on machine you intend to run on **Amazon Linux** @@ -44,29 +45,29 @@ poetry install To run the python version 3.10+ examples: ```bash -MOMENTO_API_KEY= poetry run python -m py310.example -MOMENTO_API_KEY= poetry run python -m py310.example_async +MOMENTO_API_KEY= MOMENTO_ENDPOINT= poetry run python -m py310.example +MOMENTO_API_KEY= MOMENTO_ENDPOINT= poetry run python -m py310.example_async ``` To run the examples with SDK debug logging enabled: ```bash -DEBUG=true MOMENTO_API_KEY= poetry run python -m py310.example -DEBUG=true MOMENTO_API_KEY= poetry run python -m py310.example_async +DEBUG=true MOMENTO_API_KEY= MOMENTO_ENDPOINT= poetry run python -m py310.example +DEBUG=true MOMENTO_API_KEY= MOMENTO_ENDPOINT= poetry run python -m py310.example_async ``` To run the python version <3.10 examples: ```bash -MOMENTO_API_KEY= poetry run python -m prepy310.example -MOMENTO_API_KEY= poetry run python -m prepy310.example_async +MOMENTO_API_KEY= MOMENTO_ENDPOINT= poetry run python -m prepy310.example +MOMENTO_API_KEY= MOMENTO_ENDPOINT= poetry run python -m prepy310.example_async ``` To run the examples with SDK debug logging enabled: ```bash -DEBUG=true MOMENTO_API_KEY= poetry run python -m prepy310.example -DEBUG=true MOMENTO_API_KEY= poetry run python -m prepy310.example_async +DEBUG=true MOMENTO_API_KEY= MOMENTO_ENDPOINT= poetry run python -m prepy310.example +DEBUG=true MOMENTO_API_KEY= MOMENTO_ENDPOINT= poetry run python -m prepy310.example_async ``` ## Running the Example Using pip @@ -80,29 +81,29 @@ pip install -r requirements.txt To run the python version 3.10+ examples: ```bash -MOMENTO_API_KEY= python -m py310.example -MOMENTO_API_KEY= python -m py310.example_async +MOMENTO_API_KEY= MOMENTO_ENDPOINT= python -m py310.example +MOMENTO_API_KEY= MOMENTO_ENDPOINT= python -m py310.example_async ``` To run the examples with SDK debug logging enabled: ```bash -DEBUG=true MOMENTO_API_KEY= python -m py310.example -DEBUG=true MOMENTO_API_KEY= python -m py310.example_async +DEBUG=true MOMENTO_API_KEY= MOMENTO_ENDPOINT= python -m py310.example +DEBUG=true MOMENTO_API_KEY= MOMENTO_ENDPOINT= python -m py310.example_async ``` To run the python version <3.10 examples: ```bash -MOMENTO_API_KEY= python -m prepy310.example -MOMENTO_API_KEY= python -m prepy310.example_async +MOMENTO_API_KEY= MOMENTO_ENDPOINT= python -m prepy310.example +MOMENTO_API_KEY= MOMENTO_ENDPOINT= python -m prepy310.example_async ``` To run the examples with SDK debug logging enabled: ```bash -DEBUG=true MOMENTO_API_KEY= python -m prepy310.example -DEBUG=true MOMENTO_API_KEY= python -m prepy310.example_async +DEBUG=true MOMENTO_API_KEY= MOMENTO_ENDPOINT= python -m prepy310.example +DEBUG=true MOMENTO_API_KEY= MOMENTO_ENDPOINT= python -m prepy310.example_async ``` ## Running the load generator example @@ -135,7 +136,7 @@ To run the load generator: ```bash # Run example load generator -MOMENTO_API_KEY= poetry run python -m py310.example_load_gen +MOMENTO_API_KEY= MOMENTO_ENDPOINT= poetry run python -m py310.example_load_gen ``` You can check out the example code in [example_load_gen.py](py310/example_load_gen.py). The configurable diff --git a/examples/observability.py b/examples/observability.py index 4304f393..e9f2fa49 100644 --- a/examples/observability.py +++ b/examples/observability.py @@ -8,7 +8,7 @@ example_observability_setup_tracing() -_AUTH_PROVIDER = CredentialProvider.from_environment_variable("MOMENTO_API_KEY") +_AUTH_PROVIDER = CredentialProvider.from_environment_variables_v2() _ITEM_DEFAULT_TTL_SECONDS = timedelta(seconds=60) _CACHE_NAME = "test-cache" _KEY = "test-key" diff --git a/examples/poetry.lock b/examples/poetry.lock index a6737dd1..4781aba0 100644 --- a/examples/poetry.lock +++ b/examples/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.1.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.5.0 and should not be changed by hand. [[package]] name = "colorama" @@ -6,8 +6,6 @@ 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" -groups = ["main"] -markers = "sys_platform == \"win32\"" files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, @@ -19,7 +17,6 @@ version = "6.7.0" description = "Add colours to the output of Python's logging module." optional = false python-versions = ">=3.6" -groups = ["main"] files = [ {file = "colorlog-6.7.0-py2.py3-none-any.whl", hash = "sha256:0d33ca236784a1ba3ff9c532d4964126d8a2c44f1f0cb1d2b0728196f512f662"}, {file = "colorlog-6.7.0.tar.gz", hash = "sha256:bd94bd21c1e13fac7bd3153f4bc3a7dc0eb0974b8bc2fdf1a989e474f6e582e5"}, @@ -33,70 +30,79 @@ development = ["black", "flake8", "mypy", "pytest", "types-colorama"] [[package]] name = "grpcio" -version = "1.62.3" +version = "1.76.0" description = "HTTP/2-based RPC framework" optional = false -python-versions = ">=3.7" -groups = ["main"] +python-versions = ">=3.9" files = [ - {file = "grpcio-1.62.3-cp310-cp310-linux_armv7l.whl", hash = "sha256:13571a5b868dcc308a55d36669a2d17d9dcd6ec8335213f6c49cc68da7305abe"}, - {file = "grpcio-1.62.3-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:f5def814c5a4c90c8fe389c526ab881f4a28b7e239b23ed8e02dd02934dfaa1a"}, - {file = "grpcio-1.62.3-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:7349cd7445ac65fbe1b744dcab9cc1ec02dae2256941a2e67895926cbf7422b4"}, - {file = "grpcio-1.62.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:646c14e9f3356d3f34a65b58b0f8d08daa741ba1d4fcd4966b79407543332154"}, - {file = "grpcio-1.62.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:807176971c504c598976f5a9ea62363cffbbbb6c7509d9808c2342b020880fa2"}, - {file = "grpcio-1.62.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:43670a25b752b7ed960fcec3db50ae5886dc0df897269b3f5119cde9b731745f"}, - {file = "grpcio-1.62.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:668211f3699bbee4deaf1d6e6b8df59328bf63f077bf2dc9b8bfa4a17df4a279"}, - {file = "grpcio-1.62.3-cp310-cp310-win32.whl", hash = "sha256:216740723fc5971429550c374a0c039723b9d4dcaf7ba05227b7e0a500b06417"}, - {file = "grpcio-1.62.3-cp310-cp310-win_amd64.whl", hash = "sha256:b708401ede2c4cb8943e8a713988fcfe6cbea105b07cd7fa7c8a9f137c22bddb"}, - {file = "grpcio-1.62.3-cp311-cp311-linux_armv7l.whl", hash = "sha256:c8bb1a7aa82af6c7713cdf9dcb8f4ea1024ac7ce82bb0a0a82a49aea5237da34"}, - {file = "grpcio-1.62.3-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:57823dc7299c4f258ae9c32fd327d29f729d359c34d7612b36e48ed45b3ab8d0"}, - {file = "grpcio-1.62.3-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:1de3d04d9a4ec31ebe848ae1fe61e4cbc367fb9495cbf6c54368e60609a998d9"}, - {file = "grpcio-1.62.3-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:325c56ce94d738c31059cf91376f625d3effdff8f85c96660a5fd6395d5a707f"}, - {file = "grpcio-1.62.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c175b252d063af388523a397dbe8edbc4319761f5ee892a8a0f5890acc067362"}, - {file = "grpcio-1.62.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:25cd75dc73c5269932413e517be778640402f18cf9a81147e68645bd8af18ab0"}, - {file = "grpcio-1.62.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a1b85d35a7d9638c03321dfe466645b87e23c30df1266f9e04bbb5f44e7579a9"}, - {file = "grpcio-1.62.3-cp311-cp311-win32.whl", hash = "sha256:6be243f3954b0ca709f56f9cae926c84ac96e1cce19844711e647a1f1db88b99"}, - {file = "grpcio-1.62.3-cp311-cp311-win_amd64.whl", hash = "sha256:e9ffdb7bc9ccd56ec201aec3eab3432e1e820335b5a16ad2b37e094218dcd7a6"}, - {file = "grpcio-1.62.3-cp312-cp312-linux_armv7l.whl", hash = "sha256:4c9c1502c76cadbf2e145061b63af077b08d5677afcef91970d6db87b30e2f8b"}, - {file = "grpcio-1.62.3-cp312-cp312-macosx_10_10_universal2.whl", hash = "sha256:abfe64811177e681edc81d9d9d1bd23edc5f599bd9846650864769264ace30cd"}, - {file = "grpcio-1.62.3-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:3737e5ef0aa0fcdfeaf3b4ecc1a6be78b494549b28aec4b7f61b5dc357f7d8be"}, - {file = "grpcio-1.62.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:940459d81685549afdfe13a6de102c52ea4cdda093477baa53056884aadf7c48"}, - {file = "grpcio-1.62.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac9783d5679c8da612465168c820fd0b916e70ec5496c840bddba0be7f2d124c"}, - {file = "grpcio-1.62.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:c95a0b76a44c548e6bd8c5f7dbecf89c77e2e16d3965be817b57769c4a30bea2"}, - {file = "grpcio-1.62.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b097347441b86a8c3ad9579abaf5e5f7f82b1d74a898f47360433b2bca0e4536"}, - {file = "grpcio-1.62.3-cp312-cp312-win32.whl", hash = "sha256:3fb7d966a976d762a31346353a19fce4afcffbeda3027dd563bc8cb521fcf799"}, - {file = "grpcio-1.62.3-cp312-cp312-win_amd64.whl", hash = "sha256:454a6aed4ebd56198d37e1f3be6f1c70838e33dd62d1e2cea12f2bcb08efecc5"}, - {file = "grpcio-1.62.3-cp37-cp37m-linux_armv7l.whl", hash = "sha256:8257cc9e55fb0e2149a652d9dc14c023720f9e73c9145776e07c97e0a553922e"}, - {file = "grpcio-1.62.3-cp37-cp37m-macosx_10_10_universal2.whl", hash = "sha256:e202e3f963480ca067a261179b1ac610c0f0272cb4a7942d11b7e2b3fc99c3aa"}, - {file = "grpcio-1.62.3-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:9c4aae4e683776c319169d87e7891b67b75e3f1c0beeb877902ea148b0585164"}, - {file = "grpcio-1.62.3-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a82410d7620c07cb32624e38f2a106980564dfef9dbe78f5b295cda9ef217c03"}, - {file = "grpcio-1.62.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c118cfc80e2402a5595be36e9245ffd9b0e146f426cc40bdf60015bf183f8373"}, - {file = "grpcio-1.62.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:377babc817e8b4186aed7ed56e832867c513e4e9b6c3503565c344ffdef440d4"}, - {file = "grpcio-1.62.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7b33c1807d4ac564a3027d06f21a2220c116ceacaaef614deb96b3341ee58896"}, - {file = "grpcio-1.62.3-cp37-cp37m-win_amd64.whl", hash = "sha256:1ac0944e9e3ee3e20825226d1e17985e9f88487055c475986cf0922a7d806d8a"}, - {file = "grpcio-1.62.3-cp38-cp38-linux_armv7l.whl", hash = "sha256:56757d3e4cf5d4b98a30f2c5456151607261c891fa2298a4554848dcbf83083d"}, - {file = "grpcio-1.62.3-cp38-cp38-macosx_10_10_universal2.whl", hash = "sha256:ea7ca66a58421411c6486fa5015fe7704e2816ff0b4ec4fb779ad5e1cbbdabf3"}, - {file = "grpcio-1.62.3-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:4dab8b64c438e19c763a6332b55e5efdbecfb7c55ae59a42c38c81ed27955fa5"}, - {file = "grpcio-1.62.3-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b033d50bd41e506e3b579775f54a30c16c222e0d88847ac8098d2eca2a7454cc"}, - {file = "grpcio-1.62.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75a4e9ac7ff185cad529f35934c5d711b88aca48b90c70e195f5657da50ce321"}, - {file = "grpcio-1.62.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:bd900e666bb68fff49703084be14407cd73b8a5752a7590cea98ec22de24fb5d"}, - {file = "grpcio-1.62.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:80a82fdee14dc27e9299248b7aabd5a8739a1cf6b76c78aa2b848158b44a99d5"}, - {file = "grpcio-1.62.3-cp38-cp38-win32.whl", hash = "sha256:8ae2e7a390b2cdd2a95d3bf3b3385245eeb48a5e853943cb46139666462c2d1a"}, - {file = "grpcio-1.62.3-cp38-cp38-win_amd64.whl", hash = "sha256:620165df24aae3d5b3e84cb8dd6b98f6ed49aed04126186bbf43061e301d6a21"}, - {file = "grpcio-1.62.3-cp39-cp39-linux_armv7l.whl", hash = "sha256:8a5f00b2508937952d23a1767739e95bbbe1120f8a66d10187d5e971d56bb55c"}, - {file = "grpcio-1.62.3-cp39-cp39-macosx_10_10_universal2.whl", hash = "sha256:059444f0ed5dba73ab7dd0ee7e8e6b606df4130d2b0a9f010f84da4ab9f6c2d8"}, - {file = "grpcio-1.62.3-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:114f2a865886ff33f85d70670e971fe0e3d252a1209656fefa5470286e3fcc76"}, - {file = "grpcio-1.62.3-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6da20a1ae010a988bc4ed47850f1122de0a88e18cd2f901fcf56007be1fc6c30"}, - {file = "grpcio-1.62.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2ff8ac447765e173842b554b31307b98b3bb1852710903ebb936e7efb7df6e5"}, - {file = "grpcio-1.62.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:81b7c121c4e52a0749bf0759185b8d5cfa48a786cd7d411cdab08269813e0aab"}, - {file = "grpcio-1.62.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9d5f8e0050a179b3bce9189b522dc91008d44f08c757a7c310e0fd06b4d3d147"}, - {file = "grpcio-1.62.3-cp39-cp39-win32.whl", hash = "sha256:74f3fc9b93290e58264844f5bc46df4c58a94c4287a277dbcf75344fc6c37ca4"}, - {file = "grpcio-1.62.3-cp39-cp39-win_amd64.whl", hash = "sha256:582bd03e9c3d1bd1162eb51fa0f1a35633d66e73f4f36702d3b8484a8b45eda7"}, - {file = "grpcio-1.62.3.tar.gz", hash = "sha256:4439bbd759636e37b66841117a66444b454937e27f0125205d2d117d7827c643"}, + {file = "grpcio-1.76.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:65a20de41e85648e00305c1bb09a3598f840422e522277641145a32d42dcefcc"}, + {file = "grpcio-1.76.0-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:40ad3afe81676fd9ec6d9d406eda00933f218038433980aa19d401490e46ecde"}, + {file = "grpcio-1.76.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:035d90bc79eaa4bed83f524331d55e35820725c9fbb00ffa1904d5550ed7ede3"}, + {file = "grpcio-1.76.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:4215d3a102bd95e2e11b5395c78562967959824156af11fa93d18fdd18050990"}, + {file = "grpcio-1.76.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:49ce47231818806067aea3324d4bf13825b658ad662d3b25fada0bdad9b8a6af"}, + {file = "grpcio-1.76.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:8cc3309d8e08fd79089e13ed4819d0af72aa935dd8f435a195fd152796752ff2"}, + {file = "grpcio-1.76.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:971fd5a1d6e62e00d945423a567e42eb1fa678ba89072832185ca836a94daaa6"}, + {file = "grpcio-1.76.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9d9adda641db7207e800a7f089068f6f645959f2df27e870ee81d44701dd9db3"}, + {file = "grpcio-1.76.0-cp310-cp310-win32.whl", hash = "sha256:063065249d9e7e0782d03d2bca50787f53bd0fb89a67de9a7b521c4a01f1989b"}, + {file = "grpcio-1.76.0-cp310-cp310-win_amd64.whl", hash = "sha256:a6ae758eb08088d36812dd5d9af7a9859c05b1e0f714470ea243694b49278e7b"}, + {file = "grpcio-1.76.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:2e1743fbd7f5fa713a1b0a8ac8ebabf0ec980b5d8809ec358d488e273b9cf02a"}, + {file = "grpcio-1.76.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:a8c2cf1209497cf659a667d7dea88985e834c24b7c3b605e6254cbb5076d985c"}, + {file = "grpcio-1.76.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:08caea849a9d3c71a542827d6df9d5a69067b0a1efbea8a855633ff5d9571465"}, + {file = "grpcio-1.76.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:f0e34c2079d47ae9f6188211db9e777c619a21d4faba6977774e8fa43b085e48"}, + {file = "grpcio-1.76.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8843114c0cfce61b40ad48df65abcfc00d4dba82eae8718fab5352390848c5da"}, + {file = "grpcio-1.76.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8eddfb4d203a237da6f3cc8a540dad0517d274b5a1e9e636fd8d2c79b5c1d397"}, + {file = "grpcio-1.76.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:32483fe2aab2c3794101c2a159070584e5db11d0aa091b2c0ea9c4fc43d0d749"}, + {file = "grpcio-1.76.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:dcfe41187da8992c5f40aa8c5ec086fa3672834d2be57a32384c08d5a05b4c00"}, + {file = "grpcio-1.76.0-cp311-cp311-win32.whl", hash = "sha256:2107b0c024d1b35f4083f11245c0e23846ae64d02f40b2b226684840260ed054"}, + {file = "grpcio-1.76.0-cp311-cp311-win_amd64.whl", hash = "sha256:522175aba7af9113c48ec10cc471b9b9bd4f6ceb36aeb4544a8e2c80ed9d252d"}, + {file = "grpcio-1.76.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:81fd9652b37b36f16138611c7e884eb82e0cec137c40d3ef7c3f9b3ed00f6ed8"}, + {file = "grpcio-1.76.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:04bbe1bfe3a68bbfd4e52402ab7d4eb59d72d02647ae2042204326cf4bbad280"}, + {file = "grpcio-1.76.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d388087771c837cdb6515539f43b9d4bf0b0f23593a24054ac16f7a960be16f4"}, + {file = "grpcio-1.76.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:9f8f757bebaaea112c00dba718fc0d3260052ce714e25804a03f93f5d1c6cc11"}, + {file = "grpcio-1.76.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:980a846182ce88c4f2f7e2c22c56aefd515daeb36149d1c897f83cf57999e0b6"}, + {file = "grpcio-1.76.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f92f88e6c033db65a5ae3d97905c8fea9c725b63e28d5a75cb73b49bda5024d8"}, + {file = "grpcio-1.76.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4baf3cbe2f0be3289eb68ac8ae771156971848bb8aaff60bad42005539431980"}, + {file = "grpcio-1.76.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:615ba64c208aaceb5ec83bfdce7728b80bfeb8be97562944836a7a0a9647d882"}, + {file = "grpcio-1.76.0-cp312-cp312-win32.whl", hash = "sha256:45d59a649a82df5718fd9527ce775fd66d1af35e6d31abdcdc906a49c6822958"}, + {file = "grpcio-1.76.0-cp312-cp312-win_amd64.whl", hash = "sha256:c088e7a90b6017307f423efbb9d1ba97a22aa2170876223f9709e9d1de0b5347"}, + {file = "grpcio-1.76.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:26ef06c73eb53267c2b319f43e6634c7556ea37672029241a056629af27c10e2"}, + {file = "grpcio-1.76.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:45e0111e73f43f735d70786557dc38141185072d7ff8dc1829d6a77ac1471468"}, + {file = "grpcio-1.76.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:83d57312a58dcfe2a3a0f9d1389b299438909a02db60e2f2ea2ae2d8034909d3"}, + {file = "grpcio-1.76.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:3e2a27c89eb9ac3d81ec8835e12414d73536c6e620355d65102503064a4ed6eb"}, + {file = "grpcio-1.76.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:61f69297cba3950a524f61c7c8ee12e55c486cb5f7db47ff9dcee33da6f0d3ae"}, + {file = "grpcio-1.76.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6a15c17af8839b6801d554263c546c69c4d7718ad4321e3166175b37eaacca77"}, + {file = "grpcio-1.76.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:25a18e9810fbc7e7f03ec2516addc116a957f8cbb8cbc95ccc80faa072743d03"}, + {file = "grpcio-1.76.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:931091142fd8cc14edccc0845a79248bc155425eee9a98b2db2ea4f00a235a42"}, + {file = "grpcio-1.76.0-cp313-cp313-win32.whl", hash = "sha256:5e8571632780e08526f118f74170ad8d50fb0a48c23a746bef2a6ebade3abd6f"}, + {file = "grpcio-1.76.0-cp313-cp313-win_amd64.whl", hash = "sha256:f9f7bd5faab55f47231ad8dba7787866b69f5e93bc306e3915606779bbfb4ba8"}, + {file = "grpcio-1.76.0-cp314-cp314-linux_armv7l.whl", hash = "sha256:ff8a59ea85a1f2191a0ffcc61298c571bc566332f82e5f5be1b83c9d8e668a62"}, + {file = "grpcio-1.76.0-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:06c3d6b076e7b593905d04fdba6a0525711b3466f43b3400266f04ff735de0cd"}, + {file = "grpcio-1.76.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fd5ef5932f6475c436c4a55e4336ebbe47bd3272be04964a03d316bbf4afbcbc"}, + {file = "grpcio-1.76.0-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:b331680e46239e090f5b3cead313cc772f6caa7d0fc8de349337563125361a4a"}, + {file = "grpcio-1.76.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2229ae655ec4e8999599469559e97630185fdd53ae1e8997d147b7c9b2b72cba"}, + {file = "grpcio-1.76.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:490fa6d203992c47c7b9e4a9d39003a0c2bcc1c9aa3c058730884bbbb0ee9f09"}, + {file = "grpcio-1.76.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:479496325ce554792dba6548fae3df31a72cef7bad71ca2e12b0e58f9b336bfc"}, + {file = "grpcio-1.76.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:1c9b93f79f48b03ada57ea24725d83a30284a012ec27eab2cf7e50a550cbbbcc"}, + {file = "grpcio-1.76.0-cp314-cp314-win32.whl", hash = "sha256:747fa73efa9b8b1488a95d0ba1039c8e2dca0f741612d80415b1e1c560febf4e"}, + {file = "grpcio-1.76.0-cp314-cp314-win_amd64.whl", hash = "sha256:922fa70ba549fce362d2e2871ab542082d66e2aaf0c19480ea453905b01f384e"}, + {file = "grpcio-1.76.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:8ebe63ee5f8fa4296b1b8cfc743f870d10e902ca18afc65c68cf46fd39bb0783"}, + {file = "grpcio-1.76.0-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:3bf0f392c0b806905ed174dcd8bdd5e418a40d5567a05615a030a5aeddea692d"}, + {file = "grpcio-1.76.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0b7604868b38c1bfd5cf72d768aedd7db41d78cb6a4a18585e33fb0f9f2363fd"}, + {file = "grpcio-1.76.0-cp39-cp39-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:e6d1db20594d9daba22f90da738b1a0441a7427552cc6e2e3d1297aeddc00378"}, + {file = "grpcio-1.76.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d099566accf23d21037f18a2a63d323075bebace807742e4b0ac210971d4dd70"}, + {file = "grpcio-1.76.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ebea5cc3aa8ea72e04df9913492f9a96d9348db876f9dda3ad729cfedf7ac416"}, + {file = "grpcio-1.76.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:0c37db8606c258e2ee0c56b78c62fc9dee0e901b5dbdcf816c2dd4ad652b8b0c"}, + {file = "grpcio-1.76.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:ebebf83299b0cb1721a8859ea98f3a77811e35dce7609c5c963b9ad90728f886"}, + {file = "grpcio-1.76.0-cp39-cp39-win32.whl", hash = "sha256:0aaa82d0813fd4c8e589fac9b65d7dd88702555f702fb10417f96e2a2a6d4c0f"}, + {file = "grpcio-1.76.0-cp39-cp39-win_amd64.whl", hash = "sha256:acab0277c40eff7143c2323190ea57b9ee5fd353d8190ee9652369fae735668a"}, + {file = "grpcio-1.76.0.tar.gz", hash = "sha256:7be78388d6da1a25c0d5ec506523db58b18be22d9c37d8d3a32c08be4987bd73"}, ] +[package.dependencies] +typing-extensions = ">=4.12,<5.0" + [package.extras] -protobuf = ["grpcio-tools (>=1.62.3)"] +protobuf = ["grpcio-tools (>=1.76.0)"] [[package]] name = "hdrhistogram" @@ -104,7 +110,6 @@ version = "0.10.3" description = "High Dynamic Range histogram in native python" optional = false python-versions = "*" -groups = ["main"] files = [ {file = "hdrhistogram-0.10.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5ca99b4ea5c4a94fff9ed9e76fe308273376f630c461379671fcbdd2c9934b0b"}, {file = "hdrhistogram-0.10.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a52d892b093e7906c91d577dafe75c2d8864a8e113e98d6f88848f9ce40a952f"}, @@ -179,14 +184,13 @@ pbr = ">=1.4" [[package]] name = "momento" -version = "1.27.0" +version = "1.28.0" description = "SDK for Momento" optional = false python-versions = "<4.0,>=3.7" -groups = ["main"] files = [ - {file = "momento-1.27.0-py3-none-any.whl", hash = "sha256:1d9f04d7a0b484403fa8199f6ad65ed84ca70ec35093e81b4ebe791cae99d767"}, - {file = "momento-1.27.0.tar.gz", hash = "sha256:3ff09ff7f889ba4ae374162aa92dd2d1a66d0dfe8af0908125dde0ed851015e4"}, + {file = "momento-1.28.0-py3-none-any.whl", hash = "sha256:804d8a034787dcea0ae2d8b4d24203c111d4ece824096e88bea3ef7037810f01"}, + {file = "momento-1.28.0.tar.gz", hash = "sha256:090aaa1cf89d05d0b6d2e5e2dd9002efa3a771da158492fe973c55f086eff53f"}, ] [package.dependencies] @@ -196,14 +200,13 @@ pyjwt = ">=2.4.0,<3.0.0" [[package]] name = "momento-wire-types" -version = "0.119.4" +version = "0.119.5" description = "Momento Client Proto Generated Files" optional = false python-versions = "<4.0,>=3.7" -groups = ["main"] files = [ - {file = "momento_wire_types-0.119.4-py3-none-any.whl", hash = "sha256:0ee1fd5e4a78945adc6bd6ec2c37d067bac79b046420aae208078e0e1390f806"}, - {file = "momento_wire_types-0.119.4.tar.gz", hash = "sha256:025c895334958f806354300309b86339e5909e8105be32d6781bf2e14af1ff5f"}, + {file = "momento_wire_types-0.119.5-py3-none-any.whl", hash = "sha256:6b88dcd6512a019015dba6894a4ae556d6c4e19b0d93a897dfdde3b78e847610"}, + {file = "momento_wire_types-0.119.5.tar.gz", hash = "sha256:5804f71195b598d58b181e28cefe648d5d4c3d43b8889763b4dc50afe3655023"}, ] [package.dependencies] @@ -216,7 +219,6 @@ version = "0.971" description = "Optional static typing for Python" optional = false python-versions = ">=3.6" -groups = ["lint"] files = [ {file = "mypy-0.971-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f2899a3cbd394da157194f913a931edfd4be5f274a88041c9dc2d9cdcb1c315c"}, {file = "mypy-0.971-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:98e02d56ebe93981c41211c05adb630d1d26c14195d04d95e49cd97dbc046dc5"}, @@ -246,7 +248,6 @@ files = [ [package.dependencies] mypy-extensions = ">=0.4.3" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typed-ast = {version = ">=1.4.0,<2", markers = "python_version < \"3.8\""} typing-extensions = ">=3.10" [package.extras] @@ -256,70 +257,64 @@ reports = ["lxml"] [[package]] name = "mypy-extensions" -version = "1.0.0" +version = "1.1.0" description = "Type system extensions for programs checked with the mypy type checker." optional = false -python-versions = ">=3.5" -groups = ["lint"] +python-versions = ">=3.8" 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"}, + {file = "mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505"}, + {file = "mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558"}, ] [[package]] name = "pbr" -version = "6.1.0" +version = "7.0.3" description = "Python Build Reasonableness" optional = false python-versions = ">=2.6" -groups = ["main"] files = [ - {file = "pbr-6.1.0-py2.py3-none-any.whl", hash = "sha256:a776ae228892d8013649c0aeccbb3d5f99ee15e005a4cbb7e61d55a067b28a2a"}, - {file = "pbr-6.1.0.tar.gz", hash = "sha256:788183e382e3d1d7707db08978239965e8b9e4e5ed42669bf4758186734d5f24"}, + {file = "pbr-7.0.3-py2.py3-none-any.whl", hash = "sha256:ff223894eb1cd271a98076b13d3badff3bb36c424074d26334cd25aebeecea6b"}, + {file = "pbr-7.0.3.tar.gz", hash = "sha256:b46004ec30a5324672683ec848aed9e8fc500b0d261d40a3229c2d2bbfcedc29"}, ] +[package.dependencies] +setuptools = "*" + [[package]] name = "protobuf" -version = "4.24.4" +version = "4.25.8" description = "" optional = false -python-versions = ">=3.7" -groups = ["main"] +python-versions = ">=3.8" files = [ - {file = "protobuf-4.24.4-cp310-abi3-win32.whl", hash = "sha256:ec9912d5cb6714a5710e28e592ee1093d68c5ebfeda61983b3f40331da0b1ebb"}, - {file = "protobuf-4.24.4-cp310-abi3-win_amd64.whl", hash = "sha256:1badab72aa8a3a2b812eacfede5020472e16c6b2212d737cefd685884c191085"}, - {file = "protobuf-4.24.4-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:8e61a27f362369c2f33248a0ff6896c20dcd47b5d48239cb9720134bef6082e4"}, - {file = "protobuf-4.24.4-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:bffa46ad9612e6779d0e51ae586fde768339b791a50610d85eb162daeb23661e"}, - {file = "protobuf-4.24.4-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:b493cb590960ff863743b9ff1452c413c2ee12b782f48beca77c8da3e2ffe9d9"}, - {file = "protobuf-4.24.4-cp37-cp37m-win32.whl", hash = "sha256:dbbed8a56e56cee8d9d522ce844a1379a72a70f453bde6243e3c86c30c2a3d46"}, - {file = "protobuf-4.24.4-cp37-cp37m-win_amd64.whl", hash = "sha256:6b7d2e1c753715dcfe9d284a25a52d67818dd43c4932574307daf836f0071e37"}, - {file = "protobuf-4.24.4-cp38-cp38-win32.whl", hash = "sha256:02212557a76cd99574775a81fefeba8738d0f668d6abd0c6b1d3adcc75503dbe"}, - {file = "protobuf-4.24.4-cp38-cp38-win_amd64.whl", hash = "sha256:2fa3886dfaae6b4c5ed2730d3bf47c7a38a72b3a1f0acb4d4caf68e6874b947b"}, - {file = "protobuf-4.24.4-cp39-cp39-win32.whl", hash = "sha256:b77272f3e28bb416e2071186cb39efd4abbf696d682cbb5dc731308ad37fa6dd"}, - {file = "protobuf-4.24.4-cp39-cp39-win_amd64.whl", hash = "sha256:9fee5e8aa20ef1b84123bb9232b3f4a5114d9897ed89b4b8142d81924e05d79b"}, - {file = "protobuf-4.24.4-py3-none-any.whl", hash = "sha256:80797ce7424f8c8d2f2547e2d42bfbb6c08230ce5832d6c099a37335c9c90a92"}, - {file = "protobuf-4.24.4.tar.gz", hash = "sha256:5a70731910cd9104762161719c3d883c960151eea077134458503723b60e3667"}, + {file = "protobuf-4.25.8-cp310-abi3-win32.whl", hash = "sha256:504435d831565f7cfac9f0714440028907f1975e4bed228e58e72ecfff58a1e0"}, + {file = "protobuf-4.25.8-cp310-abi3-win_amd64.whl", hash = "sha256:bd551eb1fe1d7e92c1af1d75bdfa572eff1ab0e5bf1736716814cdccdb2360f9"}, + {file = "protobuf-4.25.8-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:ca809b42f4444f144f2115c4c1a747b9a404d590f18f37e9402422033e464e0f"}, + {file = "protobuf-4.25.8-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:9ad7ef62d92baf5a8654fbb88dac7fa5594cfa70fd3440488a5ca3bfc6d795a7"}, + {file = "protobuf-4.25.8-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:83e6e54e93d2b696a92cad6e6efc924f3850f82b52e1563778dfab8b355101b0"}, + {file = "protobuf-4.25.8-cp38-cp38-win32.whl", hash = "sha256:27d498ffd1f21fb81d987a041c32d07857d1d107909f5134ba3350e1ce80a4af"}, + {file = "protobuf-4.25.8-cp38-cp38-win_amd64.whl", hash = "sha256:d552c53d0415449c8d17ced5c341caba0d89dbf433698e1436c8fa0aae7808a3"}, + {file = "protobuf-4.25.8-cp39-cp39-win32.whl", hash = "sha256:077ff8badf2acf8bc474406706ad890466274191a48d0abd3bd6987107c9cde5"}, + {file = "protobuf-4.25.8-cp39-cp39-win_amd64.whl", hash = "sha256:f4510b93a3bec6eba8fd8f1093e9d7fb0d4a24d1a81377c10c0e5bbfe9e4ed24"}, + {file = "protobuf-4.25.8-py3-none-any.whl", hash = "sha256:15a0af558aa3b13efef102ae6e4f3efac06f1eea11afb3a57db2901447d9fb59"}, + {file = "protobuf-4.25.8.tar.gz", hash = "sha256:6135cf8affe1fc6f76cced2641e4ea8d3e59518d1f24ae41ba97bcad82d397cd"}, ] [[package]] name = "pyjwt" -version = "2.8.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.7" -groups = ["main"] +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.8.0-py3-none-any.whl", hash = "sha256:59127c392cc44c2da5bb3192169a91f429924e17aff6534d70fdc02ab3e04320"}, - {file = "PyJWT-2.8.0.tar.gz", hash = "sha256:57e28d156e3d5c10088e0c68abb90bfac3df82b40a71bd0daa20c65ccd5c23de"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] -[package.dependencies] -typing-extensions = {version = "*", markers = "python_version <= \"3.7\""} - [package.extras] crypto = ["cryptography (>=3.4.0)"] -dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"] -docs = ["sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"] +dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx", "sphinx-rtd-theme", "zope.interface"] +docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] [[package]] @@ -328,7 +323,6 @@ version = "0.1.15" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" -groups = ["lint"] files = [ {file = "ruff-0.1.15-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:5fe8d54df166ecc24106db7dd6a68d44852d14eb0729ea4672bb4d96c320b7df"}, {file = "ruff-0.1.15-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6f0bfbb53c4b4de117ac4d6ddfd33aa5fc31beeaa21d23c45c6dd249faf9126f"}, @@ -350,84 +344,88 @@ files = [ ] [[package]] -name = "tomli" -version = "2.0.1" -description = "A lil' TOML parser" +name = "setuptools" +version = "78.1.1" +description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.7" -groups = ["lint"] -markers = "python_version < \"3.11\"" +python-versions = ">=3.9" files = [ - {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, - {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, + {file = "setuptools-78.1.1-py3-none-any.whl", hash = "sha256:c3a9c4211ff4c309edb8b8c4f1cbfa7ae324c4ba9f91ff254e3d305b9fd54561"}, + {file = "setuptools-78.1.1.tar.gz", hash = "sha256:fcc17fd9cd898242f6b4adfaca46137a9edef687f43e6f78469692a5e70d851d"}, ] +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.8.0)"] +core = ["importlib_metadata (>=6)", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.7.2)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.14.*)", "pytest-mypy"] + [[package]] -name = "typed-ast" -version = "1.5.5" -description = "a fork of Python 2 and 3 ast modules with type comment support" +name = "tomli" +version = "2.3.0" +description = "A lil' TOML parser" optional = false -python-versions = ">=3.6" -groups = ["lint"] -markers = "python_version < \"3.8\"" +python-versions = ">=3.8" files = [ - {file = "typed_ast-1.5.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4bc1efe0ce3ffb74784e06460f01a223ac1f6ab31c6bc0376a21184bf5aabe3b"}, - {file = "typed_ast-1.5.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5f7a8c46a8b333f71abd61d7ab9255440d4a588f34a21f126bbfc95f6049e686"}, - {file = "typed_ast-1.5.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:597fc66b4162f959ee6a96b978c0435bd63791e31e4f410622d19f1686d5e769"}, - {file = "typed_ast-1.5.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d41b7a686ce653e06c2609075d397ebd5b969d821b9797d029fccd71fdec8e04"}, - {file = "typed_ast-1.5.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:5fe83a9a44c4ce67c796a1b466c270c1272e176603d5e06f6afbc101a572859d"}, - {file = "typed_ast-1.5.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d5c0c112a74c0e5db2c75882a0adf3133adedcdbfd8cf7c9d6ed77365ab90a1d"}, - {file = "typed_ast-1.5.5-cp310-cp310-win_amd64.whl", hash = "sha256:e1a976ed4cc2d71bb073e1b2a250892a6e968ff02aa14c1f40eba4f365ffec02"}, - {file = "typed_ast-1.5.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c631da9710271cb67b08bd3f3813b7af7f4c69c319b75475436fcab8c3d21bee"}, - {file = "typed_ast-1.5.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b445c2abfecab89a932b20bd8261488d574591173d07827c1eda32c457358b18"}, - {file = "typed_ast-1.5.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc95ffaaab2be3b25eb938779e43f513e0e538a84dd14a5d844b8f2932593d88"}, - {file = "typed_ast-1.5.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61443214d9b4c660dcf4b5307f15c12cb30bdfe9588ce6158f4a005baeb167b2"}, - {file = "typed_ast-1.5.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6eb936d107e4d474940469e8ec5b380c9b329b5f08b78282d46baeebd3692dc9"}, - {file = "typed_ast-1.5.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e48bf27022897577d8479eaed64701ecaf0467182448bd95759883300ca818c8"}, - {file = "typed_ast-1.5.5-cp311-cp311-win_amd64.whl", hash = "sha256:83509f9324011c9a39faaef0922c6f720f9623afe3fe220b6d0b15638247206b"}, - {file = "typed_ast-1.5.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:44f214394fc1af23ca6d4e9e744804d890045d1643dd7e8229951e0ef39429b5"}, - {file = "typed_ast-1.5.5-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:118c1ce46ce58fda78503eae14b7664163aa735b620b64b5b725453696f2a35c"}, - {file = "typed_ast-1.5.5-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be4919b808efa61101456e87f2d4c75b228f4e52618621c77f1ddcaae15904fa"}, - {file = "typed_ast-1.5.5-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:fc2b8c4e1bc5cd96c1a823a885e6b158f8451cf6f5530e1829390b4d27d0807f"}, - {file = "typed_ast-1.5.5-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:16f7313e0a08c7de57f2998c85e2a69a642e97cb32f87eb65fbfe88381a5e44d"}, - {file = "typed_ast-1.5.5-cp36-cp36m-win_amd64.whl", hash = "sha256:2b946ef8c04f77230489f75b4b5a4a6f24c078be4aed241cfabe9cbf4156e7e5"}, - {file = "typed_ast-1.5.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2188bc33d85951ea4ddad55d2b35598b2709d122c11c75cffd529fbc9965508e"}, - {file = "typed_ast-1.5.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0635900d16ae133cab3b26c607586131269f88266954eb04ec31535c9a12ef1e"}, - {file = "typed_ast-1.5.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:57bfc3cf35a0f2fdf0a88a3044aafaec1d2f24d8ae8cd87c4f58d615fb5b6311"}, - {file = "typed_ast-1.5.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:fe58ef6a764de7b4b36edfc8592641f56e69b7163bba9f9c8089838ee596bfb2"}, - {file = "typed_ast-1.5.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d09d930c2d1d621f717bb217bf1fe2584616febb5138d9b3e8cdd26506c3f6d4"}, - {file = "typed_ast-1.5.5-cp37-cp37m-win_amd64.whl", hash = "sha256:d40c10326893ecab8a80a53039164a224984339b2c32a6baf55ecbd5b1df6431"}, - {file = "typed_ast-1.5.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:fd946abf3c31fb50eee07451a6aedbfff912fcd13cf357363f5b4e834cc5e71a"}, - {file = "typed_ast-1.5.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ed4a1a42df8a3dfb6b40c3d2de109e935949f2f66b19703eafade03173f8f437"}, - {file = "typed_ast-1.5.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:045f9930a1550d9352464e5149710d56a2aed23a2ffe78946478f7b5416f1ede"}, - {file = "typed_ast-1.5.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:381eed9c95484ceef5ced626355fdc0765ab51d8553fec08661dce654a935db4"}, - {file = "typed_ast-1.5.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:bfd39a41c0ef6f31684daff53befddae608f9daf6957140228a08e51f312d7e6"}, - {file = "typed_ast-1.5.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8c524eb3024edcc04e288db9541fe1f438f82d281e591c548903d5b77ad1ddd4"}, - {file = "typed_ast-1.5.5-cp38-cp38-win_amd64.whl", hash = "sha256:7f58fabdde8dcbe764cef5e1a7fcb440f2463c1bbbec1cf2a86ca7bc1f95184b"}, - {file = "typed_ast-1.5.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:042eb665ff6bf020dd2243307d11ed626306b82812aba21836096d229fdc6a10"}, - {file = "typed_ast-1.5.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:622e4a006472b05cf6ef7f9f2636edc51bda670b7bbffa18d26b255269d3d814"}, - {file = "typed_ast-1.5.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1efebbbf4604ad1283e963e8915daa240cb4bf5067053cf2f0baadc4d4fb51b8"}, - {file = "typed_ast-1.5.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0aefdd66f1784c58f65b502b6cf8b121544680456d1cebbd300c2c813899274"}, - {file = "typed_ast-1.5.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:48074261a842acf825af1968cd912f6f21357316080ebaca5f19abbb11690c8a"}, - {file = "typed_ast-1.5.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:429ae404f69dc94b9361bb62291885894b7c6fb4640d561179548c849f8492ba"}, - {file = "typed_ast-1.5.5-cp39-cp39-win_amd64.whl", hash = "sha256:335f22ccb244da2b5c296e6f96b06ee9bed46526db0de38d2f0e5a6597b81155"}, - {file = "typed_ast-1.5.5.tar.gz", hash = "sha256:94282f7a354f36ef5dbce0ef3467ebf6a258e370ab33d5b40c249fa996e590dd"}, + {file = "tomli-2.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:88bd15eb972f3664f5ed4b57c1634a97153b4bac4479dcb6a495f41921eb7f45"}, + {file = "tomli-2.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:883b1c0d6398a6a9d29b508c331fa56adbcdff647f6ace4dfca0f50e90dfd0ba"}, + {file = "tomli-2.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d1381caf13ab9f300e30dd8feadb3de072aeb86f1d34a8569453ff32a7dea4bf"}, + {file = "tomli-2.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a0e285d2649b78c0d9027570d4da3425bdb49830a6156121360b3f8511ea3441"}, + {file = "tomli-2.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a154a9ae14bfcf5d8917a59b51ffd5a3ac1fd149b71b47a3a104ca4edcfa845"}, + {file = "tomli-2.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:74bf8464ff93e413514fefd2be591c3b0b23231a77f901db1eb30d6f712fc42c"}, + {file = "tomli-2.3.0-cp311-cp311-win32.whl", hash = "sha256:00b5f5d95bbfc7d12f91ad8c593a1659b6387b43f054104cda404be6bda62456"}, + {file = "tomli-2.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:4dc4ce8483a5d429ab602f111a93a6ab1ed425eae3122032db7e9acf449451be"}, + {file = "tomli-2.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d7d86942e56ded512a594786a5ba0a5e521d02529b3826e7761a05138341a2ac"}, + {file = "tomli-2.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:73ee0b47d4dad1c5e996e3cd33b8a76a50167ae5f96a2607cbe8cc773506ab22"}, + {file = "tomli-2.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:792262b94d5d0a466afb5bc63c7daa9d75520110971ee269152083270998316f"}, + {file = "tomli-2.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4f195fe57ecceac95a66a75ac24d9d5fbc98ef0962e09b2eddec5d39375aae52"}, + {file = "tomli-2.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e31d432427dcbf4d86958c184b9bfd1e96b5b71f8eb17e6d02531f434fd335b8"}, + {file = "tomli-2.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7b0882799624980785240ab732537fcfc372601015c00f7fc367c55308c186f6"}, + {file = "tomli-2.3.0-cp312-cp312-win32.whl", hash = "sha256:ff72b71b5d10d22ecb084d345fc26f42b5143c5533db5e2eaba7d2d335358876"}, + {file = "tomli-2.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:1cb4ed918939151a03f33d4242ccd0aa5f11b3547d0cf30f7c74a408a5b99878"}, + {file = "tomli-2.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5192f562738228945d7b13d4930baffda67b69425a7f0da96d360b0a3888136b"}, + {file = "tomli-2.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:be71c93a63d738597996be9528f4abe628d1adf5e6eb11607bc8fe1a510b5dae"}, + {file = "tomli-2.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4665508bcbac83a31ff8ab08f424b665200c0e1e645d2bd9ab3d3e557b6185b"}, + {file = "tomli-2.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4021923f97266babc6ccab9f5068642a0095faa0a51a246a6a02fccbb3514eaf"}, + {file = "tomli-2.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4ea38c40145a357d513bffad0ed869f13c1773716cf71ccaa83b0fa0cc4e42f"}, + {file = "tomli-2.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ad805ea85eda330dbad64c7ea7a4556259665bdf9d2672f5dccc740eb9d3ca05"}, + {file = "tomli-2.3.0-cp313-cp313-win32.whl", hash = "sha256:97d5eec30149fd3294270e889b4234023f2c69747e555a27bd708828353ab606"}, + {file = "tomli-2.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0c95ca56fbe89e065c6ead5b593ee64b84a26fca063b5d71a1122bf26e533999"}, + {file = "tomli-2.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:cebc6fe843e0733ee827a282aca4999b596241195f43b4cc371d64fc6639da9e"}, + {file = "tomli-2.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4c2ef0244c75aba9355561272009d934953817c49f47d768070c3c94355c2aa3"}, + {file = "tomli-2.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c22a8bf253bacc0cf11f35ad9808b6cb75ada2631c2d97c971122583b129afbc"}, + {file = "tomli-2.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0eea8cc5c5e9f89c9b90c4896a8deefc74f518db5927d0e0e8d4a80953d774d0"}, + {file = "tomli-2.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b74a0e59ec5d15127acdabd75ea17726ac4c5178ae51b85bfe39c4f8a278e879"}, + {file = "tomli-2.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b5870b50c9db823c595983571d1296a6ff3e1b88f734a4c8f6fc6188397de005"}, + {file = "tomli-2.3.0-cp314-cp314-win32.whl", hash = "sha256:feb0dacc61170ed7ab602d3d972a58f14ee3ee60494292d384649a3dc38ef463"}, + {file = "tomli-2.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:b273fcbd7fc64dc3600c098e39136522650c49bca95df2d11cf3b626422392c8"}, + {file = "tomli-2.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:940d56ee0410fa17ee1f12b817b37a4d4e4dc4d27340863cc67236c74f582e77"}, + {file = "tomli-2.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f85209946d1fe94416debbb88d00eb92ce9cd5266775424ff81bc959e001acaf"}, + {file = "tomli-2.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a56212bdcce682e56b0aaf79e869ba5d15a6163f88d5451cbde388d48b13f530"}, + {file = "tomli-2.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5f3ffd1e098dfc032d4d3af5c0ac64f6d286d98bc148698356847b80fa4de1b"}, + {file = "tomli-2.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5e01decd096b1530d97d5d85cb4dff4af2d8347bd35686654a004f8dea20fc67"}, + {file = "tomli-2.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8a35dd0e643bb2610f156cca8db95d213a90015c11fee76c946aa62b7ae7e02f"}, + {file = "tomli-2.3.0-cp314-cp314t-win32.whl", hash = "sha256:a1f7f282fe248311650081faafa5f4732bdbfef5d45fe3f2e702fbc6f2d496e0"}, + {file = "tomli-2.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:70a251f8d4ba2d9ac2542eecf008b3c8a9fc5c3f9f02c56a9d7952612be2fdba"}, + {file = "tomli-2.3.0-py3-none-any.whl", hash = "sha256:e95b1af3c5b07d9e643909b5abbec77cd9f1217e6d0bca72b0234736b9fb1f1b"}, + {file = "tomli-2.3.0.tar.gz", hash = "sha256:64be704a875d2a59753d80ee8a533c3fe183e3f06807ff7dc2232938ccb01549"}, ] [[package]] name = "typing-extensions" -version = "4.7.1" -description = "Backported and Experimental Type Hints for Python 3.7+" +version = "4.15.0" +description = "Backported and Experimental Type Hints for Python 3.9+" optional = false -python-versions = ">=3.7" -groups = ["main", "lint"] +python-versions = ">=3.9" files = [ - {file = "typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36"}, - {file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"}, + {file = "typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548"}, + {file = "typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466"}, ] -markers = {main = "python_version <= \"3.7\""} [metadata] -lock-version = "2.1" -python-versions = ">=3.7,<3.12" -content-hash = "f54cedbfd0b27f15d813ca6b58594d1314ab3d58b94de482ffd53cdd5d93e484" +lock-version = "2.0" +python-versions = ">=3.9,<3.13" +content-hash = "891f409ed71c5d6b163e6a5e41193f321f30f56269f668a54a7247ae5ac26333" diff --git a/examples/prepy310/example.py b/examples/prepy310/example.py index 29f4b69b..b1f86563 100644 --- a/examples/prepy310/example.py +++ b/examples/prepy310/example.py @@ -6,7 +6,7 @@ from example_utils.example_logging import initialize_logging -_AUTH_PROVIDER = CredentialProvider.from_environment_variable("MOMENTO_API_KEY") +_AUTH_PROVIDER = CredentialProvider.from_environment_variables_v2() _CACHE_NAME = "cache" _ITEM_DEFAULT_TTL_SECONDS = timedelta(seconds=60) _KEY = "MyKey" diff --git a/examples/prepy310/example_async.py b/examples/prepy310/example_async.py index dfca8c09..72e8b243 100644 --- a/examples/prepy310/example_async.py +++ b/examples/prepy310/example_async.py @@ -7,7 +7,7 @@ from example_utils.example_logging import initialize_logging -_AUTH_PROVIDER = CredentialProvider.from_environment_variable("MOMENTO_API_KEY") +_AUTH_PROVIDER = CredentialProvider.from_environment_variables_v2() _CACHE_NAME = "cache" _ITEM_DEFAULT_TTL_SECONDS = timedelta(seconds=60) _KEY = "MyKey" diff --git a/examples/prepy310/quickstart.py b/examples/prepy310/quickstart.py index 376e50d1..5c36f361 100644 --- a/examples/prepy310/quickstart.py +++ b/examples/prepy310/quickstart.py @@ -7,7 +7,7 @@ cache_name = "default-cache" with CacheClient.create( configuration=Configurations.Laptop.v1(), - credential_provider=CredentialProvider.from_environment_variable("MOMENTO_API_KEY"), + credential_provider=CredentialProvider.from_environment_variables_v2(), default_ttl=timedelta(seconds=60), ) as cache_client: create_cache_response = cache_client.create_cache(cache_name) diff --git a/examples/prepy310/readme.py b/examples/prepy310/readme.py index 16abcaa8..7267eed2 100644 --- a/examples/prepy310/readme.py +++ b/examples/prepy310/readme.py @@ -5,7 +5,7 @@ cache_client = CacheClient( configuration=Configurations.Laptop.v1(), - credential_provider=CredentialProvider.from_environment_variable("MOMENTO_API_KEY"), + credential_provider=CredentialProvider.from_environment_variables_v2(), default_ttl=timedelta(seconds=60), ) cache_client.create_cache("cache") diff --git a/examples/prepy310/topic_publish.py b/examples/prepy310/topic_publish.py index 65c3f481..f2a76f66 100644 --- a/examples/prepy310/topic_publish.py +++ b/examples/prepy310/topic_publish.py @@ -12,7 +12,7 @@ from example_utils.example_logging import initialize_logging -_AUTH_PROVIDER = CredentialProvider.from_environment_variable("MOMENTO_API_KEY") +_AUTH_PROVIDER = CredentialProvider.from_environment_variables_v2() _CACHE_NAME = "cache" _logger = logging.getLogger("topic-publish-example") @@ -28,7 +28,10 @@ def main() -> None: initialize_logging() setup_cache() _logger.info("hello") - with TopicClient(TopicConfigurations.Default.v1(), _AUTH_PROVIDER) as client: + # You may need to adjust the timeout to accommodate your network conditions, runtime, etc + with TopicClient( + TopicConfigurations.Default.v1().with_client_timeout(timedelta(seconds=10)), _AUTH_PROVIDER + ) as client: response = client.publish("cache", "my_topic", "my_value") if isinstance(response, TopicPublish.Error): print("error: ", response.message) diff --git a/examples/prepy310/topic_publish_async.py b/examples/prepy310/topic_publish_async.py index fed69486..cabc4014 100644 --- a/examples/prepy310/topic_publish_async.py +++ b/examples/prepy310/topic_publish_async.py @@ -13,7 +13,7 @@ from example_utils.example_logging import initialize_logging -_AUTH_PROVIDER = CredentialProvider.from_environment_variable("MOMENTO_API_KEY") +_AUTH_PROVIDER = CredentialProvider.from_environment_variables_v2() _CACHE_NAME = "cache" _logger = logging.getLogger("topic-publish-example") @@ -29,7 +29,10 @@ async def main() -> None: initialize_logging() setup_cache() _logger.info("hello") - async with TopicClientAsync(TopicConfigurations.Default.v1(), _AUTH_PROVIDER) as client: + # You may need to adjust the timeout to accommodate your network conditions, runtime, etc + async with TopicClientAsync( + TopicConfigurations.Default.v1().with_client_timeout(timedelta(seconds=10)), _AUTH_PROVIDER + ) as client: response = await client.publish("cache", "my_topic", "my_value") if isinstance(response, TopicPublish.Error): print("error: ", response.message) diff --git a/examples/prepy310/topic_subscribe.py b/examples/prepy310/topic_subscribe.py index 8039edf4..ca49ab11 100644 --- a/examples/prepy310/topic_subscribe.py +++ b/examples/prepy310/topic_subscribe.py @@ -12,7 +12,7 @@ from example_utils.example_logging import initialize_logging -_AUTH_PROVIDER = CredentialProvider.from_environment_variable("MOMENTO_API_KEY") +_AUTH_PROVIDER = CredentialProvider.from_environment_variables_v2() _CACHE_NAME = "cache" _logger = logging.getLogger("topic-subscribe-example") @@ -28,7 +28,10 @@ def main() -> None: initialize_logging() setup_cache() _logger.info("hello") - with TopicClient(TopicConfigurations.Default.v1(), _AUTH_PROVIDER) as client: + # You may need to adjust the timeout to accommodate your network conditions, runtime, etc + with TopicClient( + TopicConfigurations.Default.v1().with_client_timeout(timedelta(seconds=10)), _AUTH_PROVIDER + ) as client: subscription = client.subscribe("cache", "my_topic") if isinstance(subscription, TopicSubscribe.Error): raise Exception("got subscription error: ", subscription.message) diff --git a/examples/prepy310/topic_subscribe_async.py b/examples/prepy310/topic_subscribe_async.py index e9663750..86d2878b 100644 --- a/examples/prepy310/topic_subscribe_async.py +++ b/examples/prepy310/topic_subscribe_async.py @@ -14,7 +14,7 @@ from example_utils.example_logging import initialize_logging -_AUTH_PROVIDER = CredentialProvider.from_environment_variable("MOMENTO_API_KEY") +_AUTH_PROVIDER = CredentialProvider.from_environment_variables_v2() _CACHE_NAME = "cache" _NUM_SUBSCRIBERS = 10 _logger = logging.getLogger("topic-subscribe-example") @@ -31,8 +31,12 @@ async def main() -> None: initialize_logging() setup_cache() _logger.info("hello") + # You may need to adjust the timeout to accommodate your network conditions, runtime, etc async with TopicClientAsync( - TopicConfigurations.Default.v1().with_max_subscriptions(_NUM_SUBSCRIBERS), _AUTH_PROVIDER + TopicConfigurations.Default.v1() + .with_max_subscriptions(_NUM_SUBSCRIBERS) + .with_client_timeout(timedelta(seconds=10)), + _AUTH_PROVIDER, ) as client: subscriptions = [] for i in range(0, _NUM_SUBSCRIBERS): diff --git a/examples/py310/doc-examples-python-apis.py b/examples/py310/doc-examples-python-apis.py index 9291e041..856ac586 100644 --- a/examples/py310/doc-examples-python-apis.py +++ b/examples/py310/doc-examples-python-apis.py @@ -26,8 +26,42 @@ from momento.utilities import ExpiresIn +def retrieve_api_key_from_your_secrets_manager() -> str: + # this is not a valid API key but conforms to the syntax requirements. + return "eyJhcGlfa2V5IjogImV5SjBlWEFpT2lKS1YxUWlMQ0poYkdjaU9pSklVekkxTmlKOS5leUpwYzNNaU9pSlBibXhwYm1VZ1NsZFVJRUoxYVd4a1pYSWlMQ0pwWVhRaU9qRTJOemd6TURVNE1USXNJbVY0Y0NJNk5EZzJOVFV4TlRReE1pd2lZWFZrSWpvaUlpd2ljM1ZpSWpvaWFuSnZZMnRsZEVCbGVHRnRjR3hsTG1OdmJTSjkuOEl5OHE4NExzci1EM1lDb19IUDRkLXhqSGRUOFVDSXV2QVljeGhGTXl6OCIsICJlbmRwb2ludCI6ICJ0ZXN0Lm1vbWVudG9ocS5jb20ifQo=" + + +def retrieve_api_key_v2_from_your_secrets_manager() -> str: + # this is not a valid API key but conforms to the syntax requirements. + return "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJ0IjoiZyIsImp0aSI6InNvbWUtaWQifQ.GMr9nA6HE0ttB6llXct_2Sg5-fOKGFbJCdACZFgNbN1fhT6OPg_hVc8ThGzBrWC_RlsBpLA1nzqK3SOJDXYxAw" + + def example_API_CredentialProviderFromEnvVar(): - CredentialProvider.from_environment_variable("MOMENTO_API_KEY") + CredentialProvider.from_environment_variable("V1_API_KEY") + + +# end example + + +def example_API_CredentialProviderFromEnvVarV2(): + CredentialProvider.from_environment_variables_v2() + + +# end example + + +def example_API_CredentialProviderFromApiKeyV2(): + api_key = retrieve_api_key_v2_from_your_secrets_manager() + endpoint = "cell-4-us-west-2-1.prod.a.momentohq.com" + CredentialProvider.from_api_key_v2(api_key, endpoint) + + +# end example + + +def example_API_CredentialProviderFromDisposableToken(): + auth_token = retrieve_api_key_from_your_secrets_manager() + CredentialProvider.from_disposable_token(auth_token) # end example @@ -36,7 +70,7 @@ def example_API_CredentialProviderFromEnvVar(): async def example_API_InstantiateCacheClient(): await CacheClientAsync.create( Configurations.Laptop.latest(), - CredentialProvider.from_environment_variable("MOMENTO_API_KEY"), + CredentialProvider.from_environment_variables_v2(), timedelta(seconds=60), ) @@ -129,9 +163,7 @@ async def example_API_Delete(cache_client: CacheClientAsync): async def example_API_InstantiateTopicClient(): - TopicClientAsync( - TopicConfigurations.Default.latest(), CredentialProvider.from_environment_variable("MOMENTO_API_KEY") - ) + TopicClientAsync(TopicConfigurations.Default.latest(), CredentialProvider.from_environment_variables_v2()) # end example @@ -175,7 +207,7 @@ async def example_API_TopicPublish(topic_client: TopicClientAsync): async def example_API_InstantiateAuthClient(): AuthClientAsync( Configurations.Laptop.latest(), - CredentialProvider.from_environment_variable("MOMENTO_API_KEY"), + CredentialProvider.from_environment_variable("V1_API_KEY"), ) @@ -200,11 +232,14 @@ async def example_API_GenerateDisposableToken(auth_client: AuthClientAsync): async def main(): example_API_CredentialProviderFromEnvVar() + example_API_CredentialProviderFromEnvVarV2() + example_API_CredentialProviderFromApiKeyV2() + example_API_CredentialProviderFromDisposableToken() await example_API_InstantiateCacheClient() cache_client = await CacheClientAsync.create( Configurations.Laptop.latest(), - CredentialProvider.from_environment_variable("MOMENTO_API_KEY"), + CredentialProvider.from_environment_variables_v2(), timedelta(seconds=60), ) @@ -220,7 +255,7 @@ async def main(): await example_API_DeleteCache(cache_client) topic_client = TopicClientAsync( - TopicConfigurations.Default.latest(), CredentialProvider.from_environment_variable("MOMENTO_API_KEY") + TopicConfigurations.Default.latest(), CredentialProvider.from_environment_variables_v2() ) await example_API_InstantiateTopicClient() await example_API_TopicPublish(topic_client) @@ -229,11 +264,12 @@ async def main(): auth_client = AuthClientAsync( Configurations.Laptop.latest(), - CredentialProvider.from_environment_variable("MOMENTO_API_KEY"), + CredentialProvider.from_environment_variable("V1_API_KEY"), ) await example_API_InstantiateAuthClient() await example_API_GenerateDisposableToken(auth_client) await auth_client.close() + if __name__ == "__main__": asyncio.run(main()) diff --git a/examples/py310/example.py b/examples/py310/example.py index 73b57234..bc23ebc7 100644 --- a/examples/py310/example.py +++ b/examples/py310/example.py @@ -6,7 +6,7 @@ from example_utils.example_logging import initialize_logging -_AUTH_PROVIDER = CredentialProvider.from_environment_variable("MOMENTO_API_KEY") +_AUTH_PROVIDER = CredentialProvider.from_environment_variables_v2() _CACHE_NAME = "cache" _ITEM_DEFAULT_TTL_SECONDS = timedelta(seconds=60) _KEY = "MyKey" diff --git a/examples/py310/example_async.py b/examples/py310/example_async.py index 8d51964f..b59783e5 100644 --- a/examples/py310/example_async.py +++ b/examples/py310/example_async.py @@ -7,7 +7,7 @@ from example_utils.example_logging import initialize_logging -_AUTH_PROVIDER = CredentialProvider.from_environment_variable("MOMENTO_API_KEY") +_AUTH_PROVIDER = CredentialProvider.from_environment_variables_v2() _CACHE_NAME = "cache" _ITEM_DEFAULT_TTL_SECONDS = timedelta(seconds=60) _KEY = "MyKey" diff --git a/examples/py310/example_load_gen.py b/examples/py310/example_load_gen.py index 90e48912..d910adbf 100644 --- a/examples/py310/example_load_gen.py +++ b/examples/py310/example_load_gen.py @@ -74,7 +74,7 @@ class BasicPythonLoadGen: def __init__(self, options: BasicPythonLoadGenOptions): self.logger = logging.getLogger("load-gen") - self.auth_provider = CredentialProvider.from_environment_variable("MOMENTO_API_KEY") + self.auth_provider = CredentialProvider.from_environment_variables_v2() self.options = options self.cache_value = "x" * options.cache_item_payload_bytes self.request_interval_ms = options.number_of_concurrent_requests / options.max_requests_per_second * 1000 diff --git a/examples/py310/order_system.py b/examples/py310/order_system.py index a9ea8ee0..53d4c9e9 100644 --- a/examples/py310/order_system.py +++ b/examples/py310/order_system.py @@ -43,7 +43,7 @@ from example_utils.example_logging import initialize_logging -_AUTH_PROVIDER = CredentialProvider.from_environment_variable("MOMENTO_API_KEY") +_AUTH_PROVIDER = CredentialProvider.from_environment_variables_v2() _logger = logging.getLogger("order-system-example") # Constants @@ -218,7 +218,7 @@ async def main() -> None: initialize_logging() async with TopicClientAsync( - TopicConfigurations.Default.latest(), _AUTH_PROVIDER + TopicConfigurations.Default.latest().with_client_timeout(timedelta(seconds=10)), _AUTH_PROVIDER ) as topic_client, CacheWithPublishClientAsync( Configurations.Laptop.latest(), _AUTH_PROVIDER, timedelta(seconds=60), topic_client ) as cache_with_publish_client: diff --git a/examples/py310/patterns.py b/examples/py310/patterns.py index 508d94f2..13bf656e 100644 --- a/examples/py310/patterns.py +++ b/examples/py310/patterns.py @@ -8,16 +8,27 @@ ) from momento.responses import ( CacheGet, - CacheSet, ) -database: dict[str, str] = {} -database["test-key"] = "test-value" + +class Database: + def __init__(self): + self.db: dict[str, str] = {} + + def get(self, key: str) -> str | None: + return self.db.get(key) + + def set(self, key: str, value: str) -> None: + self.db[key] = value + + +database = Database() +database.set("test-key", "test-value") async def example_patterns_WriteThroughCaching(cache_client: CacheClientAsync): database.set("test-key", "test-value") - set_response = await cache_client.set("test-cache", "test-key", "test-value") + await cache_client.set("test-cache", "test-key", "test-value") return @@ -40,12 +51,9 @@ async def example_patterns_ReadAsideCaching(cache_client: CacheClientAsync): async def main(): - example_API_CredentialProviderFromEnvVar() - - await example_API_InstantiateCacheClient() cache_client = await CacheClientAsync.create( Configurations.Laptop.latest(), - CredentialProvider.from_environment_variable("MOMENTO_API_KEY"), + CredentialProvider.from_environment_variables_v2(), timedelta(seconds=60), ) diff --git a/examples/py310/quickstart.py b/examples/py310/quickstart.py index a6647009..d105d21c 100644 --- a/examples/py310/quickstart.py +++ b/examples/py310/quickstart.py @@ -7,7 +7,7 @@ cache_name = "default-cache" with CacheClient.create( configuration=Configurations.Laptop.v1(), - credential_provider=CredentialProvider.from_environment_variable("MOMENTO_API_KEY"), + credential_provider=CredentialProvider.from_environment_variables_v2(), default_ttl=timedelta(seconds=60), ) as cache_client: create_cache_response = cache_client.create_cache(cache_name) diff --git a/examples/py310/readme.py b/examples/py310/readme.py index 0e96a2e9..2331e9b2 100644 --- a/examples/py310/readme.py +++ b/examples/py310/readme.py @@ -4,7 +4,7 @@ from momento.responses import CacheGet cache_client = CacheClient( - Configurations.Laptop.v1(), CredentialProvider.from_environment_variable("MOMENTO_API_KEY"), timedelta(seconds=60) + Configurations.Laptop.v1(), CredentialProvider.from_environment_variables_v2(), timedelta(seconds=60) ) cache_client.create_cache("cache") diff --git a/examples/py310/topic_publish.py b/examples/py310/topic_publish.py index 691a8720..f798c2ea 100644 --- a/examples/py310/topic_publish.py +++ b/examples/py310/topic_publish.py @@ -12,7 +12,7 @@ from example_utils.example_logging import initialize_logging -_AUTH_PROVIDER = CredentialProvider.from_environment_variable("MOMENTO_API_KEY") +_AUTH_PROVIDER = CredentialProvider.from_environment_variables_v2() _CACHE_NAME = "cache" _logger = logging.getLogger("topic-publish-example") @@ -29,7 +29,10 @@ def main() -> None: initialize_logging() setup_cache() _logger.info("hello") - with TopicClient(TopicConfigurations.Default.v1(), _AUTH_PROVIDER) as client: + # You may need to adjust the timeout to accommodate your network conditions, runtime, etc + with TopicClient( + TopicConfigurations.Default.v1().with_client_timeout(timedelta(seconds=10)), _AUTH_PROVIDER + ) as client: response = client.publish("cache", "my_topic", "my_value") match response: case TopicPublish.Error(): diff --git a/examples/py310/topic_publish_async.py b/examples/py310/topic_publish_async.py index 84b84da1..c90659fc 100644 --- a/examples/py310/topic_publish_async.py +++ b/examples/py310/topic_publish_async.py @@ -13,7 +13,7 @@ from example_utils.example_logging import initialize_logging -_AUTH_PROVIDER = CredentialProvider.from_environment_variable("MOMENTO_API_KEY") +_AUTH_PROVIDER = CredentialProvider.from_environment_variables_v2() _CACHE_NAME = "cache" _logger = logging.getLogger("topic-publish-example") @@ -30,7 +30,10 @@ async def main() -> None: initialize_logging() setup_cache() _logger.info("hello") - async with TopicClientAsync(TopicConfigurations.Default.v1(), _AUTH_PROVIDER) as client: + # You may need to adjust the timeout to accommodate your network conditions, runtime, etc + async with TopicClientAsync( + TopicConfigurations.Default.v1().with_client_timeout(timedelta(seconds=10)), _AUTH_PROVIDER + ) as client: response = await client.publish("cache", "my_topic", "my_value") match response: case TopicPublish.Error(): diff --git a/examples/py310/topic_subscribe.py b/examples/py310/topic_subscribe.py index 160f924a..51b9bb47 100644 --- a/examples/py310/topic_subscribe.py +++ b/examples/py310/topic_subscribe.py @@ -12,7 +12,7 @@ from example_utils.example_logging import initialize_logging -_AUTH_PROVIDER = CredentialProvider.from_environment_variable("MOMENTO_API_KEY") +_AUTH_PROVIDER = CredentialProvider.from_environment_variables_v2() _CACHE_NAME = "cache" _logger = logging.getLogger("topic-subscribe-example") @@ -29,7 +29,10 @@ def main() -> None: initialize_logging() setup_cache() _logger.info("hello") - with TopicClient(TopicConfigurations.Default.v1(), _AUTH_PROVIDER) as client: + # You may need to adjust the timeout to accommodate your network conditions, runtime, etc + with TopicClient( + TopicConfigurations.Default.v1().with_client_timeout(timedelta(seconds=10)), _AUTH_PROVIDER + ) as client: subscription = client.subscribe("cache", "my_topic") match subscription: case TopicSubscribe.Error(): diff --git a/examples/py310/topic_subscribe_async.py b/examples/py310/topic_subscribe_async.py index f19c7643..9e9c6065 100644 --- a/examples/py310/topic_subscribe_async.py +++ b/examples/py310/topic_subscribe_async.py @@ -14,7 +14,7 @@ from example_utils.example_logging import initialize_logging -_AUTH_PROVIDER = CredentialProvider.from_environment_variable("MOMENTO_API_KEY") +_AUTH_PROVIDER = CredentialProvider.from_environment_variables_v2() _CACHE_NAME = "cache" _NUM_SUBSCRIBERS = 10 _logger = logging.getLogger("topic-subscribe-example") @@ -32,8 +32,12 @@ async def main() -> None: initialize_logging() setup_cache() _logger.info("hello") + # You may need to adjust the timeout to accommodate your network conditions, runtime, etc async with TopicClientAsync( - TopicConfigurations.Default.v1().with_max_subscriptions(_NUM_SUBSCRIBERS), _AUTH_PROVIDER + TopicConfigurations.Default.v1() + .with_max_subscriptions(_NUM_SUBSCRIBERS) + .with_client_timeout(timedelta(seconds=10)), + _AUTH_PROVIDER, ) as client: tasks = [] for i in range(0, _NUM_SUBSCRIBERS): diff --git a/examples/pyproject.toml b/examples/pyproject.toml index a5f7c03a..509b21f2 100644 --- a/examples/pyproject.toml +++ b/examples/pyproject.toml @@ -6,11 +6,12 @@ authors = ["Momento "] license = "Apache-2.0" [tool.poetry.dependencies] -python = ">=3.7,<3.13" +python = ">=3.9,<3.13" -momento = "1.27.0" +momento = "1.28.0" colorlog = "6.7.0" hdrhistogram = "^0.10.1" +setuptools = "^78.1.1" [tool.poetry.group.lint.dependencies] mypy = "^0.971" diff --git a/tests/conftest.py b/tests/conftest.py index 55c9a3d1..49108145 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -58,8 +58,10 @@ TEST_TOPIC_CONFIGURATION = TopicConfigurations.Default.latest().with_client_timeout(timedelta(seconds=10)) TEST_AUTH_CONFIGURATION = AuthConfigurations.Laptop.latest() +TEST_AUTH_PROVIDER = CredentialProvider.from_environment_variable("V1_API_KEY") -TEST_AUTH_PROVIDER = CredentialProvider.from_environment_variable("TEST_API_KEY") +# Looks for env vars MOMENTO_API_KEY and MOMENTO_ENDPOINT +TEST_AUTH_PROVIDER_V2 = CredentialProvider.from_environment_variables_v2() MOMENTO_LOCAL_HOSTNAME = os.environ.get("MOMENTO_HOSTNAME", "127.0.0.1") MOMENTO_LOCAL_PORT = int(os.environ.get("MOMENTO_PORT", "8080")) @@ -88,6 +90,11 @@ def credential_provider() -> CredentialProvider: return TEST_AUTH_PROVIDER +@pytest.fixture(scope="session") +def credential_provider_v2() -> CredentialProvider: + return TEST_AUTH_PROVIDER_V2 + + @pytest.fixture(scope="session") def bad_token_credential_provider() -> CredentialProvider: os.environ["BAD_API_KEY"] = BAD_API_KEY @@ -361,6 +368,45 @@ async def auth_client_async() -> AsyncIterator[AuthClientAsync]: yield _auth_client +@pytest.fixture(scope="session") +def client_v2() -> Iterator[CacheClient]: + with CacheClient(TEST_CONFIGURATION, TEST_AUTH_PROVIDER_V2, DEFAULT_TTL_SECONDS) as _client: + # Ensure test caches exists + _client.create_cache(cast(str, TEST_CACHE_NAME)) + _client.create_cache(ALTERNATE_CACHE_NAME) + try: + yield _client + finally: + _client.delete_cache(cast(str, TEST_CACHE_NAME)) + _client.delete_cache(ALTERNATE_CACHE_NAME) + + +@pytest_asyncio.fixture(scope="session") +async def client_async_v2() -> AsyncIterator[CacheClientAsync]: + async with CacheClientAsync(TEST_CONFIGURATION, TEST_AUTH_PROVIDER_V2, DEFAULT_TTL_SECONDS) as _client: + # Ensure test cache exists + # TODO consider deleting cache on when test runner shuts down + await _client.create_cache(cast(str, TEST_CACHE_NAME)) + await _client.create_cache(ALTERNATE_CACHE_NAME) + try: + yield _client + finally: + await _client.delete_cache(cast(str, TEST_CACHE_NAME)) + await _client.delete_cache(ALTERNATE_CACHE_NAME) + + +@pytest.fixture(scope="session") +def topic_client_v2() -> Iterator[TopicClient]: + with TopicClient(TEST_TOPIC_CONFIGURATION, TEST_AUTH_PROVIDER_V2) as _client: + yield _client + + +@pytest.fixture(scope="session") +async def topic_client_async_v2() -> AsyncIterator[TopicClientAsync]: + async with TopicClientAsync(TEST_TOPIC_CONFIGURATION, TEST_AUTH_PROVIDER_V2) as _topic_client: + yield _topic_client + + @asynccontextmanager async def client_async_local( cache_name: str, diff --git a/tests/momento/cache_client/test_cache_api_key_v2.py b/tests/momento/cache_client/test_cache_api_key_v2.py new file mode 100644 index 00000000..254d4241 --- /dev/null +++ b/tests/momento/cache_client/test_cache_api_key_v2.py @@ -0,0 +1,387 @@ +from momento import CacheClient +from momento.errors import MomentoErrorCode +from momento.requests.sort_order import SortOrder +from momento.responses import ( + CacheFlush, + CacheGet, + CacheSet, + CreateCache, + DeleteCache, + ListCaches, +) +from momento.responses.data.dictionary.fetch import CacheDictionaryFetch +from momento.responses.data.dictionary.get_fields import CacheDictionaryGetFields +from momento.responses.data.dictionary.increment import CacheDictionaryIncrement +from momento.responses.data.dictionary.remove_fields import CacheDictionaryRemoveFields +from momento.responses.data.dictionary.set_fields import CacheDictionarySetFields +from momento.responses.data.list.concatenate_back import CacheListConcatenateBack +from momento.responses.data.list.concatenate_front import CacheListConcatenateFront +from momento.responses.data.list.fetch import CacheListFetch +from momento.responses.data.list.length import CacheListLength +from momento.responses.data.list.pop_back import CacheListPopBack +from momento.responses.data.list.pop_front import CacheListPopFront +from momento.responses.data.list.push_back import CacheListPushBack +from momento.responses.data.list.push_front import CacheListPushFront +from momento.responses.data.list.remove_value import CacheListRemoveValue +from momento.responses.data.scalar.delete import CacheDelete +from momento.responses.data.scalar.increment import CacheIncrement +from momento.responses.data.set.add_elements import CacheSetAddElements +from momento.responses.data.set.fetch import CacheSetFetch +from momento.responses.data.set.remove_element import CacheSetRemoveElement +from momento.responses.data.sorted_set.fetch import CacheSortedSetFetch +from momento.responses.data.sorted_set.get_score import CacheSortedSetGetScore +from momento.responses.data.sorted_set.increment_score import CacheSortedSetIncrementScore +from momento.responses.data.sorted_set.put_elements import CacheSortedSetPutElements +from momento.responses.data.sorted_set.remove_element import CacheSortedSetRemoveElement + +from tests.conftest import TUniqueCacheName +from tests.utils import uuid_str + +# Control plane + + +def test_create_and_delete_cache_succeeds(client_v2: CacheClient, cache_name: str) -> None: + cache_name = uuid_str() + + response = client_v2.create_cache(cache_name) + assert isinstance(response, CreateCache.Success) + + delete_response = client_v2.delete_cache(cache_name) + assert isinstance(delete_response, DeleteCache.Success) + + delete_response = client_v2.delete_cache(cache_name) + assert isinstance(delete_response, DeleteCache.Error) + assert delete_response.error_code == MomentoErrorCode.NOT_FOUND_ERROR + + +def test_flush_cache_succeeds(client_v2: CacheClient, unique_cache_name: TUniqueCacheName) -> None: + cache_name = unique_cache_name(client_v2) + + create_cache_rsp = client_v2.create_cache(cache_name) + assert isinstance(create_cache_rsp, CreateCache.Success) + + # set test key + rsp = client_v2.set(cache_name, "test-key", "test-value") + assert isinstance(rsp, CacheSet.Success) + + # flush it + flush_response = client_v2.flush_cache(cache_name) + assert isinstance(flush_response, CacheFlush.Success) + + # make sure key is gone + get_rsp = client_v2.get(cache_name, "test-key") + assert isinstance(get_rsp, CacheGet.Miss) + + +def test_list_caches_succeeds(client_v2: CacheClient, cache_name: str) -> None: + cache_name = uuid_str() + + initial_response = client_v2.list_caches() + assert isinstance(initial_response, ListCaches.Success) + + cache_names = [cache.name for cache in initial_response.caches] + assert cache_name not in cache_names + + try: + response = client_v2.create_cache(cache_name) + assert isinstance(response, CreateCache.Success) + + list_cache_resp = client_v2.list_caches() + assert isinstance(list_cache_resp, ListCaches.Success) + + cache_names = [cache.name for cache in list_cache_resp.caches] + assert cache_name in cache_names + finally: + delete_response = client_v2.delete_cache(cache_name) + assert isinstance(delete_response, DeleteCache.Success) + + +# Scalar methods + + +def test_create_get_set_delete_succeeds( + client_v2: CacheClient, + cache_name: str, +) -> None: + key = uuid_str() + value = uuid_str() + + set_resp = client_v2.set(cache_name, key, value) + assert isinstance(set_resp, CacheSet.Success) + + get_resp = client_v2.get(cache_name, key) + assert isinstance(get_resp, CacheGet.Hit) + assert get_resp.value_string == value + + delete_resp = client_v2.delete(cache_name, key) + assert isinstance(delete_resp, CacheDelete.Success) + + get_after_delete_resp = client_v2.get(cache_name, key) + assert isinstance(get_after_delete_resp, CacheGet.Miss) + + +def test_increment_succeeds( + client_v2: CacheClient, + cache_name: str, +) -> None: + key = uuid_str() + + inc_resp1 = client_v2.increment(cache_name, key) + assert isinstance(inc_resp1, CacheIncrement.Success) + assert inc_resp1.value == 1 + + inc_resp2 = client_v2.increment(cache_name, key) + assert isinstance(inc_resp2, CacheIncrement.Success) + assert inc_resp2.value == 2 + + +# Dictionary + + +def test_dictionary_set_get_remove_fields( + client_v2: CacheClient, + cache_name: str, +) -> None: + key = uuid_str() + field1 = "field1" + field2 = "field2" + value1 = "value1" + value2 = "value2" + + dict_set_resp = client_v2.dictionary_set_fields( + cache_name, + key, + {field1: value1, field2: value2}, + ) + assert isinstance(dict_set_resp, CacheDictionarySetFields.Success) + + dict_get_resp = client_v2.dictionary_get_fields( + cache_name, + key, + [field1, field2], + ) + assert isinstance(dict_get_resp, CacheDictionaryGetFields.Hit) + assert dict_get_resp.value_dictionary_string_string == {field1: value1, field2: value2} + + dict_remove_resp = client_v2.dictionary_remove_fields( + cache_name, + key, + [field1], + ) + assert isinstance(dict_remove_resp, CacheDictionaryRemoveFields.Success) + + dict_get_after_remove_resp = client_v2.dictionary_get_fields( + cache_name, + key, + [field1, field2], + ) + assert isinstance(dict_get_after_remove_resp, CacheDictionaryGetFields.Hit) + assert dict_get_after_remove_resp.value_dictionary_string_string == {field2: value2} + + +def test_dictionary_increment_and_fetch( + client_v2: CacheClient, + cache_name: str, +) -> None: + key = uuid_str() + field = "counter" + + dict_inc_resp1 = client_v2.dictionary_increment(cache_name, key, field) + assert isinstance(dict_inc_resp1, CacheDictionaryIncrement.Success) + assert dict_inc_resp1.value == 1 + + dict_inc_resp2 = client_v2.dictionary_increment(cache_name, key, field) + assert isinstance(dict_inc_resp2, CacheDictionaryIncrement.Success) + assert dict_inc_resp2.value == 2 + + dict_fetch_resp = client_v2.dictionary_fetch(cache_name, key) + assert isinstance(dict_fetch_resp, CacheDictionaryFetch.Hit) + assert dict_fetch_resp.value_dictionary_string_string == {field: "2"} + + +# List + + +def test_list_concatenate_and_length( + client_v2: CacheClient, + cache_name: str, +) -> None: + list_name = uuid_str() + + # Concatenate first batch + concat_resp1 = client_v2.list_concatenate_back(cache_name, list_name, ["a", "b", "c"]) + assert isinstance(concat_resp1, CacheListConcatenateBack.Success) + + # Check length + length_resp1 = client_v2.list_length(cache_name, list_name) + assert isinstance(length_resp1, CacheListLength.Hit) + assert length_resp1.length == 3 + + # Concatenate second batch + concat_resp2 = client_v2.list_concatenate_front(cache_name, list_name, ["d", "e"]) + assert isinstance(concat_resp2, CacheListConcatenateFront.Success) + + # Check length again + length_resp2 = client_v2.list_length(cache_name, list_name) + assert isinstance(length_resp2, CacheListLength.Hit) + assert length_resp2.length == 5 + + +def test_list_push_and_pop( + client_v2: CacheClient, + cache_name: str, +) -> None: + list_name = uuid_str() + + # Push to back + push_back_resp = client_v2.list_push_back(cache_name, list_name, "x") + assert isinstance(push_back_resp, CacheListPushBack.Success) + + length_resp = client_v2.list_length(cache_name, list_name) + assert isinstance(length_resp, CacheListLength.Hit) + assert length_resp.length == 1 + + # Push to front + push_front_resp = client_v2.list_push_front(cache_name, list_name, "y") + assert isinstance(push_front_resp, CacheListPushFront.Success) + + length_resp = client_v2.list_length(cache_name, list_name) + assert isinstance(length_resp, CacheListLength.Hit) + assert length_resp.length == 2 + + # Pop from back + pop_back_resp = client_v2.list_pop_back(cache_name, list_name) + assert isinstance(pop_back_resp, CacheListPopBack.Hit) + assert pop_back_resp.value_string == "x" + + # Pop from front + pop_front_resp = client_v2.list_pop_front(cache_name, list_name) + assert isinstance(pop_front_resp, CacheListPopFront.Hit) + assert pop_front_resp.value_string == "y" + + +def test_list_fetch_and_remove_value( + client_v2: CacheClient, + cache_name: str, +) -> None: + list_name = uuid_str() + + # Populate list + populate_resp = client_v2.list_concatenate_back(cache_name, list_name, ["a", "b", "c", "b", "d"]) + assert isinstance(populate_resp, CacheListConcatenateBack.Success) + + # Fetch list + fetch_resp = client_v2.list_fetch(cache_name, list_name) + assert isinstance(fetch_resp, CacheListFetch.Hit) + assert fetch_resp.value_list_string == ["a", "b", "c", "b", "d"] + + # Remove value 'b' + remove_resp = client_v2.list_remove_value(cache_name, list_name, "b") + assert isinstance(remove_resp, CacheListRemoveValue.Success) + + # Fetch list again + fetch_resp_2 = client_v2.list_fetch(cache_name, list_name) + assert isinstance(fetch_resp_2, CacheListFetch.Hit) + assert fetch_resp_2.value_list_string == ["a", "c", "d"] + + +# Set + + +def test_set_add_fetch_remove( + client_v2: CacheClient, + cache_name: str, +) -> None: + set_name = uuid_str() + + # Add elements + add_resp = client_v2.set_add_elements(cache_name, set_name, {"one", "two", "three"}) + assert isinstance(add_resp, CacheSetAddElements.Success) + + # Fetch set + fetch_resp = client_v2.set_fetch(cache_name, set_name) + assert isinstance(fetch_resp, CacheSetFetch.Hit) + assert fetch_resp.value_set_string == {"one", "two", "three"} + + # Remove an element + remove_resp = client_v2.set_remove_element(cache_name, set_name, "two") + assert isinstance(remove_resp, CacheSetRemoveElement.Success) + + # Fetch set again + fetch_resp_2 = client_v2.set_fetch(cache_name, set_name) + assert isinstance(fetch_resp_2, CacheSetFetch.Hit) + assert fetch_resp_2.value_set_string == {"one", "three"} + + +# Sorted Set + + +def test_sorted_set_put_fetch_remove(client_v2: CacheClient, cache_name: str) -> None: + sorted_set_name = uuid_str() + + # Put elements + scores = {"a": 10.0, "b": 20.0, "c": 30.0} + resp = client_v2.sorted_set_put_elements(cache_name, sorted_set_name, scores) + assert isinstance(resp, CacheSortedSetPutElements.Success) + + # Fetch elements + fetch_resp = client_v2.sorted_set_fetch_by_score(cache_name, sorted_set_name) + assert isinstance(fetch_resp, CacheSortedSetFetch.Hit) + assert fetch_resp.value_list_string == list(scores.items()) + + # Remove an element + remove_resp = client_v2.sorted_set_remove_element(cache_name, sorted_set_name, "b") + assert isinstance(remove_resp, CacheSortedSetRemoveElement.Success) + + # Fetch elements again + fetch_resp_2 = client_v2.sorted_set_fetch_by_score(cache_name, sorted_set_name) + assert isinstance(fetch_resp_2, CacheSortedSetFetch.Hit) + assert fetch_resp_2.value_list_string == [("a", 10.0), ("c", 30.0)] + + +def test_sorted_set_increment_and_get( + client_v2: CacheClient, + cache_name: str, +) -> None: + sorted_set_name = uuid_str() + member = "counter" + + # Increment member + inc_resp1 = client_v2.sorted_set_increment_score(cache_name, sorted_set_name, member, 5.0) + assert isinstance(inc_resp1, CacheSortedSetIncrementScore.Success) + assert inc_resp1.score == 5.0 + + inc_resp2 = client_v2.sorted_set_increment_score(cache_name, sorted_set_name, member, 3.0) + assert isinstance(inc_resp2, CacheSortedSetIncrementScore.Success) + assert inc_resp2.score == 8.0 + + # Get member score + get_resp = client_v2.sorted_set_get_score(cache_name, sorted_set_name, member) + assert isinstance(get_resp, CacheSortedSetGetScore.Hit) + assert get_resp.score == 8.0 + + +def test_sorted_set_fetch_by_score_and_rank( + client_v2: CacheClient, + cache_name: str, +) -> None: + sorted_set_name = uuid_str() + + # Put elements + scores = {"a": 10.0, "b": 20.0, "c": 30.0, "d": 40.0, "e": 50.0} + resp = client_v2.sorted_set_put_elements(cache_name, sorted_set_name, scores) + assert isinstance(resp, CacheSortedSetPutElements.Success) + + # Fetch by rank descending + fetch_by_rank_resp = client_v2.sorted_set_fetch_by_rank( + cache_name, sorted_set_name, start_rank=0, end_rank=2, sort_order=SortOrder.DESCENDING + ) + assert isinstance(fetch_by_rank_resp, CacheSortedSetFetch.Hit) + assert fetch_by_rank_resp.value_list_string == [("e", 50.0), ("d", 40.0)] + + # Fetch by score with all options + fetch_by_score_resp = client_v2.sorted_set_fetch_by_score( + cache_name, sorted_set_name, min_score=15.0, max_score=50.0, sort_order=SortOrder.ASCENDING, offset=1, count=2 + ) + assert isinstance(fetch_by_score_resp, CacheSortedSetFetch.Hit) + assert fetch_by_score_resp.value_list_string == [("c", 30.0), ("d", 40.0)] diff --git a/tests/momento/cache_client/test_cache_api_key_v2_async.py b/tests/momento/cache_client/test_cache_api_key_v2_async.py new file mode 100644 index 00000000..bf8afd45 --- /dev/null +++ b/tests/momento/cache_client/test_cache_api_key_v2_async.py @@ -0,0 +1,389 @@ +from momento import CacheClientAsync +from momento.errors import MomentoErrorCode +from momento.requests.sort_order import SortOrder +from momento.responses import ( + CacheFlush, + CacheGet, + CacheSet, + CreateCache, + DeleteCache, + ListCaches, +) +from momento.responses.data.dictionary.fetch import CacheDictionaryFetch +from momento.responses.data.dictionary.get_fields import CacheDictionaryGetFields +from momento.responses.data.dictionary.increment import CacheDictionaryIncrement +from momento.responses.data.dictionary.remove_fields import CacheDictionaryRemoveFields +from momento.responses.data.dictionary.set_fields import CacheDictionarySetFields +from momento.responses.data.list.concatenate_back import CacheListConcatenateBack +from momento.responses.data.list.concatenate_front import CacheListConcatenateFront +from momento.responses.data.list.fetch import CacheListFetch +from momento.responses.data.list.length import CacheListLength +from momento.responses.data.list.pop_back import CacheListPopBack +from momento.responses.data.list.pop_front import CacheListPopFront +from momento.responses.data.list.push_back import CacheListPushBack +from momento.responses.data.list.push_front import CacheListPushFront +from momento.responses.data.list.remove_value import CacheListRemoveValue +from momento.responses.data.scalar.delete import CacheDelete +from momento.responses.data.scalar.increment import CacheIncrement +from momento.responses.data.set.add_elements import CacheSetAddElements +from momento.responses.data.set.fetch import CacheSetFetch +from momento.responses.data.set.remove_element import CacheSetRemoveElement +from momento.responses.data.sorted_set.fetch import CacheSortedSetFetch +from momento.responses.data.sorted_set.get_score import CacheSortedSetGetScore +from momento.responses.data.sorted_set.increment_score import CacheSortedSetIncrementScore +from momento.responses.data.sorted_set.put_elements import CacheSortedSetPutElements +from momento.responses.data.sorted_set.remove_element import CacheSortedSetRemoveElement + +from tests.conftest import TUniqueCacheNameAsync +from tests.utils import uuid_str + +# Control plane + + +async def test_create_and_delete_cache_succeeds(client_async_v2: CacheClientAsync, cache_name: str) -> None: + cache_name = uuid_str() + + response = await client_async_v2.create_cache(cache_name) + assert isinstance(response, CreateCache.Success) + + delete_response = await client_async_v2.delete_cache(cache_name) + assert isinstance(delete_response, DeleteCache.Success) + + delete_response = await client_async_v2.delete_cache(cache_name) + assert isinstance(delete_response, DeleteCache.Error) + assert delete_response.error_code == MomentoErrorCode.NOT_FOUND_ERROR + + +async def test_flush_cache_succeeds( + client_async_v2: CacheClientAsync, unique_cache_name_async: TUniqueCacheNameAsync +) -> None: + cache_name = unique_cache_name_async(client_async_v2) + + create_cache_rsp = await client_async_v2.create_cache(cache_name) + assert isinstance(create_cache_rsp, CreateCache.Success) + + # set test key + rsp = await client_async_v2.set(cache_name, "test-key", "test-value") + assert isinstance(rsp, CacheSet.Success) + + # flush it + flush_response = await client_async_v2.flush_cache(cache_name) + assert isinstance(flush_response, CacheFlush.Success) + + # make sure key is gone + get_rsp = await client_async_v2.get(cache_name, "test-key") + assert isinstance(get_rsp, CacheGet.Miss) + + +async def test_list_caches_succeeds(client_async_v2: CacheClientAsync, cache_name: str) -> None: + cache_name = uuid_str() + + initial_response = await client_async_v2.list_caches() + assert isinstance(initial_response, ListCaches.Success) + + cache_names = [cache.name for cache in initial_response.caches] + assert cache_name not in cache_names + + try: + response = await client_async_v2.create_cache(cache_name) + assert isinstance(response, CreateCache.Success) + + list_cache_resp = await client_async_v2.list_caches() + assert isinstance(list_cache_resp, ListCaches.Success) + + cache_names = [cache.name for cache in list_cache_resp.caches] + assert cache_name in cache_names + finally: + delete_response = await client_async_v2.delete_cache(cache_name) + assert isinstance(delete_response, DeleteCache.Success) + + +# Scalar methods + + +async def test_create_get_set_delete_succeeds( + client_async_v2: CacheClientAsync, + cache_name: str, +) -> None: + key = uuid_str() + value = uuid_str() + + set_resp = await client_async_v2.set(cache_name, key, value) + assert isinstance(set_resp, CacheSet.Success) + + get_resp = await client_async_v2.get(cache_name, key) + assert isinstance(get_resp, CacheGet.Hit) + assert get_resp.value_string == value + + delete_resp = await client_async_v2.delete(cache_name, key) + assert isinstance(delete_resp, CacheDelete.Success) + + get_after_delete_resp = await client_async_v2.get(cache_name, key) + assert isinstance(get_after_delete_resp, CacheGet.Miss) + + +async def test_increment_succeeds( + client_async_v2: CacheClientAsync, + cache_name: str, +) -> None: + key = uuid_str() + + inc_resp1 = await client_async_v2.increment(cache_name, key) + assert isinstance(inc_resp1, CacheIncrement.Success) + assert inc_resp1.value == 1 + + inc_resp2 = await client_async_v2.increment(cache_name, key) + assert isinstance(inc_resp2, CacheIncrement.Success) + assert inc_resp2.value == 2 + + +# Dictionary + + +async def test_dictionary_set_get_remove_fields( + client_async_v2: CacheClientAsync, + cache_name: str, +) -> None: + key = uuid_str() + field1 = "field1" + field2 = "field2" + value1 = "value1" + value2 = "value2" + + dict_set_resp = await client_async_v2.dictionary_set_fields( + cache_name, + key, + {field1: value1, field2: value2}, + ) + assert isinstance(dict_set_resp, CacheDictionarySetFields.Success) + + dict_get_resp = await client_async_v2.dictionary_get_fields( + cache_name, + key, + [field1, field2], + ) + assert isinstance(dict_get_resp, CacheDictionaryGetFields.Hit) + assert dict_get_resp.value_dictionary_string_string == {field1: value1, field2: value2} + + dict_remove_resp = await client_async_v2.dictionary_remove_fields( + cache_name, + key, + [field1], + ) + assert isinstance(dict_remove_resp, CacheDictionaryRemoveFields.Success) + + dict_get_after_remove_resp = await client_async_v2.dictionary_get_fields( + cache_name, + key, + [field1, field2], + ) + assert isinstance(dict_get_after_remove_resp, CacheDictionaryGetFields.Hit) + assert dict_get_after_remove_resp.value_dictionary_string_string == {field2: value2} + + +async def test_dictionary_increment_and_fetch( + client_async_v2: CacheClientAsync, + cache_name: str, +) -> None: + key = uuid_str() + field = "counter" + + dict_inc_resp1 = await client_async_v2.dictionary_increment(cache_name, key, field) + assert isinstance(dict_inc_resp1, CacheDictionaryIncrement.Success) + assert dict_inc_resp1.value == 1 + + dict_inc_resp2 = await client_async_v2.dictionary_increment(cache_name, key, field) + assert isinstance(dict_inc_resp2, CacheDictionaryIncrement.Success) + assert dict_inc_resp2.value == 2 + + dict_fetch_resp = await client_async_v2.dictionary_fetch(cache_name, key) + assert isinstance(dict_fetch_resp, CacheDictionaryFetch.Hit) + assert dict_fetch_resp.value_dictionary_string_string == {field: "2"} + + +# List + + +async def test_list_concatenate_and_length( + client_async_v2: CacheClientAsync, + cache_name: str, +) -> None: + list_name = uuid_str() + + # Concatenate first batch + concat_resp1 = await client_async_v2.list_concatenate_back(cache_name, list_name, ["a", "b", "c"]) + assert isinstance(concat_resp1, CacheListConcatenateBack.Success) + + # Check length + length_resp1 = await client_async_v2.list_length(cache_name, list_name) + assert isinstance(length_resp1, CacheListLength.Hit) + assert length_resp1.length == 3 + + # Concatenate second batch + concat_resp2 = await client_async_v2.list_concatenate_front(cache_name, list_name, ["d", "e"]) + assert isinstance(concat_resp2, CacheListConcatenateFront.Success) + + # Check length again + length_resp2 = await client_async_v2.list_length(cache_name, list_name) + assert isinstance(length_resp2, CacheListLength.Hit) + assert length_resp2.length == 5 + + +async def test_list_push_and_pop( + client_async_v2: CacheClientAsync, + cache_name: str, +) -> None: + list_name = uuid_str() + + # Push to back + push_back_resp = await client_async_v2.list_push_back(cache_name, list_name, "x") + assert isinstance(push_back_resp, CacheListPushBack.Success) + + length_resp = await client_async_v2.list_length(cache_name, list_name) + assert isinstance(length_resp, CacheListLength.Hit) + assert length_resp.length == 1 + + # Push to front + push_front_resp = await client_async_v2.list_push_front(cache_name, list_name, "y") + assert isinstance(push_front_resp, CacheListPushFront.Success) + + length_resp = await client_async_v2.list_length(cache_name, list_name) + assert isinstance(length_resp, CacheListLength.Hit) + assert length_resp.length == 2 + + # Pop from back + pop_back_resp = await client_async_v2.list_pop_back(cache_name, list_name) + assert isinstance(pop_back_resp, CacheListPopBack.Hit) + assert pop_back_resp.value_string == "x" + + # Pop from front + pop_front_resp = await client_async_v2.list_pop_front(cache_name, list_name) + assert isinstance(pop_front_resp, CacheListPopFront.Hit) + assert pop_front_resp.value_string == "y" + + +async def test_list_fetch_and_remove_value( + client_async_v2: CacheClientAsync, + cache_name: str, +) -> None: + list_name = uuid_str() + + # Populate list + populate_resp = await client_async_v2.list_concatenate_back(cache_name, list_name, ["a", "b", "c", "b", "d"]) + assert isinstance(populate_resp, CacheListConcatenateBack.Success) + + # Fetch list + fetch_resp = await client_async_v2.list_fetch(cache_name, list_name) + assert isinstance(fetch_resp, CacheListFetch.Hit) + assert fetch_resp.value_list_string == ["a", "b", "c", "b", "d"] + + # Remove value 'b' + remove_resp = await client_async_v2.list_remove_value(cache_name, list_name, "b") + assert isinstance(remove_resp, CacheListRemoveValue.Success) + + # Fetch list again + fetch_resp_2 = await client_async_v2.list_fetch(cache_name, list_name) + assert isinstance(fetch_resp_2, CacheListFetch.Hit) + assert fetch_resp_2.value_list_string == ["a", "c", "d"] + + +# Set + + +async def test_set_add_fetch_remove( + client_async_v2: CacheClientAsync, + cache_name: str, +) -> None: + set_name = uuid_str() + + # Add elements + add_resp = await client_async_v2.set_add_elements(cache_name, set_name, {"one", "two", "three"}) + assert isinstance(add_resp, CacheSetAddElements.Success) + + # Fetch set + fetch_resp = await client_async_v2.set_fetch(cache_name, set_name) + assert isinstance(fetch_resp, CacheSetFetch.Hit) + assert fetch_resp.value_set_string == {"one", "two", "three"} + + # Remove an element + remove_resp = await client_async_v2.set_remove_element(cache_name, set_name, "two") + assert isinstance(remove_resp, CacheSetRemoveElement.Success) + + # Fetch set again + fetch_resp_2 = await client_async_v2.set_fetch(cache_name, set_name) + assert isinstance(fetch_resp_2, CacheSetFetch.Hit) + assert fetch_resp_2.value_set_string == {"one", "three"} + + +# Sorted Set + + +async def test_sorted_set_put_fetch_remove(client_async_v2: CacheClientAsync, cache_name: str) -> None: + sorted_set_name = uuid_str() + + # Put elements + scores = {"a": 10.0, "b": 20.0, "c": 30.0} + resp = await client_async_v2.sorted_set_put_elements(cache_name, sorted_set_name, scores) + assert isinstance(resp, CacheSortedSetPutElements.Success) + + # Fetch elements + fetch_resp = await client_async_v2.sorted_set_fetch_by_score(cache_name, sorted_set_name) + assert isinstance(fetch_resp, CacheSortedSetFetch.Hit) + assert fetch_resp.value_list_string == list(scores.items()) + + # Remove an element + remove_resp = await client_async_v2.sorted_set_remove_element(cache_name, sorted_set_name, "b") + assert isinstance(remove_resp, CacheSortedSetRemoveElement.Success) + + # Fetch elements again + fetch_resp_2 = await client_async_v2.sorted_set_fetch_by_score(cache_name, sorted_set_name) + assert isinstance(fetch_resp_2, CacheSortedSetFetch.Hit) + assert fetch_resp_2.value_list_string == [("a", 10.0), ("c", 30.0)] + + +async def test_sorted_set_increment_and_get( + client_async_v2: CacheClientAsync, + cache_name: str, +) -> None: + sorted_set_name = uuid_str() + member = "counter" + + # Increment member + inc_resp1 = await client_async_v2.sorted_set_increment_score(cache_name, sorted_set_name, member, 5.0) + assert isinstance(inc_resp1, CacheSortedSetIncrementScore.Success) + assert inc_resp1.score == 5.0 + + inc_resp2 = await client_async_v2.sorted_set_increment_score(cache_name, sorted_set_name, member, 3.0) + assert isinstance(inc_resp2, CacheSortedSetIncrementScore.Success) + assert inc_resp2.score == 8.0 + + # Get member score + get_resp = await client_async_v2.sorted_set_get_score(cache_name, sorted_set_name, member) + assert isinstance(get_resp, CacheSortedSetGetScore.Hit) + assert get_resp.score == 8.0 + + +async def test_sorted_set_fetch_by_score_and_rank( + client_async_v2: CacheClientAsync, + cache_name: str, +) -> None: + sorted_set_name = uuid_str() + + # Put elements + scores = {"a": 10.0, "b": 20.0, "c": 30.0, "d": 40.0, "e": 50.0} + resp = await client_async_v2.sorted_set_put_elements(cache_name, sorted_set_name, scores) + assert isinstance(resp, CacheSortedSetPutElements.Success) + + # Fetch by rank descending + fetch_by_rank_resp = await client_async_v2.sorted_set_fetch_by_rank( + cache_name, sorted_set_name, start_rank=0, end_rank=2, sort_order=SortOrder.DESCENDING + ) + assert isinstance(fetch_by_rank_resp, CacheSortedSetFetch.Hit) + assert fetch_by_rank_resp.value_list_string == [("e", 50.0), ("d", 40.0)] + + # Fetch by score with all options + fetch_by_score_resp = await client_async_v2.sorted_set_fetch_by_score( + cache_name, sorted_set_name, min_score=15.0, max_score=50.0, sort_order=SortOrder.ASCENDING, offset=1, count=2 + ) + assert isinstance(fetch_by_score_resp, CacheSortedSetFetch.Hit) + assert fetch_by_score_resp.value_list_string == [("c", 30.0), ("d", 40.0)] diff --git a/tests/momento/cache_client/test_control.py b/tests/momento/cache_client/test_control.py index 0027d706..c95d028a 100644 --- a/tests/momento/cache_client/test_control.py +++ b/tests/momento/cache_client/test_control.py @@ -206,7 +206,7 @@ def test_list_caches_throws_authentication_exception_for_bad_token( def test_list_caches_succeeds_even_if_cred_provider_has_been_printed() -> None: - creds_provider = CredentialProvider.from_environment_variable("TEST_API_KEY") + creds_provider = CredentialProvider.from_environment_variable("V1_API_KEY") print(f"Printing creds provider to ensure that it does not corrupt it :) : {creds_provider}") with CacheClient(Configurations.Laptop.v1(), creds_provider, timedelta(seconds=60)) as client: response = client.list_caches() diff --git a/tests/momento/cache_client/test_control_async.py b/tests/momento/cache_client/test_control_async.py index 338f6fc0..1c142a5f 100644 --- a/tests/momento/cache_client/test_control_async.py +++ b/tests/momento/cache_client/test_control_async.py @@ -210,7 +210,7 @@ async def test_list_caches_throws_authentication_exception_for_bad_token( async def test_list_caches_succeeds_even_if_cred_provider_has_been_printed() -> None: - creds_provider = CredentialProvider.from_environment_variable("TEST_API_KEY") + creds_provider = CredentialProvider.from_environment_variable("V1_API_KEY") print(f"Printing creds provider to ensure that it does not corrupt it :) : {creds_provider}") async with CacheClientAsync(Configurations.Laptop.v1(), creds_provider, timedelta(seconds=60)) as client: response = await client.list_caches() diff --git a/tests/momento/topic_client/test_topics_api_key_v2.py b/tests/momento/topic_client/test_topics_api_key_v2.py new file mode 100644 index 00000000..d4674112 --- /dev/null +++ b/tests/momento/topic_client/test_topics_api_key_v2.py @@ -0,0 +1,52 @@ +from momento import TopicClientAsync +from momento.responses import TopicSubscribe, TopicSubscriptionItem + +from tests.utils import uuid_str + +# Async tests + + +async def test_succeeds_with_nonexistent_topic_async(topic_client_async_v2: TopicClientAsync, cache_name: str) -> None: + topic = uuid_str() + + resp = await topic_client_async_v2.subscribe(cache_name, topic) + assert isinstance(resp, TopicSubscribe.SubscriptionAsync) + + +async def test_subscribe_happy_path_string_async(topic_client_async_v2: TopicClientAsync, cache_name: str) -> None: + topic = uuid_str() + value = uuid_str() + + _ = await topic_client_async_v2.publish(cache_name, topic_name=topic, value=value) + + subscribe_response = await topic_client_async_v2.subscribe(cache_name, topic_name=topic) + assert isinstance(subscribe_response, TopicSubscribe.SubscriptionAsync) + + item_task = subscribe_response.__anext__() + item_response = await item_task + assert isinstance(item_response, TopicSubscriptionItem.Text) + assert item_response.value == value + + +# Sync tests + + +def test_succeeds_with_nonexistent_topic(topic_client_v2: TopicClientAsync, cache_name: str) -> None: + topic = uuid_str() + + resp = topic_client_v2.subscribe(cache_name, topic) + assert isinstance(resp, TopicSubscribe.Subscription) + + +def test_subscribe_happy_path_string(topic_client_v2: TopicClientAsync, cache_name: str) -> None: + topic = uuid_str() + value = uuid_str() + + _ = topic_client_v2.publish(cache_name, topic_name=topic, value=value) + + subscribe_response = topic_client_v2.subscribe(cache_name, topic_name=topic) + assert isinstance(subscribe_response, TopicSubscribe.Subscription) + + item_response = next(subscribe_response) + assert isinstance(item_response, TopicSubscriptionItem.Text) + assert item_response.value == value