diff --git a/.coveragerc b/.coveragerc index 97cc4c97..86349ee1 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.flake8 b/.flake8 index 87f6e408..32986c79 100644 --- a/.flake8 +++ b/.flake8 @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml index 81f87c56..f30cb377 100644 --- a/.github/.OwlBot.lock.yaml +++ b/.github/.OwlBot.lock.yaml @@ -13,5 +13,5 @@ # limitations under the License. docker: image: gcr.io/cloud-devrel-public-resources/owlbot-python:latest - digest: sha256:5a4c19d17e597b92d786e569be101e636c9c2817731f80a5adec56b2aa8fe070 -# created: 2024-04-12T11:35:58.922854369Z + digest: sha256:52210e0e0559f5ea8c52be148b33504022e1faef4e95fbe4b32d68022af2fa7e +# created: 2024-07-08T19:25:35.862283192Z diff --git a/.github/auto-label.yaml b/.github/auto-label.yaml index 8b37ee89..21786a4e 100644 --- a/.github/auto-label.yaml +++ b/.github/auto-label.yaml @@ -1,4 +1,4 @@ -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.kokoro/build.sh b/.kokoro/build.sh index e5247962..2e9893f0 100755 --- a/.kokoro/build.sh +++ b/.kokoro/build.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.kokoro/docker/docs/Dockerfile b/.kokoro/docker/docs/Dockerfile index bdaf39fe..5205308b 100644 --- a/.kokoro/docker/docs/Dockerfile +++ b/.kokoro/docker/docs/Dockerfile @@ -1,4 +1,4 @@ -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from ubuntu:22.04 +from ubuntu:24.04 ENV DEBIAN_FRONTEND noninteractive @@ -40,7 +40,6 @@ RUN apt-get update \ libssl-dev \ libsqlite3-dev \ portaudio19-dev \ - python3-distutils \ redis-server \ software-properties-common \ ssh \ @@ -60,18 +59,22 @@ RUN apt-get update \ && rm -rf /var/lib/apt/lists/* \ && rm -f /var/cache/apt/archives/*.deb -###################### Install python 3.9.13 -# Download python 3.9.13 -RUN wget https://www.python.org/ftp/python/3.9.13/Python-3.9.13.tgz +###################### Install python 3.10.14 for docs/docfx session + +# Download python 3.10.14 +RUN wget https://www.python.org/ftp/python/3.10.14/Python-3.10.14.tgz # Extract files -RUN tar -xvf Python-3.9.13.tgz +RUN tar -xvf Python-3.10.14.tgz -# Install python 3.9.13 -RUN ./Python-3.9.13/configure --enable-optimizations +# Install python 3.10.14 +RUN ./Python-3.10.14/configure --enable-optimizations RUN make altinstall +RUN python3.10 -m venv /venv +ENV PATH /venv/bin:$PATH + ###################### Install pip RUN wget -O /tmp/get-pip.py 'https://bootstrap.pypa.io/get-pip.py' \ && python3 /tmp/get-pip.py \ @@ -84,4 +87,4 @@ RUN python3 -m pip COPY requirements.txt /requirements.txt RUN python3 -m pip install --require-hashes -r requirements.txt -CMD ["python3.8"] +CMD ["python3.10"] diff --git a/.kokoro/docker/docs/requirements.txt b/.kokoro/docker/docs/requirements.txt index 0e5d70f2..7129c771 100644 --- a/.kokoro/docker/docs/requirements.txt +++ b/.kokoro/docker/docs/requirements.txt @@ -4,9 +4,9 @@ # # pip-compile --allow-unsafe --generate-hashes requirements.in # -argcomplete==3.2.3 \ - --hash=sha256:bf7900329262e481be5a15f56f19736b376df6f82ed27576fa893652c5de6c23 \ - --hash=sha256:c12355e0494c76a2a7b73e3a59b09024ca0ba1e279fb9ed6c1b82d5b74b6a70c +argcomplete==3.4.0 \ + --hash=sha256:69a79e083a716173e5532e0fa3bef45f793f4e61096cf52b5a42c0211c8b8aa5 \ + --hash=sha256:c2abcdfe1be8ace47ba777d4fce319eb13bf8ad9dace8d085dcad6eded88057f # via nox colorlog==6.8.2 \ --hash=sha256:3e3e079a41feb5a1b64f978b5ea4f46040a94f11f0e8bbb8261e3dbbeca64d44 \ @@ -16,23 +16,27 @@ distlib==0.3.8 \ --hash=sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784 \ --hash=sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64 # via virtualenv -filelock==3.13.1 \ - --hash=sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e \ - --hash=sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c +filelock==3.15.4 \ + --hash=sha256:2207938cbc1844345cb01a5a95524dae30f0ce089eba5b00378295a17e3e90cb \ + --hash=sha256:6ca1fffae96225dab4c6eaf1c4f4f28cd2568d3ec2a44e15a08520504de468e7 # via virtualenv -nox==2024.3.2 \ - --hash=sha256:e53514173ac0b98dd47585096a55572fe504fecede58ced708979184d05440be \ - --hash=sha256:f521ae08a15adbf5e11f16cb34e8d0e6ea521e0b92868f684e91677deb974553 +nox==2024.4.15 \ + --hash=sha256:6492236efa15a460ecb98e7b67562a28b70da006ab0be164e8821177577c0565 \ + --hash=sha256:ecf6700199cdfa9e5ea0a41ff5e6ef4641d09508eda6edb89d9987864115817f # via -r requirements.in -packaging==24.0 \ - --hash=sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5 \ - --hash=sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9 +packaging==24.1 \ + --hash=sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002 \ + --hash=sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124 # via nox -platformdirs==4.2.0 \ - --hash=sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068 \ - --hash=sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768 +platformdirs==4.2.2 \ + --hash=sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee \ + --hash=sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3 # via virtualenv -virtualenv==20.25.1 \ - --hash=sha256:961c026ac520bac5f69acb8ea063e8a4f071bcc9457b9c1f28f6b085c511583a \ - --hash=sha256:e08e13ecdca7a0bd53798f356d5831434afa5b07b93f0abdf0797b7a06ffe197 +tomli==2.0.1 \ + --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \ + --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f + # via nox +virtualenv==20.26.3 \ + --hash=sha256:4c43a2a236279d9ea36a0d76f98d84bd6ca94ac4e0f4a3b9d46d05e10fea542a \ + --hash=sha256:8cc4a31139e796e9a7de2cd5cf2489de1217193116a8fd42328f1bd65f434589 # via nox diff --git a/.kokoro/populate-secrets.sh b/.kokoro/populate-secrets.sh index 6f397214..c435402f 100755 --- a/.kokoro/populate-secrets.sh +++ b/.kokoro/populate-secrets.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2023 Google LLC. +# Copyright 2024 Google LLC. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.kokoro/publish-docs.sh b/.kokoro/publish-docs.sh index 9eafe0be..38f083f0 100755 --- a/.kokoro/publish-docs.sh +++ b/.kokoro/publish-docs.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.kokoro/release.sh b/.kokoro/release.sh index bfd1a231..8c40aeb7 100755 --- a/.kokoro/release.sh +++ b/.kokoro/release.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.kokoro/requirements.txt b/.kokoro/requirements.txt index 51f92b8e..9622baf0 100644 --- a/.kokoro/requirements.txt +++ b/.kokoro/requirements.txt @@ -4,21 +4,25 @@ # # pip-compile --allow-unsafe --generate-hashes requirements.in # -argcomplete==3.1.4 \ - --hash=sha256:72558ba729e4c468572609817226fb0a6e7e9a0a7d477b882be168c0b4a62b94 \ - --hash=sha256:fbe56f8cda08aa9a04b307d8482ea703e96a6a801611acb4be9bf3942017989f +argcomplete==3.4.0 \ + --hash=sha256:69a79e083a716173e5532e0fa3bef45f793f4e61096cf52b5a42c0211c8b8aa5 \ + --hash=sha256:c2abcdfe1be8ace47ba777d4fce319eb13bf8ad9dace8d085dcad6eded88057f # via nox -attrs==23.1.0 \ - --hash=sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04 \ - --hash=sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015 +attrs==23.2.0 \ + --hash=sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30 \ + --hash=sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1 # via gcp-releasetool -cachetools==5.3.2 \ - --hash=sha256:086ee420196f7b2ab9ca2db2520aca326318b68fe5ba8bc4d49cca91add450f2 \ - --hash=sha256:861f35a13a451f94e301ce2bec7cac63e881232ccce7ed67fab9b5df4d3beaa1 +backports-tarfile==1.2.0 \ + --hash=sha256:77e284d754527b01fb1e6fa8a1afe577858ebe4e9dad8919e34c862cb399bc34 \ + --hash=sha256:d75e02c268746e1b8144c278978b6e98e85de6ad16f8e4b0844a154557eca991 + # via jaraco-context +cachetools==5.3.3 \ + --hash=sha256:0abad1021d3f8325b2fc1d2e9c8b9c9d57b04c3932657a72465447332c24d945 \ + --hash=sha256:ba29e2dfa0b8b556606f097407ed1aa62080ee108ab0dc5ec9d6a723a007d105 # via google-auth -certifi==2023.7.22 \ - --hash=sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082 \ - --hash=sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9 +certifi==2024.7.4 \ + --hash=sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b \ + --hash=sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90 # via requests cffi==1.16.0 \ --hash=sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc \ @@ -87,90 +91,90 @@ click==8.0.4 \ # -r requirements.in # gcp-docuploader # gcp-releasetool -colorlog==6.7.0 \ - --hash=sha256:0d33ca236784a1ba3ff9c532d4964126d8a2c44f1f0cb1d2b0728196f512f662 \ - --hash=sha256:bd94bd21c1e13fac7bd3153f4bc3a7dc0eb0974b8bc2fdf1a989e474f6e582e5 +colorlog==6.8.2 \ + --hash=sha256:3e3e079a41feb5a1b64f978b5ea4f46040a94f11f0e8bbb8261e3dbbeca64d44 \ + --hash=sha256:4dcbb62368e2800cb3c5abd348da7e53f6c362dda502ec27c560b2e58a66bd33 # via # gcp-docuploader # nox -cryptography==42.0.5 \ - --hash=sha256:0270572b8bd2c833c3981724b8ee9747b3ec96f699a9665470018594301439ee \ - --hash=sha256:111a0d8553afcf8eb02a4fea6ca4f59d48ddb34497aa8706a6cf536f1a5ec576 \ - --hash=sha256:16a48c23a62a2f4a285699dba2e4ff2d1cff3115b9df052cdd976a18856d8e3d \ - --hash=sha256:1b95b98b0d2af784078fa69f637135e3c317091b615cd0905f8b8a087e86fa30 \ - --hash=sha256:1f71c10d1e88467126f0efd484bd44bca5e14c664ec2ede64c32f20875c0d413 \ - --hash=sha256:2424ff4c4ac7f6b8177b53c17ed5d8fa74ae5955656867f5a8affaca36a27abb \ - --hash=sha256:2bce03af1ce5a5567ab89bd90d11e7bbdff56b8af3acbbec1faded8f44cb06da \ - --hash=sha256:329906dcc7b20ff3cad13c069a78124ed8247adcac44b10bea1130e36caae0b4 \ - --hash=sha256:37dd623507659e08be98eec89323469e8c7b4c1407c85112634ae3dbdb926fdd \ - --hash=sha256:3eaafe47ec0d0ffcc9349e1708be2aaea4c6dd4978d76bf6eb0cb2c13636c6fc \ - --hash=sha256:5e6275c09d2badf57aea3afa80d975444f4be8d3bc58f7f80d2a484c6f9485c8 \ - --hash=sha256:6fe07eec95dfd477eb9530aef5bead34fec819b3aaf6c5bd6d20565da607bfe1 \ - --hash=sha256:7367d7b2eca6513681127ebad53b2582911d1736dc2ffc19f2c3ae49997496bc \ - --hash=sha256:7cde5f38e614f55e28d831754e8a3bacf9ace5d1566235e39d91b35502d6936e \ - --hash=sha256:9481ffe3cf013b71b2428b905c4f7a9a4f76ec03065b05ff499bb5682a8d9ad8 \ - --hash=sha256:98d8dc6d012b82287f2c3d26ce1d2dd130ec200c8679b6213b3c73c08b2b7940 \ - --hash=sha256:a011a644f6d7d03736214d38832e030d8268bcff4a41f728e6030325fea3e400 \ - --hash=sha256:a2913c5375154b6ef2e91c10b5720ea6e21007412f6437504ffea2109b5a33d7 \ - --hash=sha256:a30596bae9403a342c978fb47d9b0ee277699fa53bbafad14706af51fe543d16 \ - --hash=sha256:b03c2ae5d2f0fc05f9a2c0c997e1bc18c8229f392234e8a0194f202169ccd278 \ - --hash=sha256:b6cd2203306b63e41acdf39aa93b86fb566049aeb6dc489b70e34bcd07adca74 \ - --hash=sha256:b7ffe927ee6531c78f81aa17e684e2ff617daeba7f189f911065b2ea2d526dec \ - --hash=sha256:b8cac287fafc4ad485b8a9b67d0ee80c66bf3574f655d3b97ef2e1082360faf1 \ - --hash=sha256:ba334e6e4b1d92442b75ddacc615c5476d4ad55cc29b15d590cc6b86efa487e2 \ - --hash=sha256:ba3e4a42397c25b7ff88cdec6e2a16c2be18720f317506ee25210f6d31925f9c \ - --hash=sha256:c41fb5e6a5fe9ebcd58ca3abfeb51dffb5d83d6775405305bfa8715b76521922 \ - --hash=sha256:cd2030f6650c089aeb304cf093f3244d34745ce0cfcc39f20c6fbfe030102e2a \ - --hash=sha256:cd65d75953847815962c84a4654a84850b2bb4aed3f26fadcc1c13892e1e29f6 \ - --hash=sha256:e4985a790f921508f36f81831817cbc03b102d643b5fcb81cd33df3fa291a1a1 \ - --hash=sha256:e807b3188f9eb0eaa7bbb579b462c5ace579f1cedb28107ce8b48a9f7ad3679e \ - --hash=sha256:f12764b8fffc7a123f641d7d049d382b73f96a34117e0b637b80643169cec8ac \ - --hash=sha256:f8837fe1d6ac4a8052a9a8ddab256bc006242696f03368a4009be7ee3075cdb7 +cryptography==42.0.8 \ + --hash=sha256:013629ae70b40af70c9a7a5db40abe5d9054e6f4380e50ce769947b73bf3caad \ + --hash=sha256:2346b911eb349ab547076f47f2e035fc8ff2c02380a7cbbf8d87114fa0f1c583 \ + --hash=sha256:2f66d9cd9147ee495a8374a45ca445819f8929a3efcd2e3df6428e46c3cbb10b \ + --hash=sha256:2f88d197e66c65be5e42cd72e5c18afbfae3f741742070e3019ac8f4ac57262c \ + --hash=sha256:31f721658a29331f895a5a54e7e82075554ccfb8b163a18719d342f5ffe5ecb1 \ + --hash=sha256:343728aac38decfdeecf55ecab3264b015be68fc2816ca800db649607aeee648 \ + --hash=sha256:5226d5d21ab681f432a9c1cf8b658c0cb02533eece706b155e5fbd8a0cdd3949 \ + --hash=sha256:57080dee41209e556a9a4ce60d229244f7a66ef52750f813bfbe18959770cfba \ + --hash=sha256:5a94eccb2a81a309806027e1670a358b99b8fe8bfe9f8d329f27d72c094dde8c \ + --hash=sha256:6b7c4f03ce01afd3b76cf69a5455caa9cfa3de8c8f493e0d3ab7d20611c8dae9 \ + --hash=sha256:7016f837e15b0a1c119d27ecd89b3515f01f90a8615ed5e9427e30d9cdbfed3d \ + --hash=sha256:81884c4d096c272f00aeb1f11cf62ccd39763581645b0812e99a91505fa48e0c \ + --hash=sha256:81d8a521705787afe7a18d5bfb47ea9d9cc068206270aad0b96a725022e18d2e \ + --hash=sha256:8d09d05439ce7baa8e9e95b07ec5b6c886f548deb7e0f69ef25f64b3bce842f2 \ + --hash=sha256:961e61cefdcb06e0c6d7e3a1b22ebe8b996eb2bf50614e89384be54c48c6b63d \ + --hash=sha256:9c0c1716c8447ee7dbf08d6db2e5c41c688544c61074b54fc4564196f55c25a7 \ + --hash=sha256:a0608251135d0e03111152e41f0cc2392d1e74e35703960d4190b2e0f4ca9c70 \ + --hash=sha256:a0c5b2b0585b6af82d7e385f55a8bc568abff8923af147ee3c07bd8b42cda8b2 \ + --hash=sha256:ad803773e9df0b92e0a817d22fd8a3675493f690b96130a5e24f1b8fabbea9c7 \ + --hash=sha256:b297f90c5723d04bcc8265fc2a0f86d4ea2e0f7ab4b6994459548d3a6b992a14 \ + --hash=sha256:ba4f0a211697362e89ad822e667d8d340b4d8d55fae72cdd619389fb5912eefe \ + --hash=sha256:c4783183f7cb757b73b2ae9aed6599b96338eb957233c58ca8f49a49cc32fd5e \ + --hash=sha256:c9bb2ae11bfbab395bdd072985abde58ea9860ed84e59dbc0463a5d0159f5b71 \ + --hash=sha256:cafb92b2bc622cd1aa6a1dce4b93307792633f4c5fe1f46c6b97cf67073ec961 \ + --hash=sha256:d45b940883a03e19e944456a558b67a41160e367a719833c53de6911cabba2b7 \ + --hash=sha256:dc0fdf6787f37b1c6b08e6dfc892d9d068b5bdb671198c72072828b80bd5fe4c \ + --hash=sha256:dea567d1b0e8bc5764b9443858b673b734100c2871dc93163f58c46a97a83d28 \ + --hash=sha256:dec9b018df185f08483f294cae6ccac29e7a6e0678996587363dc352dc65c842 \ + --hash=sha256:e3ec3672626e1b9e55afd0df6d774ff0e953452886e06e0f1eb7eb0c832e8902 \ + --hash=sha256:e599b53fd95357d92304510fb7bda8523ed1f79ca98dce2f43c115950aa78801 \ + --hash=sha256:fa76fbb7596cc5839320000cdd5d0955313696d9511debab7ee7278fc8b5c84a \ + --hash=sha256:fff12c88a672ab9c9c1cf7b0c80e3ad9e2ebd9d828d955c126be4fd3e5578c9e # via # -r requirements.in # gcp-releasetool # secretstorage -distlib==0.3.7 \ - --hash=sha256:2e24928bc811348f0feb63014e97aaae3037f2cf48712d51ae61df7fd6075057 \ - --hash=sha256:9dafe54b34a028eafd95039d5e5d4851a13734540f1331060d31c9916e7147a8 +distlib==0.3.8 \ + --hash=sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784 \ + --hash=sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64 # via virtualenv -docutils==0.20.1 \ - --hash=sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6 \ - --hash=sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b +docutils==0.21.2 \ + --hash=sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f \ + --hash=sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2 # via readme-renderer -filelock==3.13.1 \ - --hash=sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e \ - --hash=sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c +filelock==3.15.4 \ + --hash=sha256:2207938cbc1844345cb01a5a95524dae30f0ce089eba5b00378295a17e3e90cb \ + --hash=sha256:6ca1fffae96225dab4c6eaf1c4f4f28cd2568d3ec2a44e15a08520504de468e7 # via virtualenv gcp-docuploader==0.6.5 \ --hash=sha256:30221d4ac3e5a2b9c69aa52fdbef68cc3f27d0e6d0d90e220fc024584b8d2318 \ --hash=sha256:b7458ef93f605b9d46a4bf3a8dc1755dad1f31d030c8679edf304e343b347eea # via -r requirements.in -gcp-releasetool==2.0.0 \ - --hash=sha256:3d73480b50ba243f22d7c7ec08b115a30e1c7817c4899781840c26f9c55b8277 \ - --hash=sha256:7aa9fd935ec61e581eb8458ad00823786d91756c25e492f372b2b30962f3c28f +gcp-releasetool==2.0.1 \ + --hash=sha256:34314a910c08e8911d9c965bd44f8f2185c4f556e737d719c33a41f6a610de96 \ + --hash=sha256:b0d5863c6a070702b10883d37c4bdfd74bf930fe417f36c0c965d3b7c779ae62 # via -r requirements.in -google-api-core==2.12.0 \ - --hash=sha256:c22e01b1e3c4dcd90998494879612c38d0a3411d1f7b679eb89e2abe3ce1f553 \ - --hash=sha256:ec6054f7d64ad13b41e43d96f735acbd763b0f3b695dabaa2d579673f6a6e160 +google-api-core==2.19.1 \ + --hash=sha256:f12a9b8309b5e21d92483bbd47ce2c445861ec7d269ef6784ecc0ea8c1fa6125 \ + --hash=sha256:f4695f1e3650b316a795108a76a1c416e6afb036199d1c1f1f110916df479ffd # via # google-cloud-core # google-cloud-storage -google-auth==2.23.4 \ - --hash=sha256:79905d6b1652187def79d491d6e23d0cbb3a21d3c7ba0dbaa9c8a01906b13ff3 \ - --hash=sha256:d4bbc92fe4b8bfd2f3e8d88e5ba7085935da208ee38a134fc280e7ce682a05f2 +google-auth==2.31.0 \ + --hash=sha256:042c4702efa9f7d3c48d3a69341c209381b125faa6dbf3ebe56bc7e40ae05c23 \ + --hash=sha256:87805c36970047247c8afe614d4e3af8eceafc1ebba0c679fe75ddd1d575e871 # via # gcp-releasetool # google-api-core # google-cloud-core # google-cloud-storage -google-cloud-core==2.3.3 \ - --hash=sha256:37b80273c8d7eee1ae816b3a20ae43585ea50506cb0e60f3cf5be5f87f1373cb \ - --hash=sha256:fbd11cad3e98a7e5b0343dc07cb1039a5ffd7a5bb96e1f1e27cee4bda4a90863 +google-cloud-core==2.4.1 \ + --hash=sha256:9b7749272a812bde58fff28868d0c5e2f585b82f37e09a1f6ed2d4d10f134073 \ + --hash=sha256:a9e6a4422b9ac5c29f79a0ede9485473338e2ce78d91f2370c01e730eab22e61 # via google-cloud-storage -google-cloud-storage==2.13.0 \ - --hash=sha256:ab0bf2e1780a1b74cf17fccb13788070b729f50c252f0c94ada2aae0ca95437d \ - --hash=sha256:f62dc4c7b6cd4360d072e3deb28035fbdad491ac3d9b0b1815a12daea10f37c7 +google-cloud-storage==2.17.0 \ + --hash=sha256:49378abff54ef656b52dca5ef0f2eba9aa83dc2b2c72c78714b03a1a95fe9388 \ + --hash=sha256:5b393bc766b7a3bc6f5407b9e665b2450d36282614b7945e570b3480a456d1e1 # via gcp-docuploader google-crc32c==1.5.0 \ --hash=sha256:024894d9d3cfbc5943f8f230e23950cd4906b2fe004c72e29b209420a1e6b05a \ @@ -244,28 +248,36 @@ google-crc32c==1.5.0 \ # via # google-cloud-storage # google-resumable-media -google-resumable-media==2.6.0 \ - --hash=sha256:972852f6c65f933e15a4a210c2b96930763b47197cdf4aa5f5bea435efb626e7 \ - --hash=sha256:fc03d344381970f79eebb632a3c18bb1828593a2dc5572b5f90115ef7d11e81b +google-resumable-media==2.7.1 \ + --hash=sha256:103ebc4ba331ab1bfdac0250f8033627a2cd7cde09e7ccff9181e31ba4315b2c \ + --hash=sha256:eae451a7b2e2cdbaaa0fd2eb00cc8a1ee5e95e16b55597359cbc3d27d7d90e33 # via google-cloud-storage -googleapis-common-protos==1.61.0 \ - --hash=sha256:22f1915393bb3245343f6efe87f6fe868532efc12aa26b391b15132e1279f1c0 \ - --hash=sha256:8a64866a97f6304a7179873a465d6eee97b7a24ec6cfd78e0f575e96b821240b +googleapis-common-protos==1.63.2 \ + --hash=sha256:27a2499c7e8aff199665b22741997e485eccc8645aa9176c7c988e6fae507945 \ + --hash=sha256:27c5abdffc4911f28101e635de1533fb4cfd2c37fbaa9174587c799fac90aa87 # via google-api-core idna==3.7 \ --hash=sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc \ --hash=sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0 # via requests -importlib-metadata==6.8.0 \ - --hash=sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb \ - --hash=sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743 +importlib-metadata==8.0.0 \ + --hash=sha256:15584cf2b1bf449d98ff8a6ff1abef57bf20f3ac6454f431736cd3e660921b2f \ + --hash=sha256:188bd24e4c346d3f0a933f275c2fec67050326a856b9a359881d7c2a697e8812 # via # -r requirements.in # keyring # twine -jaraco-classes==3.3.0 \ - --hash=sha256:10afa92b6743f25c0cf5f37c6bb6e18e2c5bb84a16527ccfc0040ea377e7aaeb \ - --hash=sha256:c063dd08e89217cee02c8d5e5ec560f2c8ce6cdc2fcdc2e68f7b2e5547ed3621 +jaraco-classes==3.4.0 \ + --hash=sha256:47a024b51d0239c0dd8c8540c6c7f484be3b8fcf0b2d85c13825780d3b3f3acd \ + --hash=sha256:f662826b6bed8cace05e7ff873ce0f9283b5c924470fe664fff1c2f00f581790 + # via keyring +jaraco-context==5.3.0 \ + --hash=sha256:3e16388f7da43d384a1a7cd3452e72e14732ac9fe459678773a3608a812bf266 \ + --hash=sha256:c2f67165ce1f9be20f32f650f25d8edfc1646a8aeee48ae06fb35f90763576d2 + # via keyring +jaraco-functools==4.0.1 \ + --hash=sha256:3b24ccb921d6b593bdceb56ce14799204f473976e2a9d4b15b04d0f2c2326664 \ + --hash=sha256:d33fa765374c0611b52f8b3a795f8900869aa88c84769d4d1746cd68fb28c3e8 # via keyring jeepney==0.8.0 \ --hash=sha256:5efe48d255973902f6badc3ce55e2aa6c5c3b3bc642059ef3a91247bcfcc5806 \ @@ -273,13 +285,13 @@ jeepney==0.8.0 \ # via # keyring # secretstorage -jinja2==3.1.3 \ - --hash=sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa \ - --hash=sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90 +jinja2==3.1.4 \ + --hash=sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369 \ + --hash=sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d # via gcp-releasetool -keyring==24.2.0 \ - --hash=sha256:4901caaf597bfd3bbd78c9a0c7c4c29fcd8310dab2cffefe749e916b6527acd6 \ - --hash=sha256:ca0746a19ec421219f4d713f848fa297a661a8a8c1504867e55bfb5e09091509 +keyring==25.2.1 \ + --hash=sha256:2458681cdefc0dbc0b7eb6cf75d0b98e59f9ad9b2d4edd319d18f68bdca95e50 \ + --hash=sha256:daaffd42dbda25ddafb1ad5fec4024e5bbcfe424597ca1ca452b299861e49f1b # via # gcp-releasetool # twine @@ -287,146 +299,153 @@ markdown-it-py==3.0.0 \ --hash=sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1 \ --hash=sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb # via rich -markupsafe==2.1.3 \ - --hash=sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e \ - --hash=sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e \ - --hash=sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431 \ - --hash=sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686 \ - --hash=sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c \ - --hash=sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559 \ - --hash=sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc \ - --hash=sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb \ - --hash=sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939 \ - --hash=sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c \ - --hash=sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0 \ - --hash=sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4 \ - --hash=sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9 \ - --hash=sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575 \ - --hash=sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba \ - --hash=sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d \ - --hash=sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd \ - --hash=sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3 \ - --hash=sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00 \ - --hash=sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155 \ - --hash=sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac \ - --hash=sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52 \ - --hash=sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f \ - --hash=sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8 \ - --hash=sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b \ - --hash=sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007 \ - --hash=sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24 \ - --hash=sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea \ - --hash=sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198 \ - --hash=sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0 \ - --hash=sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee \ - --hash=sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be \ - --hash=sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2 \ - --hash=sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1 \ - --hash=sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707 \ - --hash=sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6 \ - --hash=sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c \ - --hash=sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58 \ - --hash=sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823 \ - --hash=sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779 \ - --hash=sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636 \ - --hash=sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c \ - --hash=sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad \ - --hash=sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee \ - --hash=sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc \ - --hash=sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2 \ - --hash=sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48 \ - --hash=sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7 \ - --hash=sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e \ - --hash=sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b \ - --hash=sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa \ - --hash=sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5 \ - --hash=sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e \ - --hash=sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb \ - --hash=sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9 \ - --hash=sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57 \ - --hash=sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc \ - --hash=sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc \ - --hash=sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2 \ - --hash=sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11 +markupsafe==2.1.5 \ + --hash=sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf \ + --hash=sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff \ + --hash=sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f \ + --hash=sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3 \ + --hash=sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532 \ + --hash=sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f \ + --hash=sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617 \ + --hash=sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df \ + --hash=sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4 \ + --hash=sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906 \ + --hash=sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f \ + --hash=sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4 \ + --hash=sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8 \ + --hash=sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371 \ + --hash=sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2 \ + --hash=sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465 \ + --hash=sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52 \ + --hash=sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6 \ + --hash=sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169 \ + --hash=sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad \ + --hash=sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2 \ + --hash=sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0 \ + --hash=sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029 \ + --hash=sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f \ + --hash=sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a \ + --hash=sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced \ + --hash=sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5 \ + --hash=sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c \ + --hash=sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf \ + --hash=sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9 \ + --hash=sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb \ + --hash=sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad \ + --hash=sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3 \ + --hash=sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1 \ + --hash=sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46 \ + --hash=sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc \ + --hash=sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a \ + --hash=sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee \ + --hash=sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900 \ + --hash=sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5 \ + --hash=sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea \ + --hash=sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f \ + --hash=sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5 \ + --hash=sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e \ + --hash=sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a \ + --hash=sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f \ + --hash=sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50 \ + --hash=sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a \ + --hash=sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b \ + --hash=sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4 \ + --hash=sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff \ + --hash=sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2 \ + --hash=sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46 \ + --hash=sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b \ + --hash=sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf \ + --hash=sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5 \ + --hash=sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5 \ + --hash=sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab \ + --hash=sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd \ + --hash=sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68 # via jinja2 mdurl==0.1.2 \ --hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \ --hash=sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba # via markdown-it-py -more-itertools==10.1.0 \ - --hash=sha256:626c369fa0eb37bac0291bce8259b332fd59ac792fa5497b59837309cd5b114a \ - --hash=sha256:64e0735fcfdc6f3464ea133afe8ea4483b1c5fe3a3d69852e6503b43a0b222e6 - # via jaraco-classes -nh3==0.2.14 \ - --hash=sha256:116c9515937f94f0057ef50ebcbcc10600860065953ba56f14473ff706371873 \ - --hash=sha256:18415df36db9b001f71a42a3a5395db79cf23d556996090d293764436e98e8ad \ - --hash=sha256:203cac86e313cf6486704d0ec620a992c8bc164c86d3a4fd3d761dd552d839b5 \ - --hash=sha256:2b0be5c792bd43d0abef8ca39dd8acb3c0611052ce466d0401d51ea0d9aa7525 \ - --hash=sha256:377aaf6a9e7c63962f367158d808c6a1344e2b4f83d071c43fbd631b75c4f0b2 \ - --hash=sha256:525846c56c2bcd376f5eaee76063ebf33cf1e620c1498b2a40107f60cfc6054e \ - --hash=sha256:5529a3bf99402c34056576d80ae5547123f1078da76aa99e8ed79e44fa67282d \ - --hash=sha256:7771d43222b639a4cd9e341f870cee336b9d886de1ad9bec8dddab22fe1de450 \ - --hash=sha256:88c753efbcdfc2644a5012938c6b9753f1c64a5723a67f0301ca43e7b85dcf0e \ - --hash=sha256:93a943cfd3e33bd03f77b97baa11990148687877b74193bf777956b67054dcc6 \ - --hash=sha256:9be2f68fb9a40d8440cbf34cbf40758aa7f6093160bfc7fb018cce8e424f0c3a \ - --hash=sha256:a0c509894fd4dccdff557068e5074999ae3b75f4c5a2d6fb5415e782e25679c4 \ - --hash=sha256:ac8056e937f264995a82bf0053ca898a1cb1c9efc7cd68fa07fe0060734df7e4 \ - --hash=sha256:aed56a86daa43966dd790ba86d4b810b219f75b4bb737461b6886ce2bde38fd6 \ - --hash=sha256:e8986f1dd3221d1e741fda0a12eaa4a273f1d80a35e31a1ffe579e7c621d069e \ - --hash=sha256:f99212a81c62b5f22f9e7c3e347aa00491114a5647e1f13bbebd79c3e5f08d75 +more-itertools==10.3.0 \ + --hash=sha256:e5d93ef411224fbcef366a6e8ddc4c5781bc6359d43412a65dd5964e46111463 \ + --hash=sha256:ea6a02e24a9161e51faad17a8782b92a0df82c12c1c8886fec7f0c3fa1a1b320 + # via + # jaraco-classes + # jaraco-functools +nh3==0.2.18 \ + --hash=sha256:0411beb0589eacb6734f28d5497ca2ed379eafab8ad8c84b31bb5c34072b7164 \ + --hash=sha256:14c5a72e9fe82aea5fe3072116ad4661af5cf8e8ff8fc5ad3450f123e4925e86 \ + --hash=sha256:19aaba96e0f795bd0a6c56291495ff59364f4300d4a39b29a0abc9cb3774a84b \ + --hash=sha256:34c03fa78e328c691f982b7c03d4423bdfd7da69cd707fe572f544cf74ac23ad \ + --hash=sha256:36c95d4b70530b320b365659bb5034341316e6a9b30f0b25fa9c9eff4c27a204 \ + --hash=sha256:3a157ab149e591bb638a55c8c6bcb8cdb559c8b12c13a8affaba6cedfe51713a \ + --hash=sha256:42c64511469005058cd17cc1537578eac40ae9f7200bedcfd1fc1a05f4f8c200 \ + --hash=sha256:5f36b271dae35c465ef5e9090e1fdaba4a60a56f0bb0ba03e0932a66f28b9189 \ + --hash=sha256:6955369e4d9f48f41e3f238a9e60f9410645db7e07435e62c6a9ea6135a4907f \ + --hash=sha256:7b7c2a3c9eb1a827d42539aa64091640bd275b81e097cd1d8d82ef91ffa2e811 \ + --hash=sha256:8ce0f819d2f1933953fca255db2471ad58184a60508f03e6285e5114b6254844 \ + --hash=sha256:94a166927e53972a9698af9542ace4e38b9de50c34352b962f4d9a7d4c927af4 \ + --hash=sha256:a7f1b5b2c15866f2db413a3649a8fe4fd7b428ae58be2c0f6bca5eefd53ca2be \ + --hash=sha256:c8b3a1cebcba9b3669ed1a84cc65bf005728d2f0bc1ed2a6594a992e817f3a50 \ + --hash=sha256:de3ceed6e661954871d6cd78b410213bdcb136f79aafe22aa7182e028b8c7307 \ + --hash=sha256:f0eca9ca8628dbb4e916ae2491d72957fdd35f7a5d326b7032a345f111ac07fe # via readme-renderer -nox==2023.4.22 \ - --hash=sha256:0b1adc619c58ab4fa57d6ab2e7823fe47a32e70202f287d78474adcc7bda1891 \ - --hash=sha256:46c0560b0dc609d7d967dc99e22cb463d3c4caf54a5fda735d6c11b5177e3a9f +nox==2024.4.15 \ + --hash=sha256:6492236efa15a460ecb98e7b67562a28b70da006ab0be164e8821177577c0565 \ + --hash=sha256:ecf6700199cdfa9e5ea0a41ff5e6ef4641d09508eda6edb89d9987864115817f # via -r requirements.in -packaging==23.2 \ - --hash=sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5 \ - --hash=sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7 +packaging==24.1 \ + --hash=sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002 \ + --hash=sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124 # via # gcp-releasetool # nox -pkginfo==1.9.6 \ - --hash=sha256:4b7a555a6d5a22169fcc9cf7bfd78d296b0361adad412a346c1226849af5e546 \ - --hash=sha256:8fd5896e8718a4372f0ea9cc9d96f6417c9b986e23a4d116dda26b62cc29d046 +pkginfo==1.10.0 \ + --hash=sha256:5df73835398d10db79f8eecd5cd86b1f6d29317589ea70796994d49399af6297 \ + --hash=sha256:889a6da2ed7ffc58ab5b900d888ddce90bce912f2d2de1dc1c26f4cb9fe65097 # via twine -platformdirs==3.11.0 \ - --hash=sha256:cf8ee52a3afdb965072dcc652433e0c7e3e40cf5ea1477cd4b3b1d2eb75495b3 \ - --hash=sha256:e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e +platformdirs==4.2.2 \ + --hash=sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee \ + --hash=sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3 # via virtualenv -protobuf==4.25.3 \ - --hash=sha256:19b270aeaa0099f16d3ca02628546b8baefe2955bbe23224aaf856134eccf1e4 \ - --hash=sha256:209ba4cc916bab46f64e56b85b090607a676f66b473e6b762e6f1d9d591eb2e8 \ - --hash=sha256:25b5d0b42fd000320bd7830b349e3b696435f3b329810427a6bcce6a5492cc5c \ - --hash=sha256:7c8daa26095f82482307bc717364e7c13f4f1c99659be82890dcfc215194554d \ - --hash=sha256:c053062984e61144385022e53678fbded7aea14ebb3e0305ae3592fb219ccfa4 \ - --hash=sha256:d4198877797a83cbfe9bffa3803602bbe1625dc30d8a097365dbc762e5790faa \ - --hash=sha256:e3c97a1555fd6388f857770ff8b9703083de6bf1f9274a002a332d65fbb56c8c \ - --hash=sha256:e7cb0ae90dd83727f0c0718634ed56837bfeeee29a5f82a7514c03ee1364c019 \ - --hash=sha256:f0700d54bcf45424477e46a9f0944155b46fb0639d69728739c0e47bab83f2b9 \ - --hash=sha256:f1279ab38ecbfae7e456a108c5c0681e4956d5b1090027c1de0f934dfdb4b35c \ - --hash=sha256:f4f118245c4a087776e0a8408be33cf09f6c547442c00395fbfb116fac2f8ac2 +proto-plus==1.24.0 \ + --hash=sha256:30b72a5ecafe4406b0d339db35b56c4059064e69227b8c3bda7462397f966445 \ + --hash=sha256:402576830425e5f6ce4c2a6702400ac79897dab0b4343821aa5188b0fab81a12 + # via google-api-core +protobuf==5.27.2 \ + --hash=sha256:0e341109c609749d501986b835f667c6e1e24531096cff9d34ae411595e26505 \ + --hash=sha256:176c12b1f1c880bf7a76d9f7c75822b6a2bc3db2d28baa4d300e8ce4cde7409b \ + --hash=sha256:354d84fac2b0d76062e9b3221f4abbbacdfd2a4d8af36bab0474f3a0bb30ab38 \ + --hash=sha256:4fadd8d83e1992eed0248bc50a4a6361dc31bcccc84388c54c86e530b7f58863 \ + --hash=sha256:54330f07e4949d09614707c48b06d1a22f8ffb5763c159efd5c0928326a91470 \ + --hash=sha256:610e700f02469c4a997e58e328cac6f305f649826853813177e6290416e846c6 \ + --hash=sha256:7fc3add9e6003e026da5fc9e59b131b8f22b428b991ccd53e2af8071687b4fce \ + --hash=sha256:9e8f199bf7f97bd7ecebffcae45ebf9527603549b2b562df0fbc6d4d688f14ca \ + --hash=sha256:a109916aaac42bff84702fb5187f3edadbc7c97fc2c99c5ff81dd15dcce0d1e5 \ + --hash=sha256:b848dbe1d57ed7c191dfc4ea64b8b004a3f9ece4bf4d0d80a367b76df20bf36e \ + --hash=sha256:f3ecdef226b9af856075f28227ff2c90ce3a594d092c39bee5513573f25e2714 # via # gcp-docuploader # gcp-releasetool # google-api-core # googleapis-common-protos -pyasn1==0.5.0 \ - --hash=sha256:87a2121042a1ac9358cabcaf1d07680ff97ee6404333bacca15f76aa8ad01a57 \ - --hash=sha256:97b7290ca68e62a832558ec3976f15cbf911bf5d7c7039d8b861c2a0ece69fde + # proto-plus +pyasn1==0.6.0 \ + --hash=sha256:3a35ab2c4b5ef98e17dfdec8ab074046fbda76e281c5a706ccd82328cfc8f64c \ + --hash=sha256:cca4bb0f2df5504f02f6f8a775b6e416ff9b0b3b16f7ee80b5a3153d9b804473 # via # pyasn1-modules # rsa -pyasn1-modules==0.3.0 \ - --hash=sha256:5bd01446b736eb9d31512a30d46c1ac3395d676c6f3cafa4c03eb54b9925631c \ - --hash=sha256:d3ccd6ed470d9ffbc716be08bd90efbd44d0734bc9303818f7336070984a162d +pyasn1-modules==0.4.0 \ + --hash=sha256:831dbcea1b177b28c9baddf4c6d1013c24c3accd14a1873fffaa6a2e905f17b6 \ + --hash=sha256:be04f15b66c206eed667e0bb5ab27e2b1855ea54a842e5037738099e8ca4ae0b # via google-auth -pycparser==2.21 \ - --hash=sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9 \ - --hash=sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206 +pycparser==2.22 \ + --hash=sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6 \ + --hash=sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc # via cffi -pygments==2.16.1 \ - --hash=sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692 \ - --hash=sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29 +pygments==2.18.0 \ + --hash=sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199 \ + --hash=sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a # via # readme-renderer # rich @@ -434,20 +453,20 @@ pyjwt==2.8.0 \ --hash=sha256:57e28d156e3d5c10088e0c68abb90bfac3df82b40a71bd0daa20c65ccd5c23de \ --hash=sha256:59127c392cc44c2da5bb3192169a91f429924e17aff6534d70fdc02ab3e04320 # via gcp-releasetool -pyperclip==1.8.2 \ - --hash=sha256:105254a8b04934f0bc84e9c24eb360a591aaf6535c9def5f29d92af107a9bf57 +pyperclip==1.9.0 \ + --hash=sha256:b7de0142ddc81bfc5c7507eea19da920b92252b548b96186caf94a5e2527d310 # via gcp-releasetool -python-dateutil==2.8.2 \ - --hash=sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86 \ - --hash=sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9 +python-dateutil==2.9.0.post0 \ + --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ + --hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 # via gcp-releasetool -readme-renderer==42.0 \ - --hash=sha256:13d039515c1f24de668e2c93f2e877b9dbe6c6c32328b90a40a49d8b2b85f36d \ - --hash=sha256:2d55489f83be4992fe4454939d1a051c33edbab778e82761d060c9fc6b308cd1 +readme-renderer==44.0 \ + --hash=sha256:2fbca89b81a08526aadf1357a8c2ae889ec05fb03f5da67f9769c9a592166151 \ + --hash=sha256:8712034eabbfa6805cacf1402b4eeb2a73028f72d1166d6f5cb7f9c047c5d1e1 # via twine -requests==2.31.0 \ - --hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f \ - --hash=sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1 +requests==2.32.3 \ + --hash=sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760 \ + --hash=sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6 # via # gcp-releasetool # google-api-core @@ -462,9 +481,9 @@ rfc3986==2.0.0 \ --hash=sha256:50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd \ --hash=sha256:97aacf9dbd4bfd829baad6e6309fa6573aaf1be3f6fa735c8ab05e46cecb261c # via twine -rich==13.6.0 \ - --hash=sha256:2b38e2fe9ca72c9a00170a1a2d20c63c790d0e10ef1fe35eba76e1e7b1d7d245 \ - --hash=sha256:5c14d22737e6d5084ef4771b62d5d4363165b403455a30a1c8ca39dc7b644bef +rich==13.7.1 \ + --hash=sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222 \ + --hash=sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432 # via twine rsa==4.9 \ --hash=sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7 \ @@ -480,35 +499,39 @@ six==1.16.0 \ # via # gcp-docuploader # python-dateutil -twine==4.0.2 \ - --hash=sha256:929bc3c280033347a00f847236564d1c52a3e61b1ac2516c97c48f3ceab756d8 \ - --hash=sha256:9e102ef5fdd5a20661eb88fad46338806c3bd32cf1db729603fe3697b1bc83c8 +tomli==2.0.1 \ + --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \ + --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f + # via nox +twine==5.1.1 \ + --hash=sha256:215dbe7b4b94c2c50a7315c0275d2258399280fbb7d04182c7e55e24b5f93997 \ + --hash=sha256:9aa0825139c02b3434d913545c7b847a21c835e11597f5255842d457da2322db # via -r requirements.in -typing-extensions==4.8.0 \ - --hash=sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0 \ - --hash=sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef +typing-extensions==4.12.2 \ + --hash=sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d \ + --hash=sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8 # via -r requirements.in -urllib3==2.0.7 \ - --hash=sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84 \ - --hash=sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e +urllib3==2.2.2 \ + --hash=sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472 \ + --hash=sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168 # via # requests # twine -virtualenv==20.24.6 \ - --hash=sha256:02ece4f56fbf939dbbc33c0715159951d6bf14aaf5457b092e4548e1382455af \ - --hash=sha256:520d056652454c5098a00c0f073611ccbea4c79089331f60bf9d7ba247bb7381 +virtualenv==20.26.3 \ + --hash=sha256:4c43a2a236279d9ea36a0d76f98d84bd6ca94ac4e0f4a3b9d46d05e10fea542a \ + --hash=sha256:8cc4a31139e796e9a7de2cd5cf2489de1217193116a8fd42328f1bd65f434589 # via nox -wheel==0.41.3 \ - --hash=sha256:488609bc63a29322326e05560731bf7bfea8e48ad646e1f5e40d366607de0942 \ - --hash=sha256:4d4987ce51a49370ea65c0bfd2234e8ce80a12780820d9dc462597a6e60d0841 +wheel==0.43.0 \ + --hash=sha256:465ef92c69fa5c5da2d1cf8ac40559a8c940886afcef87dcf14b9470862f1d85 \ + --hash=sha256:55c570405f142630c6b9f72fe09d9b67cf1477fcf543ae5b8dcb1f5b7377da81 # via -r requirements.in -zipp==3.17.0 \ - --hash=sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31 \ - --hash=sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0 +zipp==3.19.2 \ + --hash=sha256:bf1dcf6450f873a13e952a29504887c89e6de7506209e5b1bcc3460135d4de19 \ + --hash=sha256:f091755f667055f2d02b32c53771a7a6c8b47e1fdbc4b72a8b9072b3eef8015c # via importlib-metadata # The following packages are considered to be unsafe in a requirements file: -setuptools==69.2.0 \ - --hash=sha256:0ff4183f8f42cd8fa3acea16c45205521a4ef28f73c6391d8a25e92893134f2e \ - --hash=sha256:c21c49fb1042386df081cb5d86759792ab89efca84cf114889191cd09aacc80c +setuptools==70.2.0 \ + --hash=sha256:b8b8060bb426838fbe942479c90296ce976249451118ef566a5a0b7d8b78fb05 \ + --hash=sha256:bd63e505105011b25c3c11f753f7e3b8465ea739efddaccef8f0efac2137bac1 # via -r requirements.in diff --git a/.kokoro/test-samples-against-head.sh b/.kokoro/test-samples-against-head.sh index 63ac41df..e9d8bd79 100755 --- a/.kokoro/test-samples-against-head.sh +++ b/.kokoro/test-samples-against-head.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.kokoro/test-samples-impl.sh b/.kokoro/test-samples-impl.sh index 5a0f5fab..55910c8b 100755 --- a/.kokoro/test-samples-impl.sh +++ b/.kokoro/test-samples-impl.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.kokoro/test-samples.sh b/.kokoro/test-samples.sh index 50b35a48..7933d820 100755 --- a/.kokoro/test-samples.sh +++ b/.kokoro/test-samples.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.kokoro/trampoline.sh b/.kokoro/trampoline.sh index d85b1f26..48f79699 100755 --- a/.kokoro/trampoline.sh +++ b/.kokoro/trampoline.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.kokoro/trampoline_v2.sh b/.kokoro/trampoline_v2.sh index 59a7cf3a..35fa5292 100755 --- a/.kokoro/trampoline_v2.sh +++ b/.kokoro/trampoline_v2.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6a8e1695..1d74695f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,4 +1,4 @@ -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.trampolinerc b/.trampolinerc index a7dfeb42..00801523 100644 --- a/.trampolinerc +++ b/.trampolinerc @@ -1,4 +1,4 @@ -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d8415b5..68ba84da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## [0.14.0-alpha](https://github.com/googleapis/python-documentai-toolbox/compare/v0.13.5-alpha...v0.14.0-alpha) (2024-07-16) + + +### Features + +* Add Support for Layout Parser Documents ([#334](https://github.com/googleapis/python-documentai-toolbox/issues/334)) ([c877b22](https://github.com/googleapis/python-documentai-toolbox/commit/c877b22367adb821ca4dd4e783249f8dd9a32501)) + + +### Bug Fixes + +* Add support for Classifier entities ([#333](https://github.com/googleapis/python-documentai-toolbox/issues/333)) ([2352cae](https://github.com/googleapis/python-documentai-toolbox/commit/2352cae6a04669188244a6dda443d7fa668cc457)) + ## [0.13.5-alpha](https://github.com/googleapis/python-documentai-toolbox/compare/v0.13.4-alpha...v0.13.5-alpha) (2024-07-02) diff --git a/MANIFEST.in b/MANIFEST.in index e0a66705..d6814cd6 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/docs/conf.py b/docs/conf.py index e1af8af8..9634a864 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/google/cloud/documentai_toolbox/version.py b/google/cloud/documentai_toolbox/version.py index 05a8bc38..0d4278a2 100644 --- a/google/cloud/documentai_toolbox/version.py +++ b/google/cloud/documentai_toolbox/version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.13.5-alpha" +__version__ = "0.14.0-alpha" diff --git a/google/cloud/documentai_toolbox/wrappers/document.py b/google/cloud/documentai_toolbox/wrappers/document.py index 92c0e8c6..092cf2d9 100644 --- a/google/cloud/documentai_toolbox/wrappers/document.py +++ b/google/cloud/documentai_toolbox/wrappers/document.py @@ -15,13 +15,14 @@ # """Wrappers for Document AI Document type.""" +import collections import copy import dataclasses from functools import cached_property import glob import os import re -from typing import Dict, List, Optional, Type, Union +from typing import Dict, Iterator, List, Optional, Type, Union from google.api_core.client_options import ClientOptions from google.api_core.operation import from_gapic as operation_from_gapic @@ -38,6 +39,33 @@ from google.cloud.documentai_toolbox.wrappers.page import FormField, Page +def _chunks_from_shards( + shards: List[documentai.Document], +) -> Iterator[documentai.Document.ChunkedDocument.Chunk]: + for shard in shards: + for chunk in shard.chunked_document.chunks: + yield chunk + + +def _document_layout_blocks_from_shards( + shards: List[documentai.Document], +) -> Iterator[documentai.Document.DocumentLayout.DocumentLayoutBlock]: + def extract_blocks( + blocks: List[documentai.Document.DocumentLayout.DocumentLayoutBlock], + ) -> Iterator[documentai.Document.DocumentLayout.DocumentLayoutBlock]: + queue = collections.deque(blocks) + + while queue: + block = queue.popleft() + yield block + # Add the nested blocks to the stack in the correct order + if block.text_block and block.text_block.blocks: + queue.extendleft(reversed(block.text_block.blocks)) + + for shard in shards: + yield from extract_blocks(shard.document_layout.blocks) + + def _entities_from_shards( shards: List[documentai.Document], ) -> List[Entity]: @@ -379,7 +407,11 @@ class Document: pages (List[Page]): A list of `Pages` in the `Document`. entities (List[Entity]): - A list of `Entities` in the `Document`. + A list of un-nested `Entities` in the `Document`. + chunks (Iterator[documentai.Document.ChunkedDocument.Chunk]): + An iterator of document chunks extracted from a Layout Parser. + document_layout_blocks (Iterator[documentai.Document.DocumentLayout.DocumentLayoutBlock]): + An iterator of document layout blocks extracted from a Layout Parser. text (str): The full text of the `Document`. """ @@ -398,6 +430,14 @@ def pages(self): def entities(self): return _entities_from_shards(shards=self.shards) + @cached_property + def chunks(self): + return _chunks_from_shards(shards=self.shards) + + @cached_property + def document_layout_blocks(self): + return _document_layout_blocks_from_shards(shards=self.shards) + @cached_property def text(self): return "".join(shard.text for shard in self.shards) @@ -765,7 +805,7 @@ def entities_to_bigquery( ) def split_pdf(self, pdf_path: str, output_path: str) -> List[str]: - r"""Splits local PDF file into multiple PDF files based on output from a Splitter/Classifier processor. + r"""Splits local PDF file into multiple PDF files based on output from a Splitter processor. Args: pdf_path (str): @@ -776,6 +816,8 @@ def split_pdf(self, pdf_path: str, output_path: str) -> List[str]: List[str]: A list of output pdf files. """ + if self.entities[0].start_page is None or self.entities[0].end_page is None: + raise ValueError("Entities do not contain start or end pages.") output_files: List[str] = [] input_filename, input_extension = os.path.splitext(os.path.basename(pdf_path)) with Pdf.open(pdf_path) as pdf: diff --git a/google/cloud/documentai_toolbox/wrappers/entity.py b/google/cloud/documentai_toolbox/wrappers/entity.py index 2ccb6530..02b2e1ba 100644 --- a/google/cloud/documentai_toolbox/wrappers/entity.py +++ b/google/cloud/documentai_toolbox/wrappers/entity.py @@ -40,45 +40,46 @@ class Entity: Required. Entity type from a schema e.g. "Address". mention_text (str): Optional. Text value in the document e.g. "1600 Amphitheatre Pkwy". - If the entity is not present in - the document, this field will be empty. + Only populated for Extraction processors. normalized_text (str): Optional. Normalized text value in the document e.g. "1970-01-01". - If the entity is not present in - the document, this field will be empty. + Only populated for Extraction processors. start_page (int): - Required. `Page` containing the `Entity` or the first page of the - classification (for Splitter/Classifier processors). + Optional. `Page` containing the `Entity` for Extraction processors or the first page of the + subdocument for Splitter processors. end_page (int): - Required. Last page of the classification + Optional. Last page of the subdocument for Splitter processors. """ documentai_object: documentai.Document.Entity = dataclasses.field(repr=False) page_offset: dataclasses.InitVar[Optional[int]] = 0 type_: str = dataclasses.field(init=False) - mention_text: str = dataclasses.field(init=False, default="") - normalized_text: str = dataclasses.field(init=False, default="") + mention_text: Optional[str] = dataclasses.field(init=False, default=None) + normalized_text: Optional[str] = dataclasses.field(init=False, default=None) - start_page: int = dataclasses.field(init=False) - # Only Populated for Splitter/Classifier Output - end_page: int = dataclasses.field(init=False) + start_page: Optional[int] = dataclasses.field(init=False, default=None) + end_page: Optional[int] = dataclasses.field(init=False, default=None) _image: Optional[Image.Image] = dataclasses.field(init=False, default=None) def __post_init__(self, page_offset: int) -> None: self.type_ = self.documentai_object.type_ - self.mention_text = self.documentai_object.mention_text + + if self.documentai_object.mention_text: + self.mention_text = self.documentai_object.mention_text + if ( self.documentai_object.normalized_value and self.documentai_object.normalized_value.text ): self.normalized_text = self.documentai_object.normalized_value.text - page_refs = self.documentai_object.page_anchor.page_refs - if page_refs: - self.start_page = int(page_refs[0].page) + page_offset - self.end_page = int(page_refs[-1].page) + page_offset + if self.documentai_object.page_anchor: + page_refs = self.documentai_object.page_anchor.page_refs + if page_refs: + self.start_page = int(page_refs[0].page) + page_offset + self.end_page = int(page_refs[-1].page) + page_offset def crop_image( self, documentai_page: documentai.Document.Page diff --git a/noxfile.py b/noxfile.py index 9a9b1ba2..d8f865ea 100644 --- a/noxfile.py +++ b/noxfile.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -159,14 +159,28 @@ def install_unittest_dependencies(session, *constraints): session.install("-e", ".", *constraints) -def default(session): +@nox.session(python=UNIT_TEST_PYTHON_VERSIONS) +@nox.parametrize( + "protobuf_implementation", + ["python", "upb", "cpp"], +) +def unit(session, protobuf_implementation): # Install all test dependencies, then install this package in-place. + if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12"): + session.skip("cpp implementation is not supported in python 3.11+") + constraints_path = str( CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" ) install_unittest_dependencies(session, "-c", constraints_path) + # TODO(https://github.com/googleapis/synthtool/issues/1976): + # Remove the 'cpp' implementation once support for Protobuf 3.x is dropped. + # The 'cpp' implementation requires Protobuf<4. + if protobuf_implementation == "cpp": + session.install("protobuf<4") + # Run py.test against the unit tests. session.run( "py.test", @@ -180,15 +194,12 @@ def default(session): "--cov-fail-under=0", os.path.join("tests", "unit"), *session.posargs, + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + }, ) -@nox.session(python=UNIT_TEST_PYTHON_VERSIONS) -def unit(session): - """Run the unit test suite.""" - default(session) - - def install_systemtest_dependencies(session, *constraints): # Use pre-release gRPC for system tests. # Exclude version 1.52.0rc1 which has a known issue. @@ -275,7 +286,7 @@ def cover(session): session.run("coverage", "erase") -@nox.session(python="3.9") +@nox.session(python="3.10") def docs(session): """Build the docs for this library.""" @@ -356,10 +367,17 @@ def docfx(session): ) -@nox.session(python=SYSTEM_TEST_PYTHON_VERSIONS) -def prerelease_deps(session): +@nox.session(python="3.12") +@nox.parametrize( + "protobuf_implementation", + ["python", "upb", "cpp"], +) +def prerelease_deps(session, protobuf_implementation): """Run all tests with prerelease versions of dependencies installed.""" + if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12"): + session.skip("cpp implementation is not supported in python 3.11+") + # Install all dependencies session.install("-e", ".[all, tests, tracing]") unit_deps_all = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_EXTERNAL_DEPENDENCIES @@ -394,9 +412,9 @@ def prerelease_deps(session): "protobuf", # dependency of grpc "six", + "grpc-google-iam-v1", "googleapis-common-protos", - # Exclude version 1.52.0rc1 which has a known issue. See https://github.com/grpc/grpc/issues/32163 - "grpcio!=1.52.0rc1", + "grpcio", "grpcio-status", "google-api-core", "google-auth", @@ -422,7 +440,13 @@ def prerelease_deps(session): session.run("python", "-c", "import grpc; print(grpc.__version__)") session.run("python", "-c", "import google.auth; print(google.auth.__version__)") - session.run("py.test", "tests/unit") + session.run( + "py.test", + "tests/unit", + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + }, + ) system_test_path = os.path.join("tests", "system.py") system_test_folder_path = os.path.join("tests", "system") @@ -435,6 +459,9 @@ def prerelease_deps(session): f"--junitxml=system_{session.python}_sponge_log.xml", system_test_path, *session.posargs, + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + }, ) if os.path.exists(system_test_folder_path): session.run( @@ -443,4 +470,7 @@ def prerelease_deps(session): f"--junitxml=system_{session.python}_sponge_log.xml", system_test_folder_path, *session.posargs, + env={ + "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation, + }, ) diff --git a/samples/snippets/quickstart_sample.py b/samples/snippets/quickstart_sample.py index e08dc4f3..226eca60 100644 --- a/samples/snippets/quickstart_sample.py +++ b/samples/snippets/quickstart_sample.py @@ -1,3 +1,4 @@ +# flake8: noqa: C901 # Copyright 2023 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -127,6 +128,20 @@ def quickstart_sample( if entity.normalized_text: print(f"\tNormalized Text: {entity.normalized_text}") + # Only supported with Layout Parser + for chunk in wrapped_document.chunks: + print(f"Chunk {chunk.chunk_id}: {chunk.content}") + + for block in wrapped_document.document_layout_blocks: + print(f"Document Layout Block {block.block_id}") + + if block.text_block: + print(f"{block.text_block.type_}: {block.text_block.text}") + if block.list_block: + print(f"{block.list_block.type_}: {block.list_block.list_entries}") + if block.table_block: + print(block.table_block.header_rows, block.table_block.body_rows) + # [END documentai_toolbox_quickstart] return wrapped_document diff --git a/samples/snippets/requirements-test.txt b/samples/snippets/requirements-test.txt index 12c2b12b..993fd02e 100644 --- a/samples/snippets/requirements-test.txt +++ b/samples/snippets/requirements-test.txt @@ -1,3 +1,3 @@ -pytest==8.2.1 +pytest==8.2.2 mock==5.1.0 -google-cloud-bigquery==3.23.0 +google-cloud-bigquery==3.25.0 diff --git a/samples/snippets/requirements.txt b/samples/snippets/requirements.txt index 231a6522..55b47b65 100644 --- a/samples/snippets/requirements.txt +++ b/samples/snippets/requirements.txt @@ -1,4 +1,4 @@ -google-cloud-bigquery==3.23.0 -google-cloud-documentai==2.27.1 -google-cloud-storage==2.16.0 -google-cloud-documentai-toolbox==0.13.1a0 +google-cloud-bigquery==3.25.0 +google-cloud-documentai==2.29.2 +google-cloud-storage==2.17.0 +google-cloud-documentai-toolbox==0.13.5a0 diff --git a/scripts/decrypt-secrets.sh b/scripts/decrypt-secrets.sh index 0018b421..120b0ddc 100755 --- a/scripts/decrypt-secrets.sh +++ b/scripts/decrypt-secrets.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2023 Google LLC All rights reserved. +# Copyright 2024 Google LLC All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/scripts/readme-gen/readme_gen.py b/scripts/readme-gen/readme_gen.py index 1acc1198..8f5e248a 100644 --- a/scripts/readme-gen/readme_gen.py +++ b/scripts/readme-gen/readme_gen.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2023 Google LLC +# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/setup.py b/setup.py index 6a6f6c98..469cbb32 100644 --- a/setup.py +++ b/setup.py @@ -60,7 +60,7 @@ "proto-plus>=1.22.3, <2.0.0dev", "grpc-google-iam-v1>=0.12.6, <1.0.0dev", "google-cloud-bigquery>=3.5.0, <4.0.0dev", - "google-cloud-documentai>=2.20.0, <3.0.0dev", + "google-cloud-documentai>=2.29.2, <3.0.0dev", "google-cloud-storage>=1.31.0, <3.0.0dev", "google-cloud-vision>=2.7.0, <4.0.0dev", "numpy>=1.23.5, <2.0.0", diff --git a/testing/constraints-3.8.txt b/testing/constraints-3.8.txt index 9214782a..d58f0c58 100644 --- a/testing/constraints-3.8.txt +++ b/testing/constraints-3.8.txt @@ -10,7 +10,7 @@ pandas==2.0.0 proto-plus==1.22.3 grpc-google-iam-v1==0.12.6 google-cloud-bigquery==3.5.0 -google-cloud-documentai==2.20.0 +google-cloud-documentai==2.29.2 google-cloud-storage==2.7.0 pandas-gbq==0.21.0 numpy==1.23.5 diff --git a/tests/unit/resources/classifier/custom_classifier_output.json b/tests/unit/resources/classifier/custom_classifier_output.json new file mode 100644 index 00000000..1cd42eb0 --- /dev/null +++ b/tests/unit/resources/classifier/custom_classifier_output.json @@ -0,0 +1 @@ +{"text": "US010182182B2\n(12) United States Patent\nLewkow et al.\n(10) Patent No.: US 10,182,182 B2\n(45) Date of Patent: Jan. 15, 2019\n(54)\nIMAGE SENSOR HAVING MULTIPLE\nOUTPUT PORTS\n(71)\nApplicant: Google LLC, Mountain View, CA (US)\nH04N 7/0127 (2013.01); H04N_7/0806\n(2013.01); H04N 13/239 (2018.05); H04N\n13/254 (2018.05); H04N 13/271 (2018.05)\n(58) Field of Classification Search\nCPC G01S 17/08; H04N 5/2258; H04N 5/23229;\nH04N 13/0271; H04N 5/376; H04N\n5/3765; H04N 5/378; H04N 5/345\nSee application file for complete search history.\n(72)\nInventors: Roman Lewkow, San Jose, CA (US);\nChung Chun Wan, San Jose, CA (US)\n(73)\nAssignee: Google LLC, Mountain View, CA (US)\n(*)\nNotice:\n(56)\nReferences Cited\nSubject to any disclaimer, the term of this\npatent is extended or adjusted under 35\nU.S.C. 154(b) by 0 days.\nU.S. PATENT DOCUMENTS\n(21)\nAppl. No.: 15/831,925\n6,831,688 B2 * 12/2004 Lareau\nGO1J 3/02\n348/272\n(22)\nFiled:\nDec. 5, 2017\n7,247,393 B2\n7,936,038 B2\n7,990,636 B2\n8,027,107 B2\n7/2007 Hazel et al.\n5/2011 Jeong et al.\n8/2011 Park et al.\n9/2011 Hwang et al.\n(Continued)\n(65)\nPrior Publication Data\nFOREIGN PATENT DOCUMENTS\n(63)\nUS 2018/0097979 A1 Apr. 5, 2018\nRelated U.S. Application Data\nContinuation of application No. 15/476,165, filed on\nMar. 31, 2017, now Pat. No. 9,866,740, which is a\ncontinuation of application No. 14/580,025, filed on\nDec. 22, 2014, now Pat. No. 9,615,013.\nEP\n1478176\n11/2004\nOTHER PUBLICATIONS\n(51)\nPCT/US2015/062157-International Search Report & Written Opin-\nion, dated Mar. 8, 2016, 12 pages.\n(Continued)\nPrimary Examiner Nicholas G Giles\n(74) Attorney, Agent, or Firm - Fish & Richardson P.C.\nInt. Cl.\nH04N 5/225\n(2006.01)\nH04N 5/374\n(2011.01)\nH04N 5/378\n(2011.01)\nH04N 5/369\n(2011.01)\nH04N 5/232\n(2006.01)\nH04N 13/254 (2018.01)\nH04N 13/271\n(2018.01)\nH04N 7/01\n(2006.01)\nH04N 7/08\n(2006.01)\nH04N 13/239 (2018.01)\nU.S. Cl.\nCPC H04N 5/2258 (2013.01); H04N 5/23245\n(2013.01); H04N 5/3696 (2013.01); H04N\n5/378 (2013.01); H04N 5/3742 (2013.01);\n(57)\nABSTRACT\nAn apparatus is described that includes an image sensor\nhaving a first output port and a second output port. The first\noutput port is to transmit a first image stream concurrently\nwith a second image stream transmitted from the second\noutput port.\n(52)\n18 Claims, 10 Drawing Sheets\nImage Sensor\n410b\nFirst Image\nStream 401b\nImage Signal\nProcessing\nPipeline 407_1b\n1\n1\n2\n413_1b\n1\n2\n3\n5\n6\nSecond Image\nStream 402b\n413_2b\nImage Signal Processing\nPipeline 407_2b\ntime\n", "pages": [{"pageNumber": 1}], "entities": [{"type": "computer_vision", "confidence": 0.47925246, "id": "0"}, {"type": "crypto", "confidence": 0.0433604, "id": "1"}, {"type": "med_tech", "confidence": 0.26732057, "id": "2"}, {"type": "other", "confidence": 0.2100666, "id": "3"}]} diff --git a/tests/unit/resources/layout_parser/layout_parser.json b/tests/unit/resources/layout_parser/layout_parser.json new file mode 100644 index 00000000..0211559a --- /dev/null +++ b/tests/unit/resources/layout_parser/layout_parser.json @@ -0,0 +1 @@ +{"documentLayout": {"blocks": [{"blockId": "1", "textBlock": {"text": "CHAPTER I", "type": "heading-1", "blocks": [{"blockId": "2", "textBlock": {"text": "IN WHICH We Are Introduced to", "type": "paragraph"}, "pageSpan": {"pageStart": 1, "pageEnd": 1}}, {"blockId": "3", "textBlock": {"text": "Winnie-the-Pooh and Some", "type": "paragraph"}, "pageSpan": {"pageStart": 1, "pageEnd": 1}}, {"blockId": "4", "textBlock": {"text": "Bees, and the Stories Begin", "type": "paragraph"}, "pageSpan": {"pageStart": 1, "pageEnd": 1}}, {"blockId": "5", "textBlock": {"text": "HERE", "type": "paragraph"}, "pageSpan": {"pageStart": 1, "pageEnd": 1}}, {"blockId": "6", "textBlock": {"text": "LERE is Edward Bear, coming downstairs now, bump, bump, bump, on the back of his head, behind Christopher Robin. It is, as far as he knows, the only way of coming downstairs, but sometimes he feels that there really is another way, if only he could stop bumping for a moment and think of it. And then he feels that perhaps there isn't. Anyhow, here he is at the bottom, and ready to be introduced to you. Winnie-the-Pooh.", "type": "paragraph"}, "pageSpan": {"pageStart": 1, "pageEnd": 1}}, {"blockId": "7", "textBlock": {"text": "When I first heard his name, I said, just as you are going to say, \"But I thought he was a boy?\" \"So did I,\" said Christopher Robin.", "type": "paragraph"}, "pageSpan": {"pageStart": 1, "pageEnd": 1}}, {"blockId": "8", "textBlock": {"text": "\"Then you can't call him Winnie?\"", "type": "paragraph"}, "pageSpan": {"pageStart": 1, "pageEnd": 1}}, {"blockId": "9", "textBlock": {"text": "6. \"I don't.\"", "type": "paragraph"}, "pageSpan": {"pageStart": 1, "pageEnd": 1}}, {"blockId": "10", "textBlock": {"text": "\"But you said-\"", "type": "paragraph"}, "pageSpan": {"pageStart": 1, "pageEnd": 1}}, {"blockId": "11", "textBlock": {"text": "\"He's Winnje-ther-Pooh. Don't you know what", "type": "paragraph"}, "pageSpan": {"pageStart": 1, "pageEnd": 1}}, {"blockId": "12", "textBlock": {"text": "'ther' means?\"", "type": "paragraph"}, "pageSpan": {"pageStart": 1, "pageEnd": 1}}, {"blockId": "13", "textBlock": {"text": "I", "type": "paragraph"}, "pageSpan": {"pageStart": 1, "pageEnd": 1}}, {"blockId": "14", "textBlock": {"text": "Digitized by Google", "type": "paragraph"}, "pageSpan": {"pageStart": 1, "pageEnd": 1}}, {"blockId": "15", "textBlock": {"text": "2", "type": "paragraph"}, "pageSpan": {"pageStart": 2, "pageEnd": 2}}, {"blockId": "16", "textBlock": {"text": "WINNIE-THE-POOH", "type": "paragraph"}, "pageSpan": {"pageStart": 2, "pageEnd": 2}}, {"blockId": "17", "textBlock": {"text": "\"Ah, yes, now I do,\" I said quickly; and I hope you do too, because it is all the explanation you are going to get.", "type": "paragraph"}, "pageSpan": {"pageStart": 2, "pageEnd": 2}}, {"blockId": "18", "textBlock": {"text": "Sometimes Winnie-the-Pooh likes a game of some sort when he comes downstairs, and sometimes he likes to sit quietly in front of the fire and listen to a story. This evening--", "type": "paragraph"}, "pageSpan": {"pageStart": 2, "pageEnd": 2}}, {"blockId": "19", "textBlock": {"text": "\"What about a story?\" said Christopher Robin. \"What about a story?\" I said.", "type": "paragraph"}, "pageSpan": {"pageStart": 2, "pageEnd": 2}}, {"blockId": "20", "textBlock": {"text": "\"Could you very sweetly tell Winnie-the-Pooh one?\"", "type": "paragraph"}, "pageSpan": {"pageStart": 2, "pageEnd": 2}}, {"blockId": "21", "textBlock": {"text": "\"I suppose I could,\" I said. \"What sort of stories does he like?\"", "type": "paragraph"}, "pageSpan": {"pageStart": 2, "pageEnd": 2}}, {"blockId": "22", "textBlock": {"text": "\"About himself. Because he's that sort of Bear.\" \"Oh, I see.\"", "type": "paragraph"}, "pageSpan": {"pageStart": 2, "pageEnd": 2}}, {"blockId": "23", "textBlock": {"text": "\"So could you very sweetly?\"", "type": "paragraph"}, "pageSpan": {"pageStart": 2, "pageEnd": 2}}, {"blockId": "24", "textBlock": {"text": "\"I'll try,\" I said.", "type": "paragraph"}, "pageSpan": {"pageStart": 2, "pageEnd": 2}}, {"blockId": "25", "textBlock": {"text": "So I tried", "type": "paragraph"}, "pageSpan": {"pageStart": 2, "pageEnd": 2}}, {"blockId": "26", "textBlock": {"text": "Once upon a time, a very long time ago now, about last Friday, Winnie-the-Pooh lived in a forest all by himself under the name of Sanders.", "type": "paragraph"}, "pageSpan": {"pageStart": 2, "pageEnd": 2}}, {"blockId": "27", "textBlock": {"text": "(\"What does 'under the name mean?\" asked Christopher Robin.", "type": "paragraph"}, "pageSpan": {"pageStart": 2, "pageEnd": 2}}, {"blockId": "28", "textBlock": {"text": "\"It means he had the name over the door in gold letters, and lived under it.\"", "type": "paragraph"}, "pageSpan": {"pageStart": 2, "pageEnd": 2}}, {"blockId": "29", "textBlock": {"text": "Digitized by Google", "type": "paragraph"}, "pageSpan": {"pageStart": 2, "pageEnd": 2}}, {"blockId": "30", "textBlock": {"text": "WE ARE INTRODUCED", "type": "paragraph"}, "pageSpan": {"pageStart": 3, "pageEnd": 3}}, {"blockId": "31", "textBlock": {"text": "3", "type": "header"}, "pageSpan": {"pageStart": 3, "pageEnd": 3}}, {"blockId": "32", "textBlock": {"text": "ARNIG ALSO", "type": "paragraph"}, "pageSpan": {"pageStart": 3, "pageEnd": 3}}, {"blockId": "33", "textBlock": {"text": "AB SAUDERZ", "type": "paragraph"}, "pageSpan": {"pageStart": 3, "pageEnd": 3}}, {"blockId": "34", "textBlock": {"text": "\"Winnie-the-Pooh wasn't quite sure,\" said Chris- topher Robin.", "type": "paragraph"}, "pageSpan": {"pageStart": 3, "pageEnd": 3}}, {"blockId": "35", "textBlock": {"text": "\u201cNow I am,\u201d said a growly voice.", "type": "paragraph"}, "pageSpan": {"pageStart": 3, "pageEnd": 3}}, {"blockId": "36", "textBlock": {"text": "\"Then I will go on,\" said I.)", "type": "paragraph"}, "pageSpan": {"pageStart": 3, "pageEnd": 3}}, {"blockId": "37", "textBlock": {"text": "One day when he was out walking, he came to an open place in the middle of the forest, and in the middle of this place was a large oak-tree, and, from the top of the tree, there came a loud buzzing-noise.", "type": "paragraph"}, "pageSpan": {"pageStart": 3, "pageEnd": 3}}, {"blockId": "38", "textBlock": {"text": "Winnie-the-Pooh sat down at the foot of the tree, put his head between his paws and began to think.", "type": "paragraph"}, "pageSpan": {"pageStart": 3, "pageEnd": 3}}, {"blockId": "39", "textBlock": {"text": "Digitized by Google", "type": "paragraph"}, "pageSpan": {"pageStart": 3, "pageEnd": 3}}, {"blockId": "40", "textBlock": {"text": "4", "type": "paragraph"}, "pageSpan": {"pageStart": 4, "pageEnd": 4}}, {"blockId": "41", "textBlock": {"text": "*", "type": "paragraph"}, "pageSpan": {"pageStart": 4, "pageEnd": 4}}, {"blockId": "42", "textBlock": {"text": "WINNIE-THE-POOH", "type": "paragraph"}, "pageSpan": {"pageStart": 4, "pageEnd": 4}}, {"blockId": "43", "textBlock": {"text": "First of all he said to himself: \"That buzzing- noise means something. You don't get a buzzing- noise like that, just buzzing and buzzing, without its meaning something. If there's a buzzing-noise, somebody's making a buzzing-noise, and the only reason for making a buzzing-noise that I know of is because you're a bee.\"", "type": "paragraph"}, "pageSpan": {"pageStart": 4, "pageEnd": 4}}, {"blockId": "44", "textBlock": {"text": "Then he thought another long time, and said: \"And the only reason for being a bee that I know of is making honey.\"", "type": "paragraph"}, "pageSpan": {"pageStart": 4, "pageEnd": 4}}, {"blockId": "45", "textBlock": {"text": "And then he got up, and said: \"And the only reason for making honey is so as I can eat it.\" So he began to climb the tree.", "type": "paragraph"}, "pageSpan": {"pageStart": 4, "pageEnd": 4}}, {"blockId": "46", "textBlock": {"text": "Digitized by Google", "type": "paragraph"}, "pageSpan": {"pageStart": 4, "pageEnd": 4}}, {"blockId": "47", "textBlock": {"text": "WE ARE INTRODUCED", "type": "heading-2", "blocks": [{"blockId": "48", "textBlock": {"text": "He", "type": "paragraph"}, "pageSpan": {"pageStart": 5, "pageEnd": 5}}, {"blockId": "49", "textBlock": {"text": "climbed", "type": "paragraph"}, "pageSpan": {"pageStart": 5, "pageEnd": 5}}, {"blockId": "50", "textBlock": {"text": "and", "type": "paragraph"}, "pageSpan": {"pageStart": 5, "pageEnd": 5}}, {"blockId": "51", "textBlock": {"text": "he", "type": "paragraph"}, "pageSpan": {"pageStart": 5, "pageEnd": 5}}, {"blockId": "52", "textBlock": {"text": "climbed", "type": "paragraph"}, "pageSpan": {"pageStart": 5, "pageEnd": 5}}, {"blockId": "53", "textBlock": {"text": "and", "type": "paragraph"}, "pageSpan": {"pageStart": 5, "pageEnd": 5}}, {"blockId": "54", "textBlock": {"text": "he", "type": "paragraph"}, "pageSpan": {"pageStart": 5, "pageEnd": 5}}, {"blockId": "55", "textBlock": {"text": "climbed,", "type": "paragraph"}, "pageSpan": {"pageStart": 5, "pageEnd": 5}}, {"blockId": "56", "textBlock": {"text": "\u0995", "type": "paragraph"}, "pageSpan": {"pageStart": 5, "pageEnd": 5}}, {"blockId": "57", "textBlock": {"text": "and", "type": "paragraph"}, "pageSpan": {"pageStart": 5, "pageEnd": 5}}, {"blockId": "58", "textBlock": {"text": "as", "type": "paragraph"}, "pageSpan": {"pageStart": 5, "pageEnd": 5}}, {"blockId": "59", "textBlock": {"text": "he", "type": "paragraph"}, "pageSpan": {"pageStart": 5, "pageEnd": 5}}, {"blockId": "60", "textBlock": {"text": "climbed", "type": "paragraph"}, "pageSpan": {"pageStart": 5, "pageEnd": 5}}, {"blockId": "61", "textBlock": {"text": "he", "type": "paragraph"}, "pageSpan": {"pageStart": 5, "pageEnd": 5}}, {"blockId": "62", "textBlock": {"text": "sang", "type": "paragraph"}, "pageSpan": {"pageStart": 5, "pageEnd": 5}}, {"blockId": "63", "textBlock": {"text": "5", "type": "paragraph"}, "pageSpan": {"pageStart": 5, "pageEnd": 5}}, {"blockId": "64", "textBlock": {"text": "7", "type": "paragraph"}, "pageSpan": {"pageStart": 5, "pageEnd": 5}}, {"blockId": "65", "textBlock": {"text": "Isn't it funny", "type": "paragraph"}, "pageSpan": {"pageStart": 5, "pageEnd": 5}}, {"blockId": "66", "textBlock": {"text": "a", "type": "paragraph"}, "pageSpan": {"pageStart": 5, "pageEnd": 5}}, {"blockId": "67", "textBlock": {"text": "little", "type": "paragraph"}, "pageSpan": {"pageStart": 5, "pageEnd": 5}}, {"blockId": "68", "textBlock": {"text": "song", "type": "paragraph"}, "pageSpan": {"pageStart": 5, "pageEnd": 5}}, {"blockId": "69", "textBlock": {"text": "to", "type": "paragraph"}, "pageSpan": {"pageStart": 5, "pageEnd": 5}}, {"blockId": "70", "textBlock": {"text": "himself.", "type": "paragraph"}, "pageSpan": {"pageStart": 5, "pageEnd": 5}}, {"blockId": "71", "textBlock": {"text": "It", "type": "paragraph"}, "pageSpan": {"pageStart": 5, "pageEnd": 5}}, {"blockId": "72", "textBlock": {"text": "went", "type": "paragraph"}, "pageSpan": {"pageStart": 5, "pageEnd": 5}}, {"blockId": "73", "textBlock": {"text": "like this:", "type": "paragraph"}, "pageSpan": {"pageStart": 5, "pageEnd": 5}}, {"blockId": "74", "textBlock": {"text": "How a bear likes honey? Buzz! Buzz! Buzz!", "type": "paragraph"}, "pageSpan": {"pageStart": 5, "pageEnd": 5}}, {"blockId": "75", "textBlock": {"text": "I wonder why he does?", "type": "paragraph"}, "pageSpan": {"pageStart": 5, "pageEnd": 5}}, {"blockId": "76", "textBlock": {"text": "Digitized by Google", "type": "paragraph"}, "pageSpan": {"pageStart": 5, "pageEnd": 5}}, {"blockId": "77", "textBlock": {"text": "6", "type": "paragraph"}, "pageSpan": {"pageStart": 6, "pageEnd": 6}}, {"blockId": "78", "textBlock": {"text": "WINNIE-THE-POOH", "type": "paragraph"}, "pageSpan": {"pageStart": 6, "pageEnd": 6}}, {"blockId": "79", "textBlock": {"text": "Then he climbed a little further and a little", "type": "paragraph"}, "pageSpan": {"pageStart": 6, "pageEnd": 6}}, {"blockId": "80", "textBlock": {"text": "...", "type": "paragraph"}, "pageSpan": {"pageStart": 6, "pageEnd": 6}}, {"blockId": "81", "textBlock": {"text": "...", "type": "paragraph"}, "pageSpan": {"pageStart": 6, "pageEnd": 6}}, {"blockId": "82", "textBlock": {"text": "further and then just a little further. By that time he had thought of another song.", "type": "paragraph"}, "pageSpan": {"pageStart": 6, "pageEnd": 6}}, {"blockId": "83", "textBlock": {"text": "It's a very funny thought that, if Bears were Bees, They'd build their nests at the bottom of trees. And that being so (if the Bees were Bears), We shouldn't have to climb up all these stairs.", "type": "paragraph"}, "pageSpan": {"pageStart": 6, "pageEnd": 6}}, {"blockId": "84", "textBlock": {"text": "He was getting rather tired by this time, so that is why he sang a Complain- ing Song. He was nearly there now, and if he just stood on that branch... Crack!", "type": "paragraph"}, "pageSpan": {"pageStart": 6, "pageEnd": 6}}, {"blockId": "85", "textBlock": {"text": "Digitized by Google", "type": "paragraph"}, "pageSpan": {"pageStart": 6, "pageEnd": 6}}, {"blockId": "86", "textBlock": {"text": "WE ARE INTRODUCED", "type": "paragraph"}, "pageSpan": {"pageStart": 7, "pageEnd": 7}}, {"blockId": "87", "textBlock": {"text": "7", "type": "paragraph"}, "pageSpan": {"pageStart": 7, "pageEnd": 7}}, {"blockId": "88", "textBlock": {"text": "\"Oh, help!\" said Pooh, as he dropped ten feet on the branch below him.", "type": "paragraph"}, "pageSpan": {"pageStart": 7, "pageEnd": 7}}, {"blockId": "89", "textBlock": {"text": "\"If only I hadn't--\" he said, as he bounced twenty feet on to the next branch.", "type": "paragraph"}, "pageSpan": {"pageStart": 7, "pageEnd": 7}}, {"blockId": "90", "textBlock": {"text": "\"You see, what I meant to do,\" he explained, as he turned head-over-heels, and crashed on to another branch thirty feet below, \"what I meant to do\u2014\u2014\u201d \"Of course, it was rather--\" he admitted, as he : 'ithered very quickly through the next six branches. \"It all comes, I suppose,\" he decided, as he said good-bye to the last branch, spun round three times, and flew gracefully into a gorse-bush, \"it all comes of liking honey so much. Oh, help!\"", "type": "paragraph"}, "pageSpan": {"pageStart": 7, "pageEnd": 7}}, {"blockId": "91", "textBlock": {"text": "He crawled out of the gorse-bush, brushed the prickles from his nose, and began to think again. And the first person he thought of was Christopher Robin.", "type": "paragraph"}, "pageSpan": {"pageStart": 7, "pageEnd": 7}}, {"blockId": "92", "textBlock": {"text": "Digitized by Google", "type": "paragraph"}, "pageSpan": {"pageStart": 7, "pageEnd": 7}}, {"blockId": "93", "textBlock": {"text": "8", "type": "header"}, "pageSpan": {"pageStart": 8, "pageEnd": 8}}]}, "pageSpan": {"pageStart": 5, "pageEnd": 8}}]}, "pageSpan": {"pageStart": 1, "pageEnd": 8}}, {"blockId": "94", "textBlock": {"text": "WINNIE-THE-POOH", "type": "heading-1", "blocks": [{"blockId": "95", "textBlock": {"text": "(\"Was that me?\" said Christopher Robin in an awed voice, hardly daring to believe it.", "type": "paragraph"}, "pageSpan": {"pageStart": 8, "pageEnd": 8}}, {"blockId": "96", "textBlock": {"text": "\u201cThat was you.\u201d", "type": "paragraph"}, "pageSpan": {"pageStart": 8, "pageEnd": 8}}, {"blockId": "97", "textBlock": {"text": "Christopher Robin said nothing, but his eyes got larger and larger, and his face got pinker and pinker.)", "type": "paragraph"}, "pageSpan": {"pageStart": 8, "pageEnd": 8}}, {"blockId": "98", "textBlock": {"text": "17", "type": "paragraph"}, "pageSpan": {"pageStart": 8, "pageEnd": 8}}, {"blockId": "99", "textBlock": {"text": "Digitized by Google", "type": "paragraph"}, "pageSpan": {"pageStart": 8, "pageEnd": 8}}, {"blockId": "100", "textBlock": {"text": "WE ARE INTRODUCED", "type": "paragraph"}, "pageSpan": {"pageStart": 9, "pageEnd": 9}}, {"blockId": "101", "textBlock": {"text": "9", "type": "paragraph"}, "pageSpan": {"pageStart": 9, "pageEnd": 9}}, {"blockId": "102", "textBlock": {"text": "So Winnie-the-Pooh went round to his friend Christopher Robin, who lived behind a green door in another part of the forest.", "type": "paragraph"}, "pageSpan": {"pageStart": 9, "pageEnd": 9}}, {"blockId": "103", "textBlock": {"text": "\"Good morning, Christopher Robin,\" he said.", "type": "paragraph"}, "pageSpan": {"pageStart": 9, "pageEnd": 9}}, {"blockId": "104", "textBlock": {"text": "\"Good morning, Winnie-ther-Pooh,\" said you.", "type": "paragraph"}, "pageSpan": {"pageStart": 9, "pageEnd": 9}}, {"blockId": "105", "textBlock": {"text": "Digitized by Google", "type": "paragraph"}, "pageSpan": {"pageStart": 9, "pageEnd": 9}}, {"blockId": "106", "textBlock": {"text": "10", "type": "paragraph"}, "pageSpan": {"pageStart": 10, "pageEnd": 10}}, {"blockId": "107", "textBlock": {"text": "WINNIE-THE-POOH", "type": "paragraph"}, "pageSpan": {"pageStart": 10, "pageEnd": 10}}, {"blockId": "108", "textBlock": {"text": "\"I wonder if you've got such a thing as a balloon", "type": "paragraph"}, "pageSpan": {"pageStart": 10, "pageEnd": 10}}, {"blockId": "109", "textBlock": {"text": "about you?\"", "type": "paragraph"}, "pageSpan": {"pageStart": 10, "pageEnd": 10}}, {"blockId": "110", "textBlock": {"text": "\"A balloon?\u201d", "type": "paragraph"}, "pageSpan": {"pageStart": 10, "pageEnd": 10}}, {"blockId": "111", "textBlock": {"text": "\"Yes, I just said to myself coming along: 'I won- der if Christopher Robin has such a thing as a bal- loon about him?' I just said it to myself, thinking of balloons, and wondering.\"", "type": "paragraph"}, "pageSpan": {"pageStart": 10, "pageEnd": 10}}, {"blockId": "112", "textBlock": {"text": "\"What do you want a balloon for?\" you said. Winnie-the-Pooh looked round to see that no- body was listening, put his paw to his mouth, and said in a deep whisper: \"Honey!\u201d", "type": "paragraph"}, "pageSpan": {"pageStart": 10, "pageEnd": 10}}, {"blockId": "113", "textBlock": {"text": "\"But you don't get honey with balloons!\" \"I do,\" said Pooh.", "type": "paragraph"}, "pageSpan": {"pageStart": 10, "pageEnd": 10}}, {"blockId": "114", "textBlock": {"text": "Well, it just happened that you had been to a party the day before at the house of your friend Piglet, and you had balloons at the party. You had", "type": "paragraph"}, "pageSpan": {"pageStart": 10, "pageEnd": 10}}, {"blockId": "115", "textBlock": {"text": "Digitized by Google", "type": "paragraph"}, "pageSpan": {"pageStart": 10, "pageEnd": 10}}, {"blockId": "116", "textBlock": {"text": "WE ARE INTRODUCED", "type": "paragraph"}, "pageSpan": {"pageStart": 11, "pageEnd": 11}}, {"blockId": "117", "textBlock": {"text": "II", "type": "header"}, "pageSpan": {"pageStart": 11, "pageEnd": 11}}, {"blockId": "118", "textBlock": {"text": "had a big green balloon; and one of Rabbit's rela- tions had had a big blue one, and had left it behind, being really too young to go to a party at all; and so you had brought the green one and the blue one home with you.", "type": "paragraph"}, "pageSpan": {"pageStart": 11, "pageEnd": 11}}, {"blockId": "119", "textBlock": {"text": "\"Which one would you like?\" you asked Pooh. He put his head between his paws and thought very carefully.", "type": "paragraph"}, "pageSpan": {"pageStart": 11, "pageEnd": 11}}, {"blockId": "120", "textBlock": {"text": "\"It's like this,\" he said. \"When you go after honey with a balloon, the great thing is not to let the bees know you're coming. Now, if you have a green balloon, they might think you were only part of the tree, and not notice you, and if you have a blue balloon, they might think you were only part of the sky, and not notice you, and the question is: Which is most likely?\"", "type": "paragraph"}, "pageSpan": {"pageStart": 11, "pageEnd": 11}}, {"blockId": "121", "textBlock": {"text": "\"Wouldn't they notice you underneath the bal- loon?\" you asked.", "type": "paragraph"}, "pageSpan": {"pageStart": 11, "pageEnd": 11}}, {"blockId": "122", "textBlock": {"text": "\"They might or they might not,\" said Winnie- the-Pooh. \"You never can tell with bees.\" He thought for a moment and said: \"I shall try to look like a small black cloud. That will deceive them.\"", "type": "paragraph"}, "pageSpan": {"pageStart": 11, "pageEnd": 11}}, {"blockId": "123", "textBlock": {"text": "Then you had better have the blue balloon,\" you said; and so it was decided. Well, you both went out with the blue balloon,", "type": "paragraph"}, "pageSpan": {"pageStart": 11, "pageEnd": 11}}, {"blockId": "124", "textBlock": {"text": "Digitized by Google", "type": "paragraph"}, "pageSpan": {"pageStart": 11, "pageEnd": 11}}, {"blockId": "125", "textBlock": {"text": "12", "type": "paragraph"}, "pageSpan": {"pageStart": 12, "pageEnd": 12}}, {"blockId": "126", "textBlock": {"text": "WINNIE-THE-POOH", "type": "header"}, "pageSpan": {"pageStart": 12, "pageEnd": 12}}, {"blockId": "127", "textBlock": {"text": "and you took your gun with you, just in case, as you always did, and Winnie-the-Pooh went to a very muddy place that he knew of, and rolled and", "type": "paragraph"}, "pageSpan": {"pageStart": 12, "pageEnd": 12}}, {"blockId": "128", "textBlock": {"text": "rolled until he was black all over; and then, when the balloon was blown up as big as big, and you and Pooh were both holding on to the string, you let go suddenly, and Pooh Bear floated gracefully up into the sky, and stayed there-level with the top of the tree and about twenty feet away from it.", "type": "paragraph"}, "pageSpan": {"pageStart": 12, "pageEnd": 12}}, {"blockId": "129", "textBlock": {"text": "\"Hooray!\" you shouted.", "type": "paragraph"}, "pageSpan": {"pageStart": 12, "pageEnd": 12}}, {"blockId": "130", "textBlock": {"text": "\"Isn't that fine?\" shouted Winnie-the-Pooh down to you. \"What do I look like?\"", "type": "paragraph"}, "pageSpan": {"pageStart": 12, "pageEnd": 12}}, {"blockId": "131", "textBlock": {"text": "\"You look like a Bear holding on to a balloon,\" you said.", "type": "paragraph"}, "pageSpan": {"pageStart": 12, "pageEnd": 12}}, {"blockId": "132", "textBlock": {"text": "\"Not,\" said Pooh anxiously, \"-not like a small black cloud in a blue sky?\"", "type": "paragraph"}, "pageSpan": {"pageStart": 12, "pageEnd": 12}}, {"blockId": "133", "textBlock": {"text": "\"Not very much.\"", "type": "paragraph"}, "pageSpan": {"pageStart": 12, "pageEnd": 12}}, {"blockId": "134", "textBlock": {"text": "\"Ah, well, perhaps from up here it looks different. And, as I say, you never can tell with bees.\"`", "type": "paragraph"}, "pageSpan": {"pageStart": 12, "pageEnd": 12}}, {"blockId": "135", "textBlock": {"text": "There was no wind to blow him nearer to the tree, so there he stayed. He could see the honey, he could smell the honey, but he couldn't quite reach the honey.", "type": "paragraph"}, "pageSpan": {"pageStart": 12, "pageEnd": 12}}, {"blockId": "136", "textBlock": {"text": "Digitized by Google", "type": "paragraph"}, "pageSpan": {"pageStart": 12, "pageEnd": 12}}, {"blockId": "137", "textBlock": {"text": "WE ARE INTRODUCED", "type": "paragraph"}, "pageSpan": {"pageStart": 13, "pageEnd": 13}}, {"blockId": "138", "textBlock": {"text": "After a little while he called down to you.", "type": "paragraph"}, "pageSpan": {"pageStart": 13, "pageEnd": 13}}, {"blockId": "139", "textBlock": {"text": "\"Christopher Robin!\" he said in a loud whisper.", "type": "paragraph"}, "pageSpan": {"pageStart": 13, "pageEnd": 13}}, {"blockId": "140", "textBlock": {"text": "\"Hallo!\"", "type": "paragraph"}, "pageSpan": {"pageStart": 13, "pageEnd": 13}}, {"blockId": "141", "textBlock": {"text": "\"I think the bees suspect something!\"", "type": "paragraph"}, "pageSpan": {"pageStart": 13, "pageEnd": 13}}, {"blockId": "142", "textBlock": {"text": "\"What sort of thing?\"", "type": "paragraph"}, "pageSpan": {"pageStart": 13, "pageEnd": 13}}, {"blockId": "143", "textBlock": {"text": "13", "type": "header"}, "pageSpan": {"pageStart": 13, "pageEnd": 13}}, {"blockId": "144", "textBlock": {"text": "\"I don't know. But something tells me that they're suspicious!\u201d", "type": "paragraph"}, "pageSpan": {"pageStart": 13, "pageEnd": 13}}, {"blockId": "145", "textBlock": {"text": "\"Perhaps they think that you're after their honey.\"", "type": "paragraph"}, "pageSpan": {"pageStart": 13, "pageEnd": 13}}, {"blockId": "146", "textBlock": {"text": "\"It may be that. You never can tell with bees.\"", "type": "paragraph"}, "pageSpan": {"pageStart": 13, "pageEnd": 13}}, {"blockId": "147", "textBlock": {"text": "There was another little silence, and then he called", "type": "paragraph"}, "pageSpan": {"pageStart": 13, "pageEnd": 13}}, {"blockId": "148", "textBlock": {"text": "down to you again.", "type": "paragraph"}, "pageSpan": {"pageStart": 13, "pageEnd": 13}}, {"blockId": "149", "textBlock": {"text": "\"Christopher Robin!\"", "type": "paragraph"}, "pageSpan": {"pageStart": 13, "pageEnd": 13}}, {"blockId": "150", "textBlock": {"text": "\"Yes?\"", "type": "paragraph"}, "pageSpan": {"pageStart": 13, "pageEnd": 13}}, {"blockId": "151", "textBlock": {"text": "\"Have you an umbrella in your house?\"", "type": "paragraph"}, "pageSpan": {"pageStart": 13, "pageEnd": 13}}, {"blockId": "152", "textBlock": {"text": "\"I think so.\"", "type": "paragraph"}, "pageSpan": {"pageStart": 13, "pageEnd": 13}}, {"blockId": "153", "textBlock": {"text": "\"I wish you would bring it out here, and walk up and down with it, and look up at me every now and then, and say 'Tut-tut, it looks like rain.' I think, if", "type": "paragraph"}, "pageSpan": {"pageStart": 13, "pageEnd": 13}}, {"blockId": "154", "textBlock": {"text": "Digitized by Google", "type": "paragraph"}, "pageSpan": {"pageStart": 13, "pageEnd": 13}}, {"blockId": "155", "textBlock": {"text": "14", "type": "paragraph"}, "pageSpan": {"pageStart": 14, "pageEnd": 14}}, {"blockId": "156", "textBlock": {"text": "WINNIE-THE-POOH", "type": "paragraph"}, "pageSpan": {"pageStart": 14, "pageEnd": 14}}, {"blockId": "157", "textBlock": {"text": "you did that, it would help the deception which we are practising on these bees.\"", "type": "paragraph"}, "pageSpan": {"pageStart": 14, "pageEnd": 14}}, {"blockId": "158", "textBlock": {"text": "Well, you laughed to yourself, \"Silly old Bear!\" but you didn't say it aloud because you were so fond of him, and you went home for your umbrella. \"Oh, there you are!\" called down Winnie-the- Pooh, as soon as you got back to the tree. \"I was beginning to get anxious. I have discovered that the bees are now definitely Suspicious.\"", "type": "paragraph"}, "pageSpan": {"pageStart": 14, "pageEnd": 14}}, {"blockId": "159", "textBlock": {"text": "\"Shall I put my umbrella up?\" you said.", "type": "paragraph"}, "pageSpan": {"pageStart": 14, "pageEnd": 14}}, {"blockId": "160", "textBlock": {"text": "\"Yes, but wait a moment. We must be practical. The important bee to deceive is the Queen Bee. Can you see which is the Queen Bee from down there?\"", "type": "paragraph"}, "pageSpan": {"pageStart": 14, "pageEnd": 14}}, {"blockId": "161", "textBlock": {"text": "\"No.\"", "type": "paragraph"}, "pageSpan": {"pageStart": 14, "pageEnd": 14}}, {"blockId": "162", "textBlock": {"text": "\"A pity. Well, now, if you walk up and down with your umbrella, saying, 'Tut-tut, it looks like rain,' I shall do what I can by singing a little Cloud Song, such as a cloud might sing. Go!\"", "type": "paragraph"}, "pageSpan": {"pageStart": 14, "pageEnd": 14}}, {"blockId": "163", "textBlock": {"text": "...", "type": "paragraph"}, "pageSpan": {"pageStart": 14, "pageEnd": 14}}, {"blockId": "164", "textBlock": {"text": "So, while you walked up and down and wondered", "type": "paragraph"}, "pageSpan": {"pageStart": 14, "pageEnd": 14}}, {"blockId": "165", "textBlock": {"text": "Digitized by Google", "type": "paragraph"}, "pageSpan": {"pageStart": 14, "pageEnd": 14}}, {"blockId": "166", "textBlock": {"text": "WE ARE INTRODUCED", "type": "paragraph"}, "pageSpan": {"pageStart": 15, "pageEnd": 15}}, {"blockId": "167", "textBlock": {"text": "15", "type": "paragraph"}, "pageSpan": {"pageStart": 15, "pageEnd": 15}}, {"blockId": "168", "textBlock": {"text": "if it would rain, Winnie-the-Pooh sang this song:", "type": "paragraph"}, "pageSpan": {"pageStart": 15, "pageEnd": 15}}, {"blockId": "169", "textBlock": {"text": "How sweet to be a Cloud", "type": "paragraph"}, "pageSpan": {"pageStart": 15, "pageEnd": 15}}, {"blockId": "170", "textBlock": {"text": "Floating in the Blue!", "type": "paragraph"}, "pageSpan": {"pageStart": 15, "pageEnd": 15}}, {"blockId": "171", "textBlock": {"text": "Every little cloud Always sings aloud.", "type": "paragraph"}, "pageSpan": {"pageStart": 15, "pageEnd": 15}}, {"blockId": "172", "textBlock": {"text": "**", "type": "paragraph"}, "pageSpan": {"pageStart": 15, "pageEnd": 15}}, {"blockId": "173", "textBlock": {"text": "\"How sweet to be a Cloud Floating in the Blue!\" It makes him very proud To be a little cloud.", "type": "paragraph"}, "pageSpan": {"pageStart": 15, "pageEnd": 15}}, {"blockId": "174", "textBlock": {"text": "The bees were still buzzing as suspiciously as ever. Some of them, indeed, left their nest and flew all round the cloud as it began the second verse of", "type": "paragraph"}, "pageSpan": {"pageStart": 15, "pageEnd": 15}}, {"blockId": "175", "textBlock": {"text": "Digitized by Google", "type": "paragraph"}, "pageSpan": {"pageStart": 15, "pageEnd": 15}}]}, "pageSpan": {"pageStart": 8, "pageEnd": 15}}]}, "chunkedDocument": {"chunks": [{"chunkId": "c1", "content": "# CHAPTER I\n\nIN WHICH We Are Introduced toWinnie-the-Pooh and SomeBees, and the Stories BeginHERELERE is Edward Bear, coming downstairs now, bump, bump, bump, on the back of his head, behind Christopher Robin. It is, as far as he knows, the only way of coming downstairs, but sometimes he feels that there really is another way, if only he could stop bumping for a moment and think of it. And then he feels that perhaps there isn't. Anyhow, here he is at the bottom, and ready to be introduced to you. Winnie-the-Pooh.When I first heard his name, I said, just as you are going to say, \"But I thought he was a boy?\" \"So did I,\" said Christopher Robin.\"Then you can't call him Winnie?\"6. \"I don't.\"\"But you said-\"\"He's Winnje-ther-Pooh. Don't you know what'ther' means?\"IDigitized by Google2WINNIE-THE-POOH\"Ah, yes, now I do,\" I said quickly; and I hope you do too, because it is all the explanation you are going to get.Sometimes Winnie-the-Pooh likes a game of some sort when he comes downstairs, and sometimes he likes to sit quietly in front of the fire and listen to a story. This evening--\"What about a story?\" said Christopher Robin. \"What about a story?\" I said.\"Could you very sweetly tell Winnie-the-Pooh one?\"\"I suppose I could,\" I said. \"What sort of stories does he like?\"\"About himself. Because he's that sort of Bear.\" \"Oh, I see.\"\"So could you very sweetly?\"\"I'll try,\" I said.So I triedOnce upon a time, a very long time ago now, about last Friday, Winnie-the-Pooh lived in a forest all by himself under the name of Sanders.(\"What does 'under the name mean?\" asked Christopher Robin.\"It means he had the name over the door in gold letters, and lived under it.\"Digitized by GoogleWE ARE INTRODUCEDARNIG ALSOAB SAUDERZ\"Winnie-the-Pooh wasn't quite sure,\" said Chris- topher Robin.\u201cNow I am,\u201d said a growly voice.\"Then I will go on,\" said I.)One day when he was out walking, he came to an open place in the middle of the forest, and in the middle of this place was a large oak-tree, and, from the top of the tree, there came a loud buzzing-noise.Winnie-the-Pooh sat down at the foot of the tree, put his head between his paws and began to think.Digitized by Google4*WINNIE-THE-POOHFirst of all he said to himself: \"That buzzing- noise means something. You don't get a buzzing- noise like that, just buzzing and buzzing, without its meaning something. If there's a buzzing-noise, somebody's making a buzzing-noise, and the only reason for making a buzzing-noise that I know of is because you're a bee.\"Then he thought another long time, and said: \"And the only reason for being a bee that I know of is making honey.\"And then he got up, and said: \"And the only reason for making honey is so as I can eat it.\" So he began to climb the tree.Digitized by Google\n\n## WE ARE INTRODUCED\n\nHeclimbedandheclimbedandheclimbed,\u0995andasheclimbedhesang57Isn't it funnyalittlesongtohimself.Itwentlike this:How a bear likes honey? Buzz! Buzz! Buzz!I wonder why he does?Digitized by Google6WINNIE-THE-POOHThen he climbed a little further and a little......further and then just a little further. By that time he had thought of another song.It's a very funny thought that, if Bears were Bees, They'd build their nests at the bottom of trees. And that being so (if the Bees were Bears), We shouldn't have to climb up all these stairs.He was getting rather tired by this time, so that is why he sang a Complain- ing Song. He was nearly there now, and if he just stood on that branch... Crack!Digitized by GoogleWE ARE INTRODUCED7\"Oh, help!\" said Pooh, as he dropped ten feet on the branch below him.\"If only I hadn't--\" he said, as he bounced twenty feet on to the next branch.\"You see, what I meant to do,\" he explained, as he turned head-over-heels, and crashed on to another branch thirty feet below, \"what I meant to do\u2014\u2014\u201d \"Of course, it was rather--\" he admitted, as he : 'ithered very quickly through the next six branches. \"It all comes, I suppose,\" he decided, as he said good-bye to the last branch, spun round three times, and flew gracefully into a gorse-bush, \"it all comes of liking honey so much. Oh, help!\"He crawled out of the gorse-bush, brushed the prickles from his nose, and began to think again. And the first person he thought of was Christopher Robin.Digitized by Google", "pageSpan": {"pageStart": 1, "pageEnd": 8}, "pageHeaders": [{"text": "3", "pageSpan": {"pageStart": 3, "pageEnd": 3}}, {"text": "8", "pageSpan": {"pageStart": 8, "pageEnd": 8}}]}, {"chunkId": "c2", "content": "# WINNIE-THE-POOH\n\n(\"Was that me?\" said Christopher Robin in an awed voice, hardly daring to believe it.\u201cThat was you.\u201dChristopher Robin said nothing, but his eyes got larger and larger, and his face got pinker and pinker.)17Digitized by GoogleWE ARE INTRODUCED9So Winnie-the-Pooh went round to his friend Christopher Robin, who lived behind a green door in another part of the forest.\"Good morning, Christopher Robin,\" he said.\"Good morning, Winnie-ther-Pooh,\" said you.Digitized by Google10WINNIE-THE-POOH\"I wonder if you've got such a thing as a balloonabout you?\"\"A balloon?\u201d\"Yes, I just said to myself coming along: 'I won- der if Christopher Robin has such a thing as a bal- loon about him?' I just said it to myself, thinking of balloons, and wondering.\"\"What do you want a balloon for?\" you said. Winnie-the-Pooh looked round to see that no- body was listening, put his paw to his mouth, and said in a deep whisper: \"Honey!\u201d\"But you don't get honey with balloons!\" \"I do,\" said Pooh.Well, it just happened that you had been to a party the day before at the house of your friend Piglet, and you had balloons at the party. You hadDigitized by GoogleWE ARE INTRODUCEDhad a big green balloon; and one of Rabbit's rela- tions had had a big blue one, and had left it behind, being really too young to go to a party at all; and so you had brought the green one and the blue one home with you.\"Which one would you like?\" you asked Pooh. He put his head between his paws and thought very carefully.\"It's like this,\" he said. \"When you go after honey with a balloon, the great thing is not to let the bees know you're coming. Now, if you have a green balloon, they might think you were only part of the tree, and not notice you, and if you have a blue balloon, they might think you were only part of the sky, and not notice you, and the question is: Which is most likely?\"\"Wouldn't they notice you underneath the bal- loon?\" you asked.\"They might or they might not,\" said Winnie- the-Pooh. \"You never can tell with bees.\" He thought for a moment and said: \"I shall try to look like a small black cloud. That will deceive them.\"Then you had better have the blue balloon,\" you said; and so it was decided. Well, you both went out with the blue balloon,Digitized by Google12and you took your gun with you, just in case, as you always did, and Winnie-the-Pooh went to a very muddy place that he knew of, and rolled androlled until he was black all over; and then, when the balloon was blown up as big as big, and you and Pooh were both holding on to the string, you let go suddenly, and Pooh Bear floated gracefully up into the sky, and stayed there-level with the top of the tree and about twenty feet away from it.\"Hooray!\" you shouted.\"Isn't that fine?\" shouted Winnie-the-Pooh down to you. \"What do I look like?\"\"You look like a Bear holding on to a balloon,\" you said.\"Not,\" said Pooh anxiously, \"-not like a small black cloud in a blue sky?\"\"Not very much.\"\"Ah, well, perhaps from up here it looks different. And, as I say, you never can tell with bees.\"`There was no wind to blow him nearer to the tree, so there he stayed. He could see the honey, he could smell the honey, but he couldn't quite reach the honey.Digitized by GoogleWE ARE INTRODUCEDAfter a little while he called down to you.\"Christopher Robin!\" he said in a loud whisper.\"Hallo!\"\"I think the bees suspect something!\"\"What sort of thing?\"\"I don't know. But something tells me that they're suspicious!\u201d\"Perhaps they think that you're after their honey.\"\"It may be that. You never can tell with bees.\"There was another little silence, and then he calleddown to you again.\"Christopher Robin!\"\"Yes?\"\"Have you an umbrella in your house?\"\"I think so.\"\"I wish you would bring it out here, and walk up and down with it, and look up at me every now and then, and say 'Tut-tut, it looks like rain.' I think, ifDigitized by Google14WINNIE-THE-POOHyou did that, it would help the deception which we are practising on these bees.\"Well, you laughed to yourself, \"Silly old Bear!\" but you didn't say it aloud because you were so fond of him, and you went home for your umbrella. \"Oh, there you are!\" called down Winnie-the- Pooh, as soon as you got back to the tree. \"I was beginning to get anxious. I have discovered that the bees are now definitely Suspicious.\"\"Shall I put my umbrella up?\" you said.\"Yes, but wait a moment. We must be practical. The important bee to deceive is the Queen Bee. Can you see which is the Queen Bee from down there?\"\"No.\"\"A pity. Well, now, if you walk up and down with your umbrella, saying, 'Tut-tut, it looks like rain,' I shall do what I can by singing a little Cloud Song, such as a cloud might sing. Go!\"...So, while you walked up and down and wonderedDigitized by GoogleWE ARE INTRODUCED15if it would rain, Winnie-the-Pooh sang this song:How sweet to be a CloudFloating in the Blue!Every little cloud Always sings aloud.**\"How sweet to be a Cloud Floating in the Blue!\" It makes him very proud To be a little cloud.The bees were still buzzing as suspiciously as ever. Some of them, indeed, left their nest and flew all round the cloud as it began the second verse ofDigitized by Google", "pageSpan": {"pageStart": 8, "pageEnd": 15}, "pageHeaders": [{"text": "8", "pageSpan": {"pageStart": 8, "pageEnd": 8}}, {"text": "II", "pageSpan": {"pageStart": 11, "pageEnd": 11}}, {"text": "WINNIE-THE-POOH", "pageSpan": {"pageStart": 12, "pageEnd": 12}}, {"text": "13", "pageSpan": {"pageStart": 13, "pageEnd": 13}}]}]}} \ No newline at end of file diff --git a/tests/unit/test_document.py b/tests/unit/test_document.py index 286a482d..21885ed0 100644 --- a/tests/unit/test_document.py +++ b/tests/unit/test_document.py @@ -14,19 +14,13 @@ # See the License for the specific language governing permissions and # limitations under the License. +import glob import json import os import shutil +from unittest import mock from xml.etree import ElementTree -# try/except added for compatibility with python < 3.8 -try: - from unittest import mock -except ImportError: # pragma: NO COVER - import mock - -import glob - from google.cloud.vision import AnnotateFileResponse import pytest @@ -85,6 +79,13 @@ def get_bytes_splitter_mock(): yield byte_factory +@pytest.fixture +def get_bytes_classifier_mock(): + with mock.patch.object(gcs_utilities, "get_bytes") as byte_factory: + byte_factory.return_value = get_bytes("tests/unit/resources/classifier") + yield byte_factory + + @pytest.fixture def get_bytes_images_mock(): with mock.patch.object(gcs_utilities, "get_bytes") as byte_factory: @@ -212,6 +213,30 @@ def test_entities_from_shards_with_hex_ids(): assert actual[1].type_ == "class_international" +def test_entities_from_shards_classifier(get_bytes_classifier_mock): + shards = document._get_shards( + gcs_bucket_name="test-directory", gcs_prefix="documentai/output/123456789/0/" + ) + get_bytes_classifier_mock.assert_called_once() + + actual = document._entities_from_shards(shards=shards) + + # Check for error reported in https://github.com/googleapis/python-documentai-toolbox/issues/332 + assert repr(actual) + assert actual[0].type_ == "computer_vision" + assert round(actual[0].documentai_object.confidence, 8) == 0.47925246 + assert actual[0].documentai_object.id == "0" + assert actual[1].type_ == "crypto" + assert round(actual[1].documentai_object.confidence, 8) == 0.0433604 + assert actual[1].documentai_object.id == "1" + assert actual[2].type_ == "med_tech" + assert round(actual[2].documentai_object.confidence, 8) == 0.26732057 + assert actual[2].documentai_object.id == "2" + assert actual[3].type_ == "other" + assert round(actual[3].documentai_object.confidence, 8) == 0.2100666 + assert actual[3].documentai_object.id == "3" + + @mock.patch("google.cloud.documentai_toolbox.wrappers.document.documentai") def test_get_batch_process_metadata_with_valid_operation( mock_docai, @@ -370,6 +395,46 @@ def test_document_from_documentai_document_with_single_shard(): assert len(actual.text) > 0 +def test_document_from_documentai_document_layout_parser(): + with open( + "tests/unit/resources/layout_parser/layout_parser.json", "r", encoding="utf-8" + ) as f: + doc = documentai.Document.from_json(f.read()) + + actual = document.Document.from_documentai_document(documentai_document=doc) + + chunk_list = list(actual.chunks) + assert len(chunk_list) == 2 + assert chunk_list[0].chunk_id == "c1" + assert "CHAPTER I" in chunk_list[0].content + assert chunk_list[0].page_span.page_start == 1 + assert chunk_list[0].page_span.page_end == 8 + + assert chunk_list[1].chunk_id == "c2" + assert "Was that me?" in chunk_list[1].content + assert chunk_list[1].page_span.page_start == 8 + assert chunk_list[1].page_span.page_end == 15 + + block_list = list(actual.document_layout_blocks) + + for i, block in enumerate(block_list, start=1): + assert int(block.block_id) == i + + assert len(block_list) == 175 + assert block_list[0].block_id == "1" + assert block_list[0].text_block.text == "CHAPTER I" + assert block_list[0].text_block.type_ == "heading-1" + assert block_list[0].text_block.blocks + assert block_list[0].page_span.page_start == 1 + assert block_list[0].page_span.page_end == 8 + + assert block_list[1].block_id == "2" + assert block_list[1].text_block.text == "IN WHICH We Are Introduced to" + assert block_list[1].text_block.type_ == "paragraph" + assert block_list[1].page_span.page_start == 1 + assert block_list[1].page_span.page_end == 1 + + def test_document_from_gcs_with_single_shard(get_bytes_single_file_mock): actual = document.Document.from_gcs( gcs_bucket_name="test-directory", gcs_prefix="documentai/output/123456789/0/" @@ -709,6 +774,22 @@ def test_split_pdf(mock_Pdf, get_bytes_splitter_mock): ] +def test_split_pdf_with_non_splitter(get_bytes_classifier_mock): + doc = document.Document.from_gcs( + gcs_bucket_name="test-directory", gcs_prefix="documentai/output/123456789/0" + ) + + with pytest.raises( + ValueError, + match="Entities do not contain start or end pages.", + ): + doc.split_pdf( + pdf_path="procurement_multi_document.pdf", output_path="splitter/output/" + ) + + get_bytes_classifier_mock.assert_called_once() + + def test_convert_document_to_annotate_file_response(): doc = document.Document.from_document_path( document_path="tests/unit/resources/0/toolbox_invoice_test-0.json" diff --git a/tests/unit/test_entity.py b/tests/unit/test_entity.py index c382d4e8..148d66c0 100644 --- a/tests/unit/test_entity.py +++ b/tests/unit/test_entity.py @@ -68,6 +68,21 @@ def test_Entity_splitter(): assert wrapper_entity.end_page == 2 +def test_Entity_classifier(): + documentai_entity = documentai.Document.Entity( + type_="clinical_notes", + id="0", + confidence=0.99878639, + ) + wrapper_entity = entity.Entity(documentai_entity) + assert wrapper_entity.type_ == "clinical_notes" + assert wrapper_entity.documentai_object.id == "0" + assert round(wrapper_entity.documentai_object.confidence, 8) == 0.99878639 + assert not wrapper_entity.mention_text + assert not wrapper_entity.start_page + assert not wrapper_entity.end_page + + def test_Entity_with_page_offset(): documentai_entity = documentai.Document.Entity( type_="invoice_statement", diff --git a/tests/unit/test_gcs_utilities.py b/tests/unit/test_gcs_utilities.py index e0815aca..dc85aaff 100644 --- a/tests/unit/test_gcs_utilities.py +++ b/tests/unit/test_gcs_utilities.py @@ -13,18 +13,13 @@ # See the License for the specific language governing permissions and # limitations under the License. +from unittest import mock + import pytest from google.cloud import storage from google.cloud.documentai_toolbox import gcs_utilities -# try/except added for compatibility with python < 3.8 -try: - from unittest import mock -except ImportError: # pragma: NO COVER - import mock - - test_bucket = "test-directory" test_prefix = "documentai/input"