diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0a5b56e..0b26bf2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ jobs: - name: Set up python uses: actions/setup-python@v4 with: - python-version: 3.7 + python-version: 3.8 - name: Bootstrap poetry run: | curl -sSL https://install.python-poetry.org | python - -y --version 1.5.1 @@ -26,7 +26,7 @@ jobs: - name: Set up python uses: actions/setup-python@v4 with: - python-version: 3.7 + python-version: 3.8 - name: Bootstrap poetry run: | curl -sSL https://install.python-poetry.org | python - -y --version 1.5.1 @@ -45,7 +45,7 @@ jobs: - name: Set up python uses: actions/setup-python@v4 with: - python-version: 3.7 + python-version: 3.8 - name: Bootstrap poetry run: | curl -sSL https://install.python-poetry.org | python - -y --version 1.5.1 diff --git a/poetry.lock b/poetry.lock index 96df000..3d5f62f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,14 +1,14 @@ -# This file is automatically @generated by Poetry 1.7.0 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.1 and should not be changed by hand. [[package]] name = "annotated-types" -version = "0.5.0" +version = "0.6.0" description = "Reusable constraint types to use with typing.Annotated" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "annotated_types-0.5.0-py3-none-any.whl", hash = "sha256:58da39888f92c276ad970249761ebea80ba544b77acddaa1a4d6cf78287d45fd"}, - {file = "annotated_types-0.5.0.tar.gz", hash = "sha256:47cdc3490d9ac1506ce92c7aaa76c579dc3509ff11e098fc867e5130ab7be802"}, + {file = "annotated_types-0.6.0-py3-none-any.whl", hash = "sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43"}, + {file = "annotated_types-0.6.0.tar.gz", hash = "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d"}, ] [package.dependencies] @@ -16,35 +16,35 @@ typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.9\""} [[package]] name = "anyio" -version = "3.7.1" +version = "4.3.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "anyio-3.7.1-py3-none-any.whl", hash = "sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5"}, - {file = "anyio-3.7.1.tar.gz", hash = "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780"}, + {file = "anyio-4.3.0-py3-none-any.whl", hash = "sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8"}, + {file = "anyio-4.3.0.tar.gz", hash = "sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6"}, ] [package.dependencies] -exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} +exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = "*", markers = "python_version < \"3.8\""} +typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} [package.extras] -doc = ["Sphinx", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme (>=1.2.2)", "sphinxcontrib-jquery"] -test = ["anyio[trio]", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] -trio = ["trio (<0.22)"] +doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] +trio = ["trio (>=0.23)"] [[package]] name = "certifi" -version = "2023.11.17" +version = "2024.2.2" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2023.11.17-py3-none-any.whl", hash = "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474"}, - {file = "certifi-2023.11.17.tar.gz", hash = "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1"}, + {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, + {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, ] [[package]] @@ -83,44 +83,42 @@ files = [ {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, ] -[package.dependencies] -typing-extensions = {version = "*", markers = "python_version < \"3.8\""} - [[package]] name = "httpcore" -version = "0.17.3" +version = "1.0.4" description = "A minimal low-level HTTP client." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "httpcore-0.17.3-py3-none-any.whl", hash = "sha256:c2789b767ddddfa2a5782e3199b2b7f6894540b17b16ec26b2c4d8e103510b87"}, - {file = "httpcore-0.17.3.tar.gz", hash = "sha256:a6f30213335e34c1ade7be6ec7c47f19f50c56db36abef1a9dfa3815b1cb3888"}, + {file = "httpcore-1.0.4-py3-none-any.whl", hash = "sha256:ac418c1db41bade2ad53ae2f3834a3a0f5ae76b56cf5aa497d2d033384fc7d73"}, + {file = "httpcore-1.0.4.tar.gz", hash = "sha256:cb2839ccfcba0d2d3c1131d3c3e26dfc327326fbe7a5dc0dbfe9f6c9151bb022"}, ] [package.dependencies] -anyio = ">=3.0,<5.0" certifi = "*" h11 = ">=0.13,<0.15" -sniffio = "==1.*" [package.extras] +asyncio = ["anyio (>=4.0,<5.0)"] http2 = ["h2 (>=3,<5)"] socks = ["socksio (==1.*)"] +trio = ["trio (>=0.22.0,<0.25.0)"] [[package]] name = "httpx" -version = "0.24.1" +version = "0.27.0" description = "The next generation HTTP client." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "httpx-0.24.1-py3-none-any.whl", hash = "sha256:06781eb9ac53cde990577af654bd990a4949de37a28bdb4a230d434f3a30b9bd"}, - {file = "httpx-0.24.1.tar.gz", hash = "sha256:5853a43053df830c20f8110c5e69fe44d035d850b2dfe795e196f00fdb774bdd"}, + {file = "httpx-0.27.0-py3-none-any.whl", hash = "sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5"}, + {file = "httpx-0.27.0.tar.gz", hash = "sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5"}, ] [package.dependencies] +anyio = "*" certifi = "*" -httpcore = ">=0.15.0,<0.18.0" +httpcore = "==1.*" idna = "*" sniffio = "*" @@ -141,26 +139,6 @@ files = [ {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, ] -[[package]] -name = "importlib-metadata" -version = "6.7.0" -description = "Read metadata from Python packages" -optional = false -python-versions = ">=3.7" -files = [ - {file = "importlib_metadata-6.7.0-py3-none-any.whl", hash = "sha256:cb52082e659e97afc5dac71e79de97d8681de3aa07ff18578330904a9d18e5b5"}, - {file = "importlib_metadata-6.7.0.tar.gz", hash = "sha256:1aaf550d4f73e5d6783e7acb77aec43d49da8017410afae93822cc9cca98c4d4"}, -] - -[package.dependencies] -typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} -zipp = ">=0.5" - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -perf = ["ipython"] -testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] - [[package]] name = "iniconfig" version = "2.0.0" @@ -174,45 +152,49 @@ files = [ [[package]] name = "mypy" -version = "0.971" +version = "1.9.0" description = "Optional static typing for Python" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "mypy-0.971-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f2899a3cbd394da157194f913a931edfd4be5f274a88041c9dc2d9cdcb1c315c"}, - {file = "mypy-0.971-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:98e02d56ebe93981c41211c05adb630d1d26c14195d04d95e49cd97dbc046dc5"}, - {file = "mypy-0.971-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:19830b7dba7d5356d3e26e2427a2ec91c994cd92d983142cbd025ebe81d69cf3"}, - {file = "mypy-0.971-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:02ef476f6dcb86e6f502ae39a16b93285fef97e7f1ff22932b657d1ef1f28655"}, - {file = "mypy-0.971-cp310-cp310-win_amd64.whl", hash = "sha256:25c5750ba5609a0c7550b73a33deb314ecfb559c350bb050b655505e8aed4103"}, - {file = "mypy-0.971-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d3348e7eb2eea2472db611486846742d5d52d1290576de99d59edeb7cd4a42ca"}, - {file = "mypy-0.971-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3fa7a477b9900be9b7dd4bab30a12759e5abe9586574ceb944bc29cddf8f0417"}, - {file = "mypy-0.971-cp36-cp36m-win_amd64.whl", hash = "sha256:2ad53cf9c3adc43cf3bea0a7d01a2f2e86db9fe7596dfecb4496a5dda63cbb09"}, - {file = "mypy-0.971-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:855048b6feb6dfe09d3353466004490b1872887150c5bb5caad7838b57328cc8"}, - {file = "mypy-0.971-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:23488a14a83bca6e54402c2e6435467a4138785df93ec85aeff64c6170077fb0"}, - {file = "mypy-0.971-cp37-cp37m-win_amd64.whl", hash = "sha256:4b21e5b1a70dfb972490035128f305c39bc4bc253f34e96a4adf9127cf943eb2"}, - {file = "mypy-0.971-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:9796a2ba7b4b538649caa5cecd398d873f4022ed2333ffde58eaf604c4d2cb27"}, - {file = "mypy-0.971-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5a361d92635ad4ada1b1b2d3630fc2f53f2127d51cf2def9db83cba32e47c856"}, - {file = "mypy-0.971-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b793b899f7cf563b1e7044a5c97361196b938e92f0a4343a5d27966a53d2ec71"}, - {file = "mypy-0.971-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d1ea5d12c8e2d266b5fb8c7a5d2e9c0219fedfeb493b7ed60cd350322384ac27"}, - {file = "mypy-0.971-cp38-cp38-win_amd64.whl", hash = "sha256:23c7ff43fff4b0df93a186581885c8512bc50fc4d4910e0f838e35d6bb6b5e58"}, - {file = "mypy-0.971-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:1f7656b69974a6933e987ee8ffb951d836272d6c0f81d727f1d0e2696074d9e6"}, - {file = "mypy-0.971-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d2022bfadb7a5c2ef410d6a7c9763188afdb7f3533f22a0a32be10d571ee4bbe"}, - {file = "mypy-0.971-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef943c72a786b0f8d90fd76e9b39ce81fb7171172daf84bf43eaf937e9f220a9"}, - {file = "mypy-0.971-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d744f72eb39f69312bc6c2abf8ff6656973120e2eb3f3ec4f758ed47e414a4bf"}, - {file = "mypy-0.971-cp39-cp39-win_amd64.whl", hash = "sha256:77a514ea15d3007d33a9e2157b0ba9c267496acf12a7f2b9b9f8446337aac5b0"}, - {file = "mypy-0.971-py3-none-any.whl", hash = "sha256:0d054ef16b071149917085f51f89555a576e2618d5d9dd70bd6eea6410af3ac9"}, - {file = "mypy-0.971.tar.gz", hash = "sha256:40b0f21484238269ae6a57200c807d80debc6459d444c0489a102d7c6a75fa56"}, + {file = "mypy-1.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f8a67616990062232ee4c3952f41c779afac41405806042a8126fe96e098419f"}, + {file = "mypy-1.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d357423fa57a489e8c47b7c85dfb96698caba13d66e086b412298a1a0ea3b0ed"}, + {file = "mypy-1.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49c87c15aed320de9b438ae7b00c1ac91cd393c1b854c2ce538e2a72d55df150"}, + {file = "mypy-1.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:48533cdd345c3c2e5ef48ba3b0d3880b257b423e7995dada04248725c6f77374"}, + {file = "mypy-1.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:4d3dbd346cfec7cb98e6cbb6e0f3c23618af826316188d587d1c1bc34f0ede03"}, + {file = "mypy-1.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:653265f9a2784db65bfca694d1edd23093ce49740b2244cde583aeb134c008f3"}, + {file = "mypy-1.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3a3c007ff3ee90f69cf0a15cbcdf0995749569b86b6d2f327af01fd1b8aee9dc"}, + {file = "mypy-1.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2418488264eb41f69cc64a69a745fad4a8f86649af4b1041a4c64ee61fc61129"}, + {file = "mypy-1.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:68edad3dc7d70f2f17ae4c6c1b9471a56138ca22722487eebacfd1eb5321d612"}, + {file = "mypy-1.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:85ca5fcc24f0b4aeedc1d02f93707bccc04733f21d41c88334c5482219b1ccb3"}, + {file = "mypy-1.9.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aceb1db093b04db5cd390821464504111b8ec3e351eb85afd1433490163d60cd"}, + {file = "mypy-1.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0235391f1c6f6ce487b23b9dbd1327b4ec33bb93934aa986efe8a9563d9349e6"}, + {file = "mypy-1.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4d5ddc13421ba3e2e082a6c2d74c2ddb3979c39b582dacd53dd5d9431237185"}, + {file = "mypy-1.9.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:190da1ee69b427d7efa8aa0d5e5ccd67a4fb04038c380237a0d96829cb157913"}, + {file = "mypy-1.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:fe28657de3bfec596bbeef01cb219833ad9d38dd5393fc649f4b366840baefe6"}, + {file = "mypy-1.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e54396d70be04b34f31d2edf3362c1edd023246c82f1730bbf8768c28db5361b"}, + {file = "mypy-1.9.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5e6061f44f2313b94f920e91b204ec600982961e07a17e0f6cd83371cb23f5c2"}, + {file = "mypy-1.9.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81a10926e5473c5fc3da8abb04119a1f5811a236dc3a38d92015cb1e6ba4cb9e"}, + {file = "mypy-1.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b685154e22e4e9199fc95f298661deea28aaede5ae16ccc8cbb1045e716b3e04"}, + {file = "mypy-1.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:5d741d3fc7c4da608764073089e5f58ef6352bedc223ff58f2f038c2c4698a89"}, + {file = "mypy-1.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:587ce887f75dd9700252a3abbc9c97bbe165a4a630597845c61279cf32dfbf02"}, + {file = "mypy-1.9.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f88566144752999351725ac623471661c9d1cd8caa0134ff98cceeea181789f4"}, + {file = "mypy-1.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61758fabd58ce4b0720ae1e2fea5cfd4431591d6d590b197775329264f86311d"}, + {file = "mypy-1.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e49499be624dead83927e70c756970a0bc8240e9f769389cdf5714b0784ca6bf"}, + {file = "mypy-1.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:571741dc4194b4f82d344b15e8837e8c5fcc462d66d076748142327626a1b6e9"}, + {file = "mypy-1.9.0-py3-none-any.whl", hash = "sha256:a260627a570559181a9ea5de61ac6297aa5af202f06fd7ab093ce74e7181e43e"}, + {file = "mypy-1.9.0.tar.gz", hash = "sha256:3cc5da0127e6a478cddd906068496a97a7618a21ce9b54bde5bf7e539c7af974"}, ] [package.dependencies] -mypy-extensions = ">=0.4.3" +mypy-extensions = ">=1.0.0" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typed-ast = {version = ">=1.4.0,<2", markers = "python_version < \"3.8\""} -typing-extensions = ">=3.10" +typing-extensions = ">=4.1.0" [package.extras] dmypy = ["psutil (>=4.0)"] -python2 = ["typed-ast (>=1.4.0,<2)"] +install-types = ["pip"] +mypyc = ["setuptools (>=50)"] reports = ["lxml"] [[package]] @@ -228,47 +210,44 @@ files = [ [[package]] name = "packaging" -version = "23.2" +version = "24.0" description = "Core utilities for Python packages" optional = false python-versions = ">=3.7" files = [ - {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, - {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, + {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, + {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, ] [[package]] name = "pluggy" -version = "1.2.0" +version = "1.4.0" description = "plugin and hook calling mechanisms for python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pluggy-1.2.0-py3-none-any.whl", hash = "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849"}, - {file = "pluggy-1.2.0.tar.gz", hash = "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3"}, + {file = "pluggy-1.4.0-py3-none-any.whl", hash = "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981"}, + {file = "pluggy-1.4.0.tar.gz", hash = "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be"}, ] -[package.dependencies] -importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} - [package.extras] dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] [[package]] name = "pydantic" -version = "2.4.2" +version = "2.6.4" description = "Data validation using Python type hints" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pydantic-2.4.2-py3-none-any.whl", hash = "sha256:bc3ddf669d234f4220e6e1c4d96b061abe0998185a8d7855c0126782b7abc8c1"}, - {file = "pydantic-2.4.2.tar.gz", hash = "sha256:94f336138093a5d7f426aac732dcfe7ab4eb4da243c88f891d65deb4a2556ee7"}, + {file = "pydantic-2.6.4-py3-none-any.whl", hash = "sha256:cc46fce86607580867bdc3361ad462bab9c222ef042d3da86f2fb333e1d916c5"}, + {file = "pydantic-2.6.4.tar.gz", hash = "sha256:b1704e0847db01817624a6b86766967f552dd9dbf3afba4004409f908dcc84e6"}, ] [package.dependencies] annotated-types = ">=0.4.0" -pydantic-core = "2.10.1" +pydantic-core = "2.16.3" typing-extensions = ">=4.6.1" [package.extras] @@ -276,117 +255,90 @@ email = ["email-validator (>=2.0.0)"] [[package]] name = "pydantic-core" -version = "2.10.1" +version = "2.16.3" description = "" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.10.1-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:d64728ee14e667ba27c66314b7d880b8eeb050e58ffc5fec3b7a109f8cddbd63"}, - {file = "pydantic_core-2.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:48525933fea744a3e7464c19bfede85df4aba79ce90c60b94d8b6e1eddd67096"}, - {file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef337945bbd76cce390d1b2496ccf9f90b1c1242a3a7bc242ca4a9fc5993427a"}, - {file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a1392e0638af203cee360495fd2cfdd6054711f2db5175b6e9c3c461b76f5175"}, - {file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0675ba5d22de54d07bccde38997e780044dcfa9a71aac9fd7d4d7a1d2e3e65f7"}, - {file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:128552af70a64660f21cb0eb4876cbdadf1a1f9d5de820fed6421fa8de07c893"}, - {file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f6e6aed5818c264412ac0598b581a002a9f050cb2637a84979859e70197aa9e"}, - {file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ecaac27da855b8d73f92123e5f03612b04c5632fd0a476e469dfc47cd37d6b2e"}, - {file = "pydantic_core-2.10.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b3c01c2fb081fced3bbb3da78510693dc7121bb893a1f0f5f4b48013201f362e"}, - {file = "pydantic_core-2.10.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:92f675fefa977625105708492850bcbc1182bfc3e997f8eecb866d1927c98ae6"}, - {file = "pydantic_core-2.10.1-cp310-none-win32.whl", hash = "sha256:420a692b547736a8d8703c39ea935ab5d8f0d2573f8f123b0a294e49a73f214b"}, - {file = "pydantic_core-2.10.1-cp310-none-win_amd64.whl", hash = "sha256:0880e239827b4b5b3e2ce05e6b766a7414e5f5aedc4523be6b68cfbc7f61c5d0"}, - {file = "pydantic_core-2.10.1-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:073d4a470b195d2b2245d0343569aac7e979d3a0dcce6c7d2af6d8a920ad0bea"}, - {file = "pydantic_core-2.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:600d04a7b342363058b9190d4e929a8e2e715c5682a70cc37d5ded1e0dd370b4"}, - {file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39215d809470f4c8d1881758575b2abfb80174a9e8daf8f33b1d4379357e417c"}, - {file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eeb3d3d6b399ffe55f9a04e09e635554012f1980696d6b0aca3e6cf42a17a03b"}, - {file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a7a7902bf75779bc12ccfc508bfb7a4c47063f748ea3de87135d433a4cca7a2f"}, - {file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3625578b6010c65964d177626fde80cf60d7f2e297d56b925cb5cdeda6e9925a"}, - {file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:caa48fc31fc7243e50188197b5f0c4228956f97b954f76da157aae7f67269ae8"}, - {file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:07ec6d7d929ae9c68f716195ce15e745b3e8fa122fc67698ac6498d802ed0fa4"}, - {file = "pydantic_core-2.10.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e6f31a17acede6a8cd1ae2d123ce04d8cca74056c9d456075f4f6f85de055607"}, - {file = "pydantic_core-2.10.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d8f1ebca515a03e5654f88411420fea6380fc841d1bea08effb28184e3d4899f"}, - {file = "pydantic_core-2.10.1-cp311-none-win32.whl", hash = "sha256:6db2eb9654a85ada248afa5a6db5ff1cf0f7b16043a6b070adc4a5be68c716d6"}, - {file = "pydantic_core-2.10.1-cp311-none-win_amd64.whl", hash = "sha256:4a5be350f922430997f240d25f8219f93b0c81e15f7b30b868b2fddfc2d05f27"}, - {file = "pydantic_core-2.10.1-cp311-none-win_arm64.whl", hash = "sha256:5fdb39f67c779b183b0c853cd6b45f7db84b84e0571b3ef1c89cdb1dfc367325"}, - {file = "pydantic_core-2.10.1-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:b1f22a9ab44de5f082216270552aa54259db20189e68fc12484873d926426921"}, - {file = "pydantic_core-2.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8572cadbf4cfa95fb4187775b5ade2eaa93511f07947b38f4cd67cf10783b118"}, - {file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:db9a28c063c7c00844ae42a80203eb6d2d6bbb97070cfa00194dff40e6f545ab"}, - {file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0e2a35baa428181cb2270a15864ec6286822d3576f2ed0f4cd7f0c1708472aff"}, - {file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05560ab976012bf40f25d5225a58bfa649bb897b87192a36c6fef1ab132540d7"}, - {file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d6495008733c7521a89422d7a68efa0a0122c99a5861f06020ef5b1f51f9ba7c"}, - {file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14ac492c686defc8e6133e3a2d9eaf5261b3df26b8ae97450c1647286750b901"}, - {file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8282bab177a9a3081fd3d0a0175a07a1e2bfb7fcbbd949519ea0980f8a07144d"}, - {file = "pydantic_core-2.10.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:aafdb89fdeb5fe165043896817eccd6434aee124d5ee9b354f92cd574ba5e78f"}, - {file = "pydantic_core-2.10.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f6defd966ca3b187ec6c366604e9296f585021d922e666b99c47e78738b5666c"}, - {file = "pydantic_core-2.10.1-cp312-none-win32.whl", hash = "sha256:7c4d1894fe112b0864c1fa75dffa045720a194b227bed12f4be7f6045b25209f"}, - {file = "pydantic_core-2.10.1-cp312-none-win_amd64.whl", hash = "sha256:5994985da903d0b8a08e4935c46ed8daf5be1cf217489e673910951dc533d430"}, - {file = "pydantic_core-2.10.1-cp312-none-win_arm64.whl", hash = "sha256:0d8a8adef23d86d8eceed3e32e9cca8879c7481c183f84ed1a8edc7df073af94"}, - {file = "pydantic_core-2.10.1-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:9badf8d45171d92387410b04639d73811b785b5161ecadabf056ea14d62d4ede"}, - {file = "pydantic_core-2.10.1-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:ebedb45b9feb7258fac0a268a3f6bec0a2ea4d9558f3d6f813f02ff3a6dc6698"}, - {file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cfe1090245c078720d250d19cb05d67e21a9cd7c257698ef139bc41cf6c27b4f"}, - {file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e357571bb0efd65fd55f18db0a2fb0ed89d0bb1d41d906b138f088933ae618bb"}, - {file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b3dcd587b69bbf54fc04ca157c2323b8911033e827fffaecf0cafa5a892a0904"}, - {file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c120c9ce3b163b985a3b966bb701114beb1da4b0468b9b236fc754783d85aa3"}, - {file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15d6bca84ffc966cc9976b09a18cf9543ed4d4ecbd97e7086f9ce9327ea48891"}, - {file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5cabb9710f09d5d2e9e2748c3e3e20d991a4c5f96ed8f1132518f54ab2967221"}, - {file = "pydantic_core-2.10.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:82f55187a5bebae7d81d35b1e9aaea5e169d44819789837cdd4720d768c55d15"}, - {file = "pydantic_core-2.10.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:1d40f55222b233e98e3921df7811c27567f0e1a4411b93d4c5c0f4ce131bc42f"}, - {file = "pydantic_core-2.10.1-cp37-none-win32.whl", hash = "sha256:14e09ff0b8fe6e46b93d36a878f6e4a3a98ba5303c76bb8e716f4878a3bee92c"}, - {file = "pydantic_core-2.10.1-cp37-none-win_amd64.whl", hash = "sha256:1396e81b83516b9d5c9e26a924fa69164156c148c717131f54f586485ac3c15e"}, - {file = "pydantic_core-2.10.1-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:6835451b57c1b467b95ffb03a38bb75b52fb4dc2762bb1d9dbed8de31ea7d0fc"}, - {file = "pydantic_core-2.10.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b00bc4619f60c853556b35f83731bd817f989cba3e97dc792bb8c97941b8053a"}, - {file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fa467fd300a6f046bdb248d40cd015b21b7576c168a6bb20aa22e595c8ffcdd"}, - {file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d99277877daf2efe074eae6338453a4ed54a2d93fb4678ddfe1209a0c93a2468"}, - {file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fa7db7558607afeccb33c0e4bf1c9a9a835e26599e76af6fe2fcea45904083a6"}, - {file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aad7bd686363d1ce4ee930ad39f14e1673248373f4a9d74d2b9554f06199fb58"}, - {file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:443fed67d33aa85357464f297e3d26e570267d1af6fef1c21ca50921d2976302"}, - {file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:042462d8d6ba707fd3ce9649e7bf268633a41018d6a998fb5fbacb7e928a183e"}, - {file = "pydantic_core-2.10.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ecdbde46235f3d560b18be0cb706c8e8ad1b965e5c13bbba7450c86064e96561"}, - {file = "pydantic_core-2.10.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ed550ed05540c03f0e69e6d74ad58d026de61b9eaebebbaaf8873e585cbb18de"}, - {file = "pydantic_core-2.10.1-cp38-none-win32.whl", hash = "sha256:8cdbbd92154db2fec4ec973d45c565e767ddc20aa6dbaf50142676484cbff8ee"}, - {file = "pydantic_core-2.10.1-cp38-none-win_amd64.whl", hash = "sha256:9f6f3e2598604956480f6c8aa24a3384dbf6509fe995d97f6ca6103bb8c2534e"}, - {file = "pydantic_core-2.10.1-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:655f8f4c8d6a5963c9a0687793da37b9b681d9ad06f29438a3b2326d4e6b7970"}, - {file = "pydantic_core-2.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e570ffeb2170e116a5b17e83f19911020ac79d19c96f320cbfa1fa96b470185b"}, - {file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:64322bfa13e44c6c30c518729ef08fda6026b96d5c0be724b3c4ae4da939f875"}, - {file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:485a91abe3a07c3a8d1e082ba29254eea3e2bb13cbbd4351ea4e5a21912cc9b0"}, - {file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7c2b8eb9fc872e68b46eeaf835e86bccc3a58ba57d0eedc109cbb14177be531"}, - {file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a5cb87bdc2e5f620693148b5f8f842d293cae46c5f15a1b1bf7ceeed324a740c"}, - {file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:25bd966103890ccfa028841a8f30cebcf5875eeac8c4bde4fe221364c92f0c9a"}, - {file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f323306d0556351735b54acbf82904fe30a27b6a7147153cbe6e19aaaa2aa429"}, - {file = "pydantic_core-2.10.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0c27f38dc4fbf07b358b2bc90edf35e82d1703e22ff2efa4af4ad5de1b3833e7"}, - {file = "pydantic_core-2.10.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f1365e032a477c1430cfe0cf2856679529a2331426f8081172c4a74186f1d595"}, - {file = "pydantic_core-2.10.1-cp39-none-win32.whl", hash = "sha256:a1c311fd06ab3b10805abb72109f01a134019739bd3286b8ae1bc2fc4e50c07a"}, - {file = "pydantic_core-2.10.1-cp39-none-win_amd64.whl", hash = "sha256:ae8a8843b11dc0b03b57b52793e391f0122e740de3df1474814c700d2622950a"}, - {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:d43002441932f9a9ea5d6f9efaa2e21458221a3a4b417a14027a1d530201ef1b"}, - {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fcb83175cc4936a5425dde3356f079ae03c0802bbdf8ff82c035f8a54b333521"}, - {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:962ed72424bf1f72334e2f1e61b68f16c0e596f024ca7ac5daf229f7c26e4208"}, - {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2cf5bb4dd67f20f3bbc1209ef572a259027c49e5ff694fa56bed62959b41e1f9"}, - {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e544246b859f17373bed915182ab841b80849ed9cf23f1f07b73b7c58baee5fb"}, - {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:c0877239307b7e69d025b73774e88e86ce82f6ba6adf98f41069d5b0b78bd1bf"}, - {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:53df009d1e1ba40f696f8995683e067e3967101d4bb4ea6f667931b7d4a01357"}, - {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a1254357f7e4c82e77c348dabf2d55f1d14d19d91ff025004775e70a6ef40ada"}, - {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:524ff0ca3baea164d6d93a32c58ac79eca9f6cf713586fdc0adb66a8cdeab96a"}, - {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f0ac9fb8608dbc6eaf17956bf623c9119b4db7dbb511650910a82e261e6600f"}, - {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:320f14bd4542a04ab23747ff2c8a778bde727158b606e2661349557f0770711e"}, - {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:63974d168b6233b4ed6a0046296803cb13c56637a7b8106564ab575926572a55"}, - {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:417243bf599ba1f1fef2bb8c543ceb918676954734e2dcb82bf162ae9d7bd514"}, - {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:dda81e5ec82485155a19d9624cfcca9be88a405e2857354e5b089c2a982144b2"}, - {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:14cfbb00959259e15d684505263d5a21732b31248a5dd4941f73a3be233865b9"}, - {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:631cb7415225954fdcc2a024119101946793e5923f6c4d73a5914d27eb3d3a05"}, - {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:bec7dd208a4182e99c5b6c501ce0b1f49de2802448d4056091f8e630b28e9a52"}, - {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:149b8a07712f45b332faee1a2258d8ef1fb4a36f88c0c17cb687f205c5dc6e7d"}, - {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d966c47f9dd73c2d32a809d2be529112d509321c5310ebf54076812e6ecd884"}, - {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7eb037106f5c6b3b0b864ad226b0b7ab58157124161d48e4b30c4a43fef8bc4b"}, - {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:154ea7c52e32dce13065dbb20a4a6f0cc012b4f667ac90d648d36b12007fa9f7"}, - {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e562617a45b5a9da5be4abe72b971d4f00bf8555eb29bb91ec2ef2be348cd132"}, - {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:f23b55eb5464468f9e0e9a9935ce3ed2a870608d5f534025cd5536bca25b1402"}, - {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:e9121b4009339b0f751955baf4543a0bfd6bc3f8188f8056b1a25a2d45099934"}, - {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:0523aeb76e03f753b58be33b26540880bac5aa54422e4462404c432230543f33"}, - {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e0e2959ef5d5b8dc9ef21e1a305a21a36e254e6a34432d00c72a92fdc5ecda5"}, - {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da01bec0a26befab4898ed83b362993c844b9a607a86add78604186297eb047e"}, - {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f2e9072d71c1f6cfc79a36d4484c82823c560e6f5599c43c1ca6b5cdbd54f881"}, - {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:f36a3489d9e28fe4b67be9992a23029c3cec0babc3bd9afb39f49844a8c721c5"}, - {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f64f82cc3443149292b32387086d02a6c7fb39b8781563e0ca7b8d7d9cf72bd7"}, - {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:b4a6db486ac8e99ae696e09efc8b2b9fea67b63c8f88ba7a1a16c24a057a0776"}, - {file = "pydantic_core-2.10.1.tar.gz", hash = "sha256:0f8682dbdd2f67f8e1edddcbffcc29f60a6182b4901c367fc8c1c40d30bb0a82"}, + {file = "pydantic_core-2.16.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:75b81e678d1c1ede0785c7f46690621e4c6e63ccd9192af1f0bd9d504bbb6bf4"}, + {file = "pydantic_core-2.16.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9c865a7ee6f93783bd5d781af5a4c43dadc37053a5b42f7d18dc019f8c9d2bd1"}, + {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:162e498303d2b1c036b957a1278fa0899d02b2842f1ff901b6395104c5554a45"}, + {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2f583bd01bbfbff4eaee0868e6fc607efdfcc2b03c1c766b06a707abbc856187"}, + {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b926dd38db1519ed3043a4de50214e0d600d404099c3392f098a7f9d75029ff8"}, + {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:716b542728d4c742353448765aa7cdaa519a7b82f9564130e2b3f6766018c9ec"}, + {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc4ad7f7ee1a13d9cb49d8198cd7d7e3aa93e425f371a68235f784e99741561f"}, + {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bd87f48924f360e5d1c5f770d6155ce0e7d83f7b4e10c2f9ec001c73cf475c99"}, + {file = "pydantic_core-2.16.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0df446663464884297c793874573549229f9eca73b59360878f382a0fc085979"}, + {file = "pydantic_core-2.16.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4df8a199d9f6afc5ae9a65f8f95ee52cae389a8c6b20163762bde0426275b7db"}, + {file = "pydantic_core-2.16.3-cp310-none-win32.whl", hash = "sha256:456855f57b413f077dff513a5a28ed838dbbb15082ba00f80750377eed23d132"}, + {file = "pydantic_core-2.16.3-cp310-none-win_amd64.whl", hash = "sha256:732da3243e1b8d3eab8c6ae23ae6a58548849d2e4a4e03a1924c8ddf71a387cb"}, + {file = "pydantic_core-2.16.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:519ae0312616026bf4cedc0fe459e982734f3ca82ee8c7246c19b650b60a5ee4"}, + {file = "pydantic_core-2.16.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b3992a322a5617ded0a9f23fd06dbc1e4bd7cf39bc4ccf344b10f80af58beacd"}, + {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d62da299c6ecb04df729e4b5c52dc0d53f4f8430b4492b93aa8de1f541c4aac"}, + {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2acca2be4bb2f2147ada8cac612f8a98fc09f41c89f87add7256ad27332c2fda"}, + {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1b662180108c55dfbf1280d865b2d116633d436cfc0bba82323554873967b340"}, + {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e7c6ed0dc9d8e65f24f5824291550139fe6f37fac03788d4580da0d33bc00c97"}, + {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6b1bb0827f56654b4437955555dc3aeeebeddc47c2d7ed575477f082622c49e"}, + {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e56f8186d6210ac7ece503193ec84104da7ceb98f68ce18c07282fcc2452e76f"}, + {file = "pydantic_core-2.16.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:936e5db01dd49476fa8f4383c259b8b1303d5dd5fb34c97de194560698cc2c5e"}, + {file = "pydantic_core-2.16.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:33809aebac276089b78db106ee692bdc9044710e26f24a9a2eaa35a0f9fa70ba"}, + {file = "pydantic_core-2.16.3-cp311-none-win32.whl", hash = "sha256:ded1c35f15c9dea16ead9bffcde9bb5c7c031bff076355dc58dcb1cb436c4721"}, + {file = "pydantic_core-2.16.3-cp311-none-win_amd64.whl", hash = "sha256:d89ca19cdd0dd5f31606a9329e309d4fcbb3df860960acec32630297d61820df"}, + {file = "pydantic_core-2.16.3-cp311-none-win_arm64.whl", hash = "sha256:6162f8d2dc27ba21027f261e4fa26f8bcb3cf9784b7f9499466a311ac284b5b9"}, + {file = "pydantic_core-2.16.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:0f56ae86b60ea987ae8bcd6654a887238fd53d1384f9b222ac457070b7ac4cff"}, + {file = "pydantic_core-2.16.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c9bd22a2a639e26171068f8ebb5400ce2c1bc7d17959f60a3b753ae13c632975"}, + {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4204e773b4b408062960e65468d5346bdfe139247ee5f1ca2a378983e11388a2"}, + {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f651dd19363c632f4abe3480a7c87a9773be27cfe1341aef06e8759599454120"}, + {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf09e615a0bf98d406657e0008e4a8701b11481840be7d31755dc9f97c44053"}, + {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8e47755d8152c1ab5b55928ab422a76e2e7b22b5ed8e90a7d584268dd49e9c6b"}, + {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:500960cb3a0543a724a81ba859da816e8cf01b0e6aaeedf2c3775d12ee49cade"}, + {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cf6204fe865da605285c34cf1172879d0314ff267b1c35ff59de7154f35fdc2e"}, + {file = "pydantic_core-2.16.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d33dd21f572545649f90c38c227cc8631268ba25c460b5569abebdd0ec5974ca"}, + {file = "pydantic_core-2.16.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:49d5d58abd4b83fb8ce763be7794d09b2f50f10aa65c0f0c1696c677edeb7cbf"}, + {file = "pydantic_core-2.16.3-cp312-none-win32.whl", hash = "sha256:f53aace168a2a10582e570b7736cc5bef12cae9cf21775e3eafac597e8551fbe"}, + {file = "pydantic_core-2.16.3-cp312-none-win_amd64.whl", hash = "sha256:0d32576b1de5a30d9a97f300cc6a3f4694c428d956adbc7e6e2f9cad279e45ed"}, + {file = "pydantic_core-2.16.3-cp312-none-win_arm64.whl", hash = "sha256:ec08be75bb268473677edb83ba71e7e74b43c008e4a7b1907c6d57e940bf34b6"}, + {file = "pydantic_core-2.16.3-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:b1f6f5938d63c6139860f044e2538baeee6f0b251a1816e7adb6cbce106a1f01"}, + {file = "pydantic_core-2.16.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2a1ef6a36fdbf71538142ed604ad19b82f67b05749512e47f247a6ddd06afdc7"}, + {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:704d35ecc7e9c31d48926150afada60401c55efa3b46cd1ded5a01bdffaf1d48"}, + {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d937653a696465677ed583124b94a4b2d79f5e30b2c46115a68e482c6a591c8a"}, + {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9803edf8e29bd825f43481f19c37f50d2b01899448273b3a7758441b512acf8"}, + {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:72282ad4892a9fb2da25defeac8c2e84352c108705c972db82ab121d15f14e6d"}, + {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f752826b5b8361193df55afcdf8ca6a57d0232653494ba473630a83ba50d8c9"}, + {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4384a8f68ddb31a0b0c3deae88765f5868a1b9148939c3f4121233314ad5532c"}, + {file = "pydantic_core-2.16.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a4b2bf78342c40b3dc830880106f54328928ff03e357935ad26c7128bbd66ce8"}, + {file = "pydantic_core-2.16.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:13dcc4802961b5f843a9385fc821a0b0135e8c07fc3d9949fd49627c1a5e6ae5"}, + {file = "pydantic_core-2.16.3-cp38-none-win32.whl", hash = "sha256:e3e70c94a0c3841e6aa831edab1619ad5c511199be94d0c11ba75fe06efe107a"}, + {file = "pydantic_core-2.16.3-cp38-none-win_amd64.whl", hash = "sha256:ecdf6bf5f578615f2e985a5e1f6572e23aa632c4bd1dc67f8f406d445ac115ed"}, + {file = "pydantic_core-2.16.3-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:bda1ee3e08252b8d41fa5537413ffdddd58fa73107171a126d3b9ff001b9b820"}, + {file = "pydantic_core-2.16.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:21b888c973e4f26b7a96491c0965a8a312e13be108022ee510248fe379a5fa23"}, + {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be0ec334369316fa73448cc8c982c01e5d2a81c95969d58b8f6e272884df0074"}, + {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b5b6079cc452a7c53dd378c6f881ac528246b3ac9aae0f8eef98498a75657805"}, + {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ee8d5f878dccb6d499ba4d30d757111847b6849ae07acdd1205fffa1fc1253c"}, + {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7233d65d9d651242a68801159763d09e9ec96e8a158dbf118dc090cd77a104c9"}, + {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c6119dc90483a5cb50a1306adb8d52c66e447da88ea44f323e0ae1a5fcb14256"}, + {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:578114bc803a4c1ff9946d977c221e4376620a46cf78da267d946397dc9514a8"}, + {file = "pydantic_core-2.16.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d8f99b147ff3fcf6b3cc60cb0c39ea443884d5559a30b1481e92495f2310ff2b"}, + {file = "pydantic_core-2.16.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4ac6b4ce1e7283d715c4b729d8f9dab9627586dafce81d9eaa009dd7f25dd972"}, + {file = "pydantic_core-2.16.3-cp39-none-win32.whl", hash = "sha256:e7774b570e61cb998490c5235740d475413a1f6de823169b4cf94e2fe9e9f6b2"}, + {file = "pydantic_core-2.16.3-cp39-none-win_amd64.whl", hash = "sha256:9091632a25b8b87b9a605ec0e61f241c456e9248bfdcf7abdf344fdb169c81cf"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:36fa178aacbc277bc6b62a2c3da95226520da4f4e9e206fdf076484363895d2c"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:dcca5d2bf65c6fb591fff92da03f94cd4f315972f97c21975398bd4bd046854a"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a72fb9963cba4cd5793854fd12f4cfee731e86df140f59ff52a49b3552db241"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b60cc1a081f80a2105a59385b92d82278b15d80ebb3adb200542ae165cd7d183"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cbcc558401de90a746d02ef330c528f2e668c83350f045833543cd57ecead1ad"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:fee427241c2d9fb7192b658190f9f5fd6dfe41e02f3c1489d2ec1e6a5ab1e04a"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f4cb85f693044e0f71f394ff76c98ddc1bc0953e48c061725e540396d5c8a2e1"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b29eeb887aa931c2fcef5aa515d9d176d25006794610c264ddc114c053bf96fe"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a425479ee40ff021f8216c9d07a6a3b54b31c8267c6e17aa88b70d7ebd0e5e5b"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:5c5cbc703168d1b7a838668998308018a2718c2130595e8e190220238addc96f"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99b6add4c0b39a513d323d3b93bc173dac663c27b99860dd5bf491b240d26137"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f76ee558751746d6a38f89d60b6228fa174e5172d143886af0f85aa306fd89"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:00ee1c97b5364b84cb0bd82e9bbf645d5e2871fb8c58059d158412fee2d33d8a"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:287073c66748f624be4cef893ef9174e3eb88fe0b8a78dc22e88eca4bc357ca6"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ed25e1835c00a332cb10c683cd39da96a719ab1dfc08427d476bce41b92531fc"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:86b3d0033580bd6bbe07590152007275bd7af95f98eaa5bd36f3da219dcd93da"}, + {file = "pydantic_core-2.16.3.tar.gz", hash = "sha256:1cac689f80a3abab2d3c0048b29eea5751114054f032a941a32de4c852c59cad"}, ] [package.dependencies] @@ -394,19 +346,18 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pytest" -version = "7.4.3" +version = "7.4.4" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.7" files = [ - {file = "pytest-7.4.3-py3-none-any.whl", hash = "sha256:0d009c083ea859a71b76adf7c1d502e4bc170b80a8ef002da5806527b9591fac"}, - {file = "pytest-7.4.3.tar.gz", hash = "sha256:d989d136982de4e3b29dabcc838ad581c64e8ed52c11fbe86ddebd9da0818cd5"}, + {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, + {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, ] [package.dependencies] colorama = {version = "*", markers = "sys_platform == \"win32\""} exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} -importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} iniconfig = "*" packaging = "*" pluggy = ">=0.12,<2.0" @@ -417,13 +368,13 @@ testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "no [[package]] name = "sniffio" -version = "1.3.0" +version = "1.3.1" description = "Sniff out which async library your code is running under" optional = false python-versions = ">=3.7" files = [ - {file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"}, - {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"}, + {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, + {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, ] [[package]] @@ -437,83 +388,18 @@ files = [ {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] -[[package]] -name = "typed-ast" -version = "1.5.5" -description = "a fork of Python 2 and 3 ast modules with type comment support" -optional = false -python-versions = ">=3.6" -files = [ - {file = "typed_ast-1.5.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4bc1efe0ce3ffb74784e06460f01a223ac1f6ab31c6bc0376a21184bf5aabe3b"}, - {file = "typed_ast-1.5.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5f7a8c46a8b333f71abd61d7ab9255440d4a588f34a21f126bbfc95f6049e686"}, - {file = "typed_ast-1.5.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:597fc66b4162f959ee6a96b978c0435bd63791e31e4f410622d19f1686d5e769"}, - {file = "typed_ast-1.5.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d41b7a686ce653e06c2609075d397ebd5b969d821b9797d029fccd71fdec8e04"}, - {file = "typed_ast-1.5.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:5fe83a9a44c4ce67c796a1b466c270c1272e176603d5e06f6afbc101a572859d"}, - {file = "typed_ast-1.5.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d5c0c112a74c0e5db2c75882a0adf3133adedcdbfd8cf7c9d6ed77365ab90a1d"}, - {file = "typed_ast-1.5.5-cp310-cp310-win_amd64.whl", hash = "sha256:e1a976ed4cc2d71bb073e1b2a250892a6e968ff02aa14c1f40eba4f365ffec02"}, - {file = "typed_ast-1.5.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c631da9710271cb67b08bd3f3813b7af7f4c69c319b75475436fcab8c3d21bee"}, - {file = "typed_ast-1.5.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b445c2abfecab89a932b20bd8261488d574591173d07827c1eda32c457358b18"}, - {file = "typed_ast-1.5.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc95ffaaab2be3b25eb938779e43f513e0e538a84dd14a5d844b8f2932593d88"}, - {file = "typed_ast-1.5.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61443214d9b4c660dcf4b5307f15c12cb30bdfe9588ce6158f4a005baeb167b2"}, - {file = "typed_ast-1.5.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6eb936d107e4d474940469e8ec5b380c9b329b5f08b78282d46baeebd3692dc9"}, - {file = "typed_ast-1.5.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e48bf27022897577d8479eaed64701ecaf0467182448bd95759883300ca818c8"}, - {file = "typed_ast-1.5.5-cp311-cp311-win_amd64.whl", hash = "sha256:83509f9324011c9a39faaef0922c6f720f9623afe3fe220b6d0b15638247206b"}, - {file = "typed_ast-1.5.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:44f214394fc1af23ca6d4e9e744804d890045d1643dd7e8229951e0ef39429b5"}, - {file = "typed_ast-1.5.5-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:118c1ce46ce58fda78503eae14b7664163aa735b620b64b5b725453696f2a35c"}, - {file = "typed_ast-1.5.5-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be4919b808efa61101456e87f2d4c75b228f4e52618621c77f1ddcaae15904fa"}, - {file = "typed_ast-1.5.5-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:fc2b8c4e1bc5cd96c1a823a885e6b158f8451cf6f5530e1829390b4d27d0807f"}, - {file = "typed_ast-1.5.5-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:16f7313e0a08c7de57f2998c85e2a69a642e97cb32f87eb65fbfe88381a5e44d"}, - {file = "typed_ast-1.5.5-cp36-cp36m-win_amd64.whl", hash = "sha256:2b946ef8c04f77230489f75b4b5a4a6f24c078be4aed241cfabe9cbf4156e7e5"}, - {file = "typed_ast-1.5.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2188bc33d85951ea4ddad55d2b35598b2709d122c11c75cffd529fbc9965508e"}, - {file = "typed_ast-1.5.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0635900d16ae133cab3b26c607586131269f88266954eb04ec31535c9a12ef1e"}, - {file = "typed_ast-1.5.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:57bfc3cf35a0f2fdf0a88a3044aafaec1d2f24d8ae8cd87c4f58d615fb5b6311"}, - {file = "typed_ast-1.5.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:fe58ef6a764de7b4b36edfc8592641f56e69b7163bba9f9c8089838ee596bfb2"}, - {file = "typed_ast-1.5.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d09d930c2d1d621f717bb217bf1fe2584616febb5138d9b3e8cdd26506c3f6d4"}, - {file = "typed_ast-1.5.5-cp37-cp37m-win_amd64.whl", hash = "sha256:d40c10326893ecab8a80a53039164a224984339b2c32a6baf55ecbd5b1df6431"}, - {file = "typed_ast-1.5.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:fd946abf3c31fb50eee07451a6aedbfff912fcd13cf357363f5b4e834cc5e71a"}, - {file = "typed_ast-1.5.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ed4a1a42df8a3dfb6b40c3d2de109e935949f2f66b19703eafade03173f8f437"}, - {file = "typed_ast-1.5.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:045f9930a1550d9352464e5149710d56a2aed23a2ffe78946478f7b5416f1ede"}, - {file = "typed_ast-1.5.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:381eed9c95484ceef5ced626355fdc0765ab51d8553fec08661dce654a935db4"}, - {file = "typed_ast-1.5.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:bfd39a41c0ef6f31684daff53befddae608f9daf6957140228a08e51f312d7e6"}, - {file = "typed_ast-1.5.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8c524eb3024edcc04e288db9541fe1f438f82d281e591c548903d5b77ad1ddd4"}, - {file = "typed_ast-1.5.5-cp38-cp38-win_amd64.whl", hash = "sha256:7f58fabdde8dcbe764cef5e1a7fcb440f2463c1bbbec1cf2a86ca7bc1f95184b"}, - {file = "typed_ast-1.5.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:042eb665ff6bf020dd2243307d11ed626306b82812aba21836096d229fdc6a10"}, - {file = "typed_ast-1.5.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:622e4a006472b05cf6ef7f9f2636edc51bda670b7bbffa18d26b255269d3d814"}, - {file = "typed_ast-1.5.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1efebbbf4604ad1283e963e8915daa240cb4bf5067053cf2f0baadc4d4fb51b8"}, - {file = "typed_ast-1.5.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0aefdd66f1784c58f65b502b6cf8b121544680456d1cebbd300c2c813899274"}, - {file = "typed_ast-1.5.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:48074261a842acf825af1968cd912f6f21357316080ebaca5f19abbb11690c8a"}, - {file = "typed_ast-1.5.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:429ae404f69dc94b9361bb62291885894b7c6fb4640d561179548c849f8492ba"}, - {file = "typed_ast-1.5.5-cp39-cp39-win_amd64.whl", hash = "sha256:335f22ccb244da2b5c296e6f96b06ee9bed46526db0de38d2f0e5a6597b81155"}, - {file = "typed_ast-1.5.5.tar.gz", hash = "sha256:94282f7a354f36ef5dbce0ef3467ebf6a258e370ab33d5b40c249fa996e590dd"}, -] - [[package]] name = "typing-extensions" -version = "4.7.1" -description = "Backported and Experimental Type Hints for Python 3.7+" +version = "4.10.0" +description = "Backported and Experimental Type Hints for Python 3.8+" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36"}, - {file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"}, + {file = "typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475"}, + {file = "typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"}, ] -[[package]] -name = "zipp" -version = "3.15.0" -description = "Backport of pathlib-compatible object wrapper for zip files" -optional = false -python-versions = ">=3.7" -files = [ - {file = "zipp-3.15.0-py3-none-any.whl", hash = "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556"}, - {file = "zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b"}, -] - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] - [metadata] lock-version = "2.0" -python-versions = "^3.7" -content-hash = "4ac84aae6b05a415337279868d39fe7ce44104dffcd6b159af9e12dcea350ba1" +python-versions = "^3.8" +content-hash = "3c8fae8de68e5484c48073bf191e51acbe3b9a32fd98e6b5e4d165e42a7fc7aa" diff --git a/pyproject.toml b/pyproject.toml index f2f2fcc..403c85b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "webflow" -version = "1.0.0" +version = "v1.1.0" description = "" readme = "README.md" authors = [] @@ -9,12 +9,13 @@ packages = [ ] [tool.poetry.dependencies] -python = "^3.7" +python = "^3.8" httpx = ">=0.21.2" -pydantic = ">= 1.9.2, < 2.5.0" +pydantic = ">= 1.9.2" +typing_extensions = ">= 4.0.0" [tool.poetry.dev-dependencies] -mypy = "0.971" +mypy = "^1.8.0" pytest = "^7.4.0" [build-system] diff --git a/src/webflow/__init__.py b/src/webflow/__init__.py index dc9642b..cfb5e09 100644 --- a/src/webflow/__init__.py +++ b/src/webflow/__init__.py @@ -26,6 +26,7 @@ CustomCodeBlock, CustomCodeBlockType, CustomCodeResponse, + Dom, Domain, DuplicateUserEmail, EcommerceSettings, @@ -44,12 +45,17 @@ FormSubmissionList, FormSubmissionTrigger, FormSubmissionTriggerPayload, + ImageNode, InvalidDomain, + InvalidScopes, InventoryItem, InventoryItemInventoryType, ListCustomCodeBlocks, MissingScopes, NoDomains, + Node, + NodeType, + NotEnterprisePlanSite, OauthScope, Order, OrderAddress, @@ -85,6 +91,8 @@ ProductAndSkUs, ProductAndSkUsList, ProductFieldData, + ProductFieldDataEcProductType, + ProductFieldDataTaxCategory, PublishStatus, PublishedItems, PublishedSite, @@ -96,12 +104,17 @@ Site, SiteActivityLogItem, SiteActivityLogItemResourceOperation, + SiteActivityLogItemUser, SiteActivityLogResponse, SitePublish, SitePublishPayload, Sites, Sku, SkuFieldData, + SkuFieldDataCompareAtPrice, + SkuFieldDataEcSkuBillingMethod, + SkuFieldDataEcSkuSubscriptionPlan, + SkuFieldDataEcSkuSubscriptionPlanInterval, SkuFieldDataPrice, SkuPropertyList, SkuPropertyListEnumItem, @@ -110,6 +123,7 @@ StripeCardBrand, StripeCardExpires, StripeDetails, + TextNode, TriggerType, User, UserAccessGroupsItem, @@ -136,11 +150,24 @@ ) from .resources import ( AccessGroupsListRequestSort, + DomWriteNodesItem, InventoryUpdateRequestInventoryType, OrdersListRequestStatus, OrdersRefundRequestReason, + ProductSkuCreateProduct, + ProductSkuCreateProductFieldData, + ProductSkuCreateProductFieldDataEcProductType, + ProductSkuCreateProductFieldDataTaxCategory, + ProductSkuCreateSku, + ProductSkuCreateSkuFieldData, + ProductSkuCreateSkuFieldDataCompareAtPrice, + ProductSkuCreateSkuFieldDataEcSkuBillingMethod, + ProductSkuCreateSkuFieldDataEcSkuSubscriptionPlan, + ProductSkuCreateSkuFieldDataEcSkuSubscriptionPlanInterval, + ProductSkuCreateSkuFieldDataPrice, ProductsCreateSkuResponse, UsersListRequestSort, + UsersUpdateRequestData, access_groups, assets, collections, @@ -187,6 +214,8 @@ "CustomCodeBlock", "CustomCodeBlockType", "CustomCodeResponse", + "Dom", + "DomWriteNodesItem", "Domain", "DuplicateUserEmail", "EcommerceSettings", @@ -206,14 +235,19 @@ "FormSubmissionList", "FormSubmissionTrigger", "FormSubmissionTriggerPayload", + "ImageNode", "InternalServerError", "InvalidDomain", + "InvalidScopes", "InventoryItem", "InventoryItemInventoryType", "InventoryUpdateRequestInventoryType", "ListCustomCodeBlocks", "MissingScopes", "NoDomains", + "Node", + "NodeType", + "NotEnterprisePlanSite", "NotFoundError", "OauthScope", "Order", @@ -252,6 +286,19 @@ "ProductAndSkUs", "ProductAndSkUsList", "ProductFieldData", + "ProductFieldDataEcProductType", + "ProductFieldDataTaxCategory", + "ProductSkuCreateProduct", + "ProductSkuCreateProductFieldData", + "ProductSkuCreateProductFieldDataEcProductType", + "ProductSkuCreateProductFieldDataTaxCategory", + "ProductSkuCreateSku", + "ProductSkuCreateSkuFieldData", + "ProductSkuCreateSkuFieldDataCompareAtPrice", + "ProductSkuCreateSkuFieldDataEcSkuBillingMethod", + "ProductSkuCreateSkuFieldDataEcSkuSubscriptionPlan", + "ProductSkuCreateSkuFieldDataEcSkuSubscriptionPlanInterval", + "ProductSkuCreateSkuFieldDataPrice", "ProductsCreateSkuResponse", "PublishStatus", "PublishedItems", @@ -264,12 +311,17 @@ "Site", "SiteActivityLogItem", "SiteActivityLogItemResourceOperation", + "SiteActivityLogItemUser", "SiteActivityLogResponse", "SitePublish", "SitePublishPayload", "Sites", "Sku", "SkuFieldData", + "SkuFieldDataCompareAtPrice", + "SkuFieldDataEcSkuBillingMethod", + "SkuFieldDataEcSkuSubscriptionPlan", + "SkuFieldDataEcSkuSubscriptionPlanInterval", "SkuFieldDataPrice", "SkuPropertyList", "SkuPropertyListEnumItem", @@ -278,6 +330,7 @@ "StripeCardBrand", "StripeCardExpires", "StripeDetails", + "TextNode", "TooManyRequestsError", "TriggerType", "UnauthorizedError", @@ -293,6 +346,7 @@ "UserWebhookPayloadTriggerType", "UsersListRequestSort", "UsersNotEnabled", + "UsersUpdateRequestData", "WebflowEnvironment", "Webhook", "WebhookList", diff --git a/src/webflow/client.py b/src/webflow/client.py index 08638bc..e69cea0 100644 --- a/src/webflow/client.py +++ b/src/webflow/client.py @@ -23,6 +23,29 @@ class Webflow: + """ + Use this class to access the different functions within the SDK. You can instantiate any number of clients with different configuration that will propogate to these functions. + + Parameters: + - base_url: typing.Optional[str]. The base url to use for requests from the client. + + - environment: WebflowEnvironment. The environment to use for requests from the client. from .environment import WebflowEnvironment + + Defaults to WebflowEnvironment.DEFAULT + + - access_token: typing.Union[str, typing.Callable[[], str]]. + + - timeout: typing.Optional[float]. The timeout to be used, in seconds, for requests by default the timeout is 60 seconds. + + - httpx_client: typing.Optional[httpx.Client]. The httpx client to use for making requests, a preconfigured client is used by default, however this is useful should you want to pass in any custom httpx configuration. + --- + from webflow.client import Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + """ + def __init__( self, *, @@ -54,6 +77,29 @@ def __init__( class AsyncWebflow: + """ + Use this class to access the different functions within the SDK. You can instantiate any number of clients with different configuration that will propogate to these functions. + + Parameters: + - base_url: typing.Optional[str]. The base url to use for requests from the client. + + - environment: WebflowEnvironment. The environment to use for requests from the client. from .environment import WebflowEnvironment + + Defaults to WebflowEnvironment.DEFAULT + + - access_token: typing.Union[str, typing.Callable[[], str]]. + + - timeout: typing.Optional[float]. The timeout to be used, in seconds, for requests by default the timeout is 60 seconds. + + - httpx_client: typing.Optional[httpx.AsyncClient]. The httpx client to use for making requests, a preconfigured client is used by default, however this is useful should you want to pass in any custom httpx configuration. + --- + from webflow.client import AsyncWebflow + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + """ + def __init__( self, *, diff --git a/src/webflow/core/__init__.py b/src/webflow/core/__init__.py index 2414955..4c53b36 100644 --- a/src/webflow/core/__init__.py +++ b/src/webflow/core/__init__.py @@ -3,14 +3,19 @@ from .api_error import ApiError from .client_wrapper import AsyncClientWrapper, BaseClientWrapper, SyncClientWrapper from .datetime_utils import serialize_datetime +from .file import File, convert_file_dict_to_httpx_tuples from .jsonable_encoder import jsonable_encoder from .remove_none_from_dict import remove_none_from_dict +from .request_options import RequestOptions __all__ = [ "ApiError", "AsyncClientWrapper", "BaseClientWrapper", + "File", + "RequestOptions", "SyncClientWrapper", + "convert_file_dict_to_httpx_tuples", "jsonable_encoder", "remove_none_from_dict", "serialize_datetime", diff --git a/src/webflow/core/client_wrapper.py b/src/webflow/core/client_wrapper.py index 2e7a724..4a5a77c 100644 --- a/src/webflow/core/client_wrapper.py +++ b/src/webflow/core/client_wrapper.py @@ -14,7 +14,7 @@ def get_headers(self) -> typing.Dict[str, str]: headers: typing.Dict[str, str] = { "X-Fern-Language": "Python", "X-Fern-SDK-Name": "webflow", - "X-Fern-SDK-Version": "0.1.0b2", + "X-Fern-SDK-Version": "v1.1.0", } headers["Authorization"] = f"Bearer {self._get_access_token()}" return headers diff --git a/src/webflow/core/file.py b/src/webflow/core/file.py new file mode 100644 index 0000000..cb0d40b --- /dev/null +++ b/src/webflow/core/file.py @@ -0,0 +1,38 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +# File typing inspired by the flexibility of types within the httpx library +# https://github.com/encode/httpx/blob/master/httpx/_types.py +FileContent = typing.Union[typing.IO[bytes], bytes, str] +File = typing.Union[ + # file (or bytes) + FileContent, + # (filename, file (or bytes)) + typing.Tuple[typing.Optional[str], FileContent], + # (filename, file (or bytes), content_type) + typing.Tuple[typing.Optional[str], FileContent, typing.Optional[str]], + # (filename, file (or bytes), content_type, headers) + typing.Tuple[typing.Optional[str], FileContent, typing.Optional[str], typing.Mapping[str, str]], +] + + +def convert_file_dict_to_httpx_tuples( + d: typing.Dict[str, typing.Union[File, typing.List[File]]] +) -> typing.List[typing.Tuple[str, File]]: + """ + The format we use is a list of tuples, where the first element is the + name of the file and the second is the file object. Typically HTTPX wants + a dict, but to be able to send lists of files, you have to use the list + approach (which also works for non-lists) + https://github.com/encode/httpx/pull/1032 + """ + + httpx_tuples = [] + for key, file_like in d.items(): + if isinstance(file_like, list): + for file_like_item in file_like: + httpx_tuples.append((key, file_like_item)) + else: + httpx_tuples.append((key, file_like)) + return httpx_tuples diff --git a/src/webflow/core/request_options.py b/src/webflow/core/request_options.py new file mode 100644 index 0000000..32e86b0 --- /dev/null +++ b/src/webflow/core/request_options.py @@ -0,0 +1,29 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +try: + from typing import NotRequired # type: ignore +except ImportError: + from typing_extensions import NotRequired # type: ignore + + +class RequestOptions(typing.TypedDict): + """ + Additional options for request-specific configuration when calling APIs via the SDK. + This is used primarily as an optional final parameter for service functions. + + Attributes: + - timeout_in_seconds: int. The number of seconds to await an API call before timing out. + + - additional_headers: typing.Dict[str, typing.Any]. A dictionary containing additional parameters to spread into the request's header dict + + - additional_query_parameters: typing.Dict[str, typing.Any]. A dictionary containing additional parameters to spread into the request's query parameters dict + + - additional_body_parameters: typing.Dict[str, typing.Any]. A dictionary containing additional parameters to spread into the request's body parameters dict + """ + + timeout_in_seconds: NotRequired[int] + additional_headers: NotRequired[typing.Dict[str, typing.Any]] + additional_query_parameters: NotRequired[typing.Dict[str, typing.Any]] + additional_body_parameters: NotRequired[typing.Dict[str, typing.Any]] diff --git a/src/webflow/resources/__init__.py b/src/webflow/resources/__init__.py index d3f2919..76beae7 100644 --- a/src/webflow/resources/__init__.py +++ b/src/webflow/resources/__init__.py @@ -19,16 +19,43 @@ from .access_groups import AccessGroupsListRequestSort from .inventory import InventoryUpdateRequestInventoryType from .orders import OrdersListRequestStatus, OrdersRefundRequestReason -from .products import ProductsCreateSkuResponse -from .users import UsersListRequestSort +from .pages import DomWriteNodesItem +from .products import ( + ProductSkuCreateProduct, + ProductSkuCreateProductFieldData, + ProductSkuCreateProductFieldDataEcProductType, + ProductSkuCreateProductFieldDataTaxCategory, + ProductSkuCreateSku, + ProductSkuCreateSkuFieldData, + ProductSkuCreateSkuFieldDataCompareAtPrice, + ProductSkuCreateSkuFieldDataEcSkuBillingMethod, + ProductSkuCreateSkuFieldDataEcSkuSubscriptionPlan, + ProductSkuCreateSkuFieldDataEcSkuSubscriptionPlanInterval, + ProductSkuCreateSkuFieldDataPrice, + ProductsCreateSkuResponse, +) +from .users import UsersListRequestSort, UsersUpdateRequestData __all__ = [ "AccessGroupsListRequestSort", + "DomWriteNodesItem", "InventoryUpdateRequestInventoryType", "OrdersListRequestStatus", "OrdersRefundRequestReason", + "ProductSkuCreateProduct", + "ProductSkuCreateProductFieldData", + "ProductSkuCreateProductFieldDataEcProductType", + "ProductSkuCreateProductFieldDataTaxCategory", + "ProductSkuCreateSku", + "ProductSkuCreateSkuFieldData", + "ProductSkuCreateSkuFieldDataCompareAtPrice", + "ProductSkuCreateSkuFieldDataEcSkuBillingMethod", + "ProductSkuCreateSkuFieldDataEcSkuSubscriptionPlan", + "ProductSkuCreateSkuFieldDataEcSkuSubscriptionPlanInterval", + "ProductSkuCreateSkuFieldDataPrice", "ProductsCreateSkuResponse", "UsersListRequestSort", + "UsersUpdateRequestData", "access_groups", "assets", "collections", diff --git a/src/webflow/resources/access_groups/client.py b/src/webflow/resources/access_groups/client.py index 6a9861a..bfd306e 100644 --- a/src/webflow/resources/access_groups/client.py +++ b/src/webflow/resources/access_groups/client.py @@ -6,7 +6,9 @@ from ...core.api_error import ApiError from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.jsonable_encoder import jsonable_encoder from ...core.remove_none_from_dict import remove_none_from_dict +from ...core.request_options import RequestOptions from ...errors.bad_request_error import BadRequestError from ...errors.forbidden_error import ForbiddenError from ...errors.internal_server_error import InternalServerError @@ -33,6 +35,7 @@ def list( offset: typing.Optional[float] = None, limit: typing.Optional[float] = None, sort: typing.Optional[AccessGroupsListRequestSort] = None, + request_options: typing.Optional[RequestOptions] = None, ) -> AccessGroupList: """ Get a list of access groups for a site

Required scope | `users:read` @@ -45,24 +48,48 @@ def list( - limit: typing.Optional[float]. Maximum number of records to be returned (max limit: 100) - sort: typing.Optional[AccessGroupsListRequestSort]. Sort string to use when ordering access groups - Can be prefixed with a `-` to reverse the sort (ex. `-CreatedOn`)--- - from webflow import AccessGroupsListRequestSort + Can be prefixed with a `-` to reverse the sort (ex. `-CreatedOn`) + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- from webflow.client import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) client.access_groups.list( - site_id="site-id", - sort=AccessGroupsListRequestSort.CREATED_ON_ASCENDING, + site_id="site_id", ) """ _response = self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/accessgroups"), - params=remove_none_from_dict({"offset": offset, "limit": limit, "sort": sort}), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/accessgroups" + ), + params=jsonable_encoder( + remove_none_from_dict( + { + "offset": offset, + "limit": limit, + "sort": sort, + **( + request_options.get("additional_query_parameters", {}) + if request_options is not None + else {} + ), + } + ) + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(AccessGroupList, _response.json()) # type: ignore @@ -96,6 +123,7 @@ async def list( offset: typing.Optional[float] = None, limit: typing.Optional[float] = None, sort: typing.Optional[AccessGroupsListRequestSort] = None, + request_options: typing.Optional[RequestOptions] = None, ) -> AccessGroupList: """ Get a list of access groups for a site

Required scope | `users:read` @@ -108,24 +136,48 @@ async def list( - limit: typing.Optional[float]. Maximum number of records to be returned (max limit: 100) - sort: typing.Optional[AccessGroupsListRequestSort]. Sort string to use when ordering access groups - Can be prefixed with a `-` to reverse the sort (ex. `-CreatedOn`)--- - from webflow import AccessGroupsListRequestSort + Can be prefixed with a `-` to reverse the sort (ex. `-CreatedOn`) + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- from webflow.client import AsyncWebflow client = AsyncWebflow( access_token="YOUR_ACCESS_TOKEN", ) await client.access_groups.list( - site_id="site-id", - sort=AccessGroupsListRequestSort.CREATED_ON_ASCENDING, + site_id="site_id", ) """ _response = await self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/accessgroups"), - params=remove_none_from_dict({"offset": offset, "limit": limit, "sort": sort}), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/accessgroups" + ), + params=jsonable_encoder( + remove_none_from_dict( + { + "offset": offset, + "limit": limit, + "sort": sort, + **( + request_options.get("additional_query_parameters", {}) + if request_options is not None + else {} + ), + } + ) + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(AccessGroupList, _response.json()) # type: ignore diff --git a/src/webflow/resources/assets/client.py b/src/webflow/resources/assets/client.py index 8beb2c3..92e58aa 100644 --- a/src/webflow/resources/assets/client.py +++ b/src/webflow/resources/assets/client.py @@ -7,6 +7,8 @@ from ...core.api_error import ApiError from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.jsonable_encoder import jsonable_encoder +from ...core.remove_none_from_dict import remove_none_from_dict +from ...core.request_options import RequestOptions from ...errors.bad_request_error import BadRequestError from ...errors.internal_server_error import InternalServerError from ...errors.not_found_error import NotFoundError @@ -30,12 +32,14 @@ class AssetsClient: def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper - def list(self, site_id: str) -> typing.List[Asset]: + def list(self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> typing.List[Asset]: """ List assets for a given site

Required scope | `assets:read` Parameters: - site_id: str. Unique identifier for a Site + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -43,14 +47,28 @@ def list(self, site_id: str) -> typing.List[Asset]: access_token="YOUR_ACCESS_TOKEN", ) client.assets.list( - site_id="site-id", + site_id="site_id", ) """ _response = self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/assets"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/assets" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(typing.List[Asset], _response.json()) # type: ignore @@ -71,7 +89,13 @@ def list(self, site_id: str) -> typing.List[Asset]: raise ApiError(status_code=_response.status_code, body=_response_json) def create( - self, site_id: str, *, file_name: str, file_hash: str, parent_folder: typing.Optional[str] = OMIT + self, + site_id: str, + *, + file_name: str, + file_hash: str, + parent_folder: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> AssetUpload: """ Create a new asset entry.

This endpoint generates a response with the following information: `uploadUrl` and `uploadDetails`. You can use these two properties to [upload the file to Amazon s3 by making a POST](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html) request to the `uploadUrl` with the `uploadDetails` object as your header information in the request.

Required scope | `assets:write` @@ -84,6 +108,8 @@ def create( - file_hash: str. MD5 hash of the file - parent_folder: typing.Optional[str]. id of the Asset folder (optional) + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -91,7 +117,7 @@ def create( access_token="YOUR_ACCESS_TOKEN", ) client.assets.create( - site_id="site-id", + site_id="site_id", file_name="file.png", file_hash="3c7d87c9575702bc3b1e991f4d3c638e", parent_folder="6436b1ce5281cace05b65aea", @@ -102,10 +128,29 @@ def create( _request["parentFolder"] = parent_folder _response = self._client_wrapper.httpx_client.request( "POST", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/assets"), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/assets" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(AssetUpload, _response.json()) # type: ignore @@ -125,12 +170,14 @@ def create( raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def get(self, asset_id: str) -> Asset: + def get(self, asset_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Asset: """ Get an Asset

Required scope | `assets:read` Parameters: - asset_id: str. Unique identifier for an Asset on a site + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -138,14 +185,26 @@ def get(self, asset_id: str) -> Asset: access_token="YOUR_ACCESS_TOKEN", ) client.assets.get( - asset_id="asset-id", + asset_id="asset_id", ) """ _response = self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"assets/{asset_id}"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"assets/{jsonable_encoder(asset_id)}"), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Asset, _response.json()) # type: ignore @@ -165,12 +224,14 @@ def get(self, asset_id: str) -> Asset: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def delete(self, asset_id: str) -> None: + def delete(self, asset_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> None: """ Delete an Asset Parameters: - asset_id: str. Unique identifier for an Asset on a site + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -178,14 +239,26 @@ def delete(self, asset_id: str) -> None: access_token="YOUR_ACCESS_TOKEN", ) client.assets.delete( - asset_id="asset-id", + asset_id="asset_id", ) """ _response = self._client_wrapper.httpx_client.request( "DELETE", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"assets/{asset_id}"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"assets/{jsonable_encoder(asset_id)}"), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return @@ -205,12 +278,79 @@ def delete(self, asset_id: str) -> None: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def list_folders(self, site_id: str) -> AssetFolderList: + def update( + self, asset_id: str, *, display_name: str, request_options: typing.Optional[RequestOptions] = None + ) -> Asset: + """ + Update an Asset

Required scope | `assets:write` + + Parameters: + - asset_id: str. Unique identifier for an Asset on a site + + - display_name: str. file name including file extension + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- + from webflow.client import Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.assets.update( + asset_id="asset_id", + display_name="file.png", + ) + """ + _response = self._client_wrapper.httpx_client.request( + "PATCH", + urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"assets/{jsonable_encoder(asset_id)}"), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder({"displayName": display_name}) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder({"displayName": display_name}), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, + ) + if 200 <= _response.status_code < 300: + return pydantic.parse_obj_as(Asset, _response.json()) # type: ignore + if _response.status_code == 400: + raise BadRequestError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 401: + raise UnauthorizedError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 404: + raise NotFoundError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 429: + raise TooManyRequestsError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 500: + raise InternalServerError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + try: + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + def list_folders(self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> AssetFolderList: """ List Asset Folders within a given site

Required scope | `assets:read` Parameters: - site_id: str. Unique identifier for a Site + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -218,14 +358,28 @@ def list_folders(self, site_id: str) -> AssetFolderList: access_token="YOUR_ACCESS_TOKEN", ) client.assets.list_folders( - site_id="site-id", + site_id="site_id", ) """ _response = self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/asset_folders"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/asset_folders" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(AssetFolderList, _response.json()) # type: ignore @@ -246,7 +400,12 @@ def list_folders(self, site_id: str) -> AssetFolderList: raise ApiError(status_code=_response.status_code, body=_response_json) def create_folder( - self, site_id: str, *, display_name: str, parent_folder: typing.Optional[str] = OMIT + self, + site_id: str, + *, + display_name: str, + parent_folder: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> AssetFolder: """ Create an Asset Folder within a given site

Required scope | `assets:write` @@ -257,6 +416,8 @@ def create_folder( - display_name: str. A human readable name for the Asset Folder - parent_folder: typing.Optional[str]. An (optional) pointer to a parent Asset Folder (or null for root) + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -264,7 +425,7 @@ def create_folder( access_token="YOUR_ACCESS_TOKEN", ) client.assets.create_folder( - site_id="site-id", + site_id="site_id", display_name="my asset folder", parent_folder="6390c49774a71f99f21a08eb", ) @@ -274,10 +435,29 @@ def create_folder( _request["parentFolder"] = parent_folder _response = self._client_wrapper.httpx_client.request( "POST", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/asset_folders"), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/asset_folders" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(AssetFolder, _response.json()) # type: ignore @@ -297,12 +477,16 @@ def create_folder( raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def get_folder(self, asset_folder_id: str) -> AssetFolder: + def get_folder( + self, asset_folder_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AssetFolder: """ Get details about a specific Asset Folder

Required scope | `assets:read` Parameters: - asset_folder_id: str. Unique identifier for an Asset Folder + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -310,14 +494,28 @@ def get_folder(self, asset_folder_id: str) -> AssetFolder: access_token="YOUR_ACCESS_TOKEN", ) client.assets.get_folder( - asset_folder_id="asset-folder-id", + asset_folder_id="asset_folder_id", ) """ _response = self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"asset_folders/{asset_folder_id}"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"asset_folders/{jsonable_encoder(asset_folder_id)}" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(AssetFolder, _response.json()) # type: ignore @@ -342,12 +540,16 @@ class AsyncAssetsClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): self._client_wrapper = client_wrapper - async def list(self, site_id: str) -> typing.List[Asset]: + async def list( + self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> typing.List[Asset]: """ List assets for a given site

Required scope | `assets:read` Parameters: - site_id: str. Unique identifier for a Site + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -355,14 +557,28 @@ async def list(self, site_id: str) -> typing.List[Asset]: access_token="YOUR_ACCESS_TOKEN", ) await client.assets.list( - site_id="site-id", + site_id="site_id", ) """ _response = await self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/assets"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/assets" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(typing.List[Asset], _response.json()) # type: ignore @@ -383,7 +599,13 @@ async def list(self, site_id: str) -> typing.List[Asset]: raise ApiError(status_code=_response.status_code, body=_response_json) async def create( - self, site_id: str, *, file_name: str, file_hash: str, parent_folder: typing.Optional[str] = OMIT + self, + site_id: str, + *, + file_name: str, + file_hash: str, + parent_folder: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> AssetUpload: """ Create a new asset entry.

This endpoint generates a response with the following information: `uploadUrl` and `uploadDetails`. You can use these two properties to [upload the file to Amazon s3 by making a POST](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html) request to the `uploadUrl` with the `uploadDetails` object as your header information in the request.

Required scope | `assets:write` @@ -396,6 +618,8 @@ async def create( - file_hash: str. MD5 hash of the file - parent_folder: typing.Optional[str]. id of the Asset folder (optional) + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -403,7 +627,7 @@ async def create( access_token="YOUR_ACCESS_TOKEN", ) await client.assets.create( - site_id="site-id", + site_id="site_id", file_name="file.png", file_hash="3c7d87c9575702bc3b1e991f4d3c638e", parent_folder="6436b1ce5281cace05b65aea", @@ -414,10 +638,29 @@ async def create( _request["parentFolder"] = parent_folder _response = await self._client_wrapper.httpx_client.request( "POST", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/assets"), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/assets" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(AssetUpload, _response.json()) # type: ignore @@ -437,12 +680,14 @@ async def create( raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def get(self, asset_id: str) -> Asset: + async def get(self, asset_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Asset: """ Get an Asset

Required scope | `assets:read` Parameters: - asset_id: str. Unique identifier for an Asset on a site + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -450,14 +695,26 @@ async def get(self, asset_id: str) -> Asset: access_token="YOUR_ACCESS_TOKEN", ) await client.assets.get( - asset_id="asset-id", + asset_id="asset_id", ) """ _response = await self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"assets/{asset_id}"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"assets/{jsonable_encoder(asset_id)}"), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Asset, _response.json()) # type: ignore @@ -477,12 +734,14 @@ async def get(self, asset_id: str) -> Asset: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def delete(self, asset_id: str) -> None: + async def delete(self, asset_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> None: """ Delete an Asset Parameters: - asset_id: str. Unique identifier for an Asset on a site + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -490,14 +749,26 @@ async def delete(self, asset_id: str) -> None: access_token="YOUR_ACCESS_TOKEN", ) await client.assets.delete( - asset_id="asset-id", + asset_id="asset_id", ) """ _response = await self._client_wrapper.httpx_client.request( "DELETE", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"assets/{asset_id}"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"assets/{jsonable_encoder(asset_id)}"), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return @@ -517,12 +788,81 @@ async def delete(self, asset_id: str) -> None: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def list_folders(self, site_id: str) -> AssetFolderList: + async def update( + self, asset_id: str, *, display_name: str, request_options: typing.Optional[RequestOptions] = None + ) -> Asset: + """ + Update an Asset

Required scope | `assets:write` + + Parameters: + - asset_id: str. Unique identifier for an Asset on a site + + - display_name: str. file name including file extension + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- + from webflow.client import AsyncWebflow + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + await client.assets.update( + asset_id="asset_id", + display_name="file.png", + ) + """ + _response = await self._client_wrapper.httpx_client.request( + "PATCH", + urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"assets/{jsonable_encoder(asset_id)}"), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder({"displayName": display_name}) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder({"displayName": display_name}), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, + ) + if 200 <= _response.status_code < 300: + return pydantic.parse_obj_as(Asset, _response.json()) # type: ignore + if _response.status_code == 400: + raise BadRequestError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 401: + raise UnauthorizedError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 404: + raise NotFoundError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 429: + raise TooManyRequestsError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 500: + raise InternalServerError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + try: + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + async def list_folders( + self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AssetFolderList: """ List Asset Folders within a given site

Required scope | `assets:read` Parameters: - site_id: str. Unique identifier for a Site + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -530,14 +870,28 @@ async def list_folders(self, site_id: str) -> AssetFolderList: access_token="YOUR_ACCESS_TOKEN", ) await client.assets.list_folders( - site_id="site-id", + site_id="site_id", ) """ _response = await self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/asset_folders"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/asset_folders" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(AssetFolderList, _response.json()) # type: ignore @@ -558,7 +912,12 @@ async def list_folders(self, site_id: str) -> AssetFolderList: raise ApiError(status_code=_response.status_code, body=_response_json) async def create_folder( - self, site_id: str, *, display_name: str, parent_folder: typing.Optional[str] = OMIT + self, + site_id: str, + *, + display_name: str, + parent_folder: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> AssetFolder: """ Create an Asset Folder within a given site

Required scope | `assets:write` @@ -569,6 +928,8 @@ async def create_folder( - display_name: str. A human readable name for the Asset Folder - parent_folder: typing.Optional[str]. An (optional) pointer to a parent Asset Folder (or null for root) + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -576,7 +937,7 @@ async def create_folder( access_token="YOUR_ACCESS_TOKEN", ) await client.assets.create_folder( - site_id="site-id", + site_id="site_id", display_name="my asset folder", parent_folder="6390c49774a71f99f21a08eb", ) @@ -586,10 +947,29 @@ async def create_folder( _request["parentFolder"] = parent_folder _response = await self._client_wrapper.httpx_client.request( "POST", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/asset_folders"), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/asset_folders" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(AssetFolder, _response.json()) # type: ignore @@ -609,12 +989,16 @@ async def create_folder( raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def get_folder(self, asset_folder_id: str) -> AssetFolder: + async def get_folder( + self, asset_folder_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AssetFolder: """ Get details about a specific Asset Folder

Required scope | `assets:read` Parameters: - asset_folder_id: str. Unique identifier for an Asset Folder + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -622,14 +1006,28 @@ async def get_folder(self, asset_folder_id: str) -> AssetFolder: access_token="YOUR_ACCESS_TOKEN", ) await client.assets.get_folder( - asset_folder_id="asset-folder-id", + asset_folder_id="asset_folder_id", ) """ _response = await self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"asset_folders/{asset_folder_id}"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"asset_folders/{jsonable_encoder(asset_folder_id)}" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(AssetFolder, _response.json()) # type: ignore diff --git a/src/webflow/resources/collections/__init__.py b/src/webflow/resources/collections/__init__.py index e06a225..ea60c9c 100644 --- a/src/webflow/resources/collections/__init__.py +++ b/src/webflow/resources/collections/__init__.py @@ -1,5 +1,5 @@ # This file was auto-generated by Fern from our API Definition. -from .resources import ItemsPublishItemResponse, fields, items +from .resources import BulkCollectionItemFieldData, FieldCreateType, ItemsPublishItemResponse, fields, items -__all__ = ["ItemsPublishItemResponse", "fields", "items"] +__all__ = ["BulkCollectionItemFieldData", "FieldCreateType", "ItemsPublishItemResponse", "fields", "items"] diff --git a/src/webflow/resources/collections/client.py b/src/webflow/resources/collections/client.py index f709baf..669cb06 100644 --- a/src/webflow/resources/collections/client.py +++ b/src/webflow/resources/collections/client.py @@ -7,6 +7,8 @@ from ...core.api_error import ApiError from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.jsonable_encoder import jsonable_encoder +from ...core.remove_none_from_dict import remove_none_from_dict +from ...core.request_options import RequestOptions from ...errors.bad_request_error import BadRequestError from ...errors.internal_server_error import InternalServerError from ...errors.not_found_error import NotFoundError @@ -32,12 +34,14 @@ def __init__(self, *, client_wrapper: SyncClientWrapper): self.fields = FieldsClient(client_wrapper=self._client_wrapper) self.items = ItemsClient(client_wrapper=self._client_wrapper) - def list(self, site_id: str) -> CollectionList: + def list(self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> CollectionList: """ List of all Collections within a Site.

Required scope | `cms:read` Parameters: - site_id: str. Unique identifier for a Site + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -45,14 +49,28 @@ def list(self, site_id: str) -> CollectionList: access_token="YOUR_ACCESS_TOKEN", ) client.collections.list( - site_id="site-id", + site_id="site_id", ) """ _response = self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/collections"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/collections" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(CollectionList, _response.json()) # type: ignore @@ -73,7 +91,13 @@ def list(self, site_id: str) -> CollectionList: raise ApiError(status_code=_response.status_code, body=_response_json) def create( - self, site_id: str, *, display_name: str, singular_name: str, slug: typing.Optional[str] = OMIT + self, + site_id: str, + *, + display_name: str, + singular_name: str, + slug: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> Collection: """ Create a Collection for a site.

Required scope | `cms:write` @@ -86,16 +110,49 @@ def create( - singular_name: str. Singular name of each item. - slug: typing.Optional[str]. Part of a URL that identifier + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- + from webflow.client import Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.collections.create( + site_id="site_id", + display_name="Blog Posts", + singular_name="Blog Post", + slug="posts", + ) """ _request: typing.Dict[str, typing.Any] = {"displayName": display_name, "singularName": singular_name} if slug is not OMIT: _request["slug"] = slug _response = self._client_wrapper.httpx_client.request( "POST", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/collections"), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/collections" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Collection, _response.json()) # type: ignore @@ -115,12 +172,14 @@ def create( raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def get(self, collection_id: str) -> Collection: + def get(self, collection_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Collection: """ Get the full details of a collection from its ID.

Required scope | `cms:read` Parameters: - collection_id: str. Unique identifier for a Collection + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -128,14 +187,28 @@ def get(self, collection_id: str) -> Collection: access_token="YOUR_ACCESS_TOKEN", ) client.collections.get( - collection_id="collection-id", + collection_id="collection_id", ) """ _response = self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"collections/{collection_id}"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"collections/{jsonable_encoder(collection_id)}" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Collection, _response.json()) # type: ignore @@ -155,12 +228,14 @@ def get(self, collection_id: str) -> Collection: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def delete_collection(self, collection_id: str) -> None: + def delete_collection(self, collection_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> None: """ Delete a collection using its ID.

Required scope | `cms:write` Parameters: - collection_id: str. Unique identifier for a Collection + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -168,14 +243,28 @@ def delete_collection(self, collection_id: str) -> None: access_token="YOUR_ACCESS_TOKEN", ) client.collections.delete_collection( - collection_id="collection-id", + collection_id="collection_id", ) """ _response = self._client_wrapper.httpx_client.request( "DELETE", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"collections/{collection_id}"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"collections/{jsonable_encoder(collection_id)}" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return @@ -195,7 +284,9 @@ def delete_collection(self, collection_id: str) -> None: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def delete(self, collection_id: str, field_id: str) -> None: + def delete( + self, collection_id: str, field_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> None: """ Delete a custom field in a collection. This endpoint does not currently support bulk deletion.

Required scope | `cms:write` @@ -203,6 +294,8 @@ def delete(self, collection_id: str, field_id: str) -> None: - collection_id: str. Unique identifier for a Collection - field_id: str. Unique identifier for a Field in a collection + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -210,17 +303,30 @@ def delete(self, collection_id: str, field_id: str) -> None: access_token="YOUR_ACCESS_TOKEN", ) client.collections.delete( - collection_id="collection-id", - field_id="field-id", + collection_id="collection_id", + field_id="field_id", ) """ _response = self._client_wrapper.httpx_client.request( "DELETE", urllib.parse.urljoin( - f"{self._client_wrapper.get_base_url()}/", f"collections/{collection_id}/fields/{field_id}" + f"{self._client_wrapper.get_base_url()}/", + f"collections/{jsonable_encoder(collection_id)}/fields/{jsonable_encoder(field_id)}", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) ), - headers=self._client_wrapper.get_headers(), - timeout=60, + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return @@ -247,12 +353,14 @@ def __init__(self, *, client_wrapper: AsyncClientWrapper): self.fields = AsyncFieldsClient(client_wrapper=self._client_wrapper) self.items = AsyncItemsClient(client_wrapper=self._client_wrapper) - async def list(self, site_id: str) -> CollectionList: + async def list(self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> CollectionList: """ List of all Collections within a Site.

Required scope | `cms:read` Parameters: - site_id: str. Unique identifier for a Site + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -260,14 +368,28 @@ async def list(self, site_id: str) -> CollectionList: access_token="YOUR_ACCESS_TOKEN", ) await client.collections.list( - site_id="site-id", + site_id="site_id", ) """ _response = await self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/collections"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/collections" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(CollectionList, _response.json()) # type: ignore @@ -288,7 +410,13 @@ async def list(self, site_id: str) -> CollectionList: raise ApiError(status_code=_response.status_code, body=_response_json) async def create( - self, site_id: str, *, display_name: str, singular_name: str, slug: typing.Optional[str] = OMIT + self, + site_id: str, + *, + display_name: str, + singular_name: str, + slug: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> Collection: """ Create a Collection for a site.

Required scope | `cms:write` @@ -301,16 +429,49 @@ async def create( - singular_name: str. Singular name of each item. - slug: typing.Optional[str]. Part of a URL that identifier + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- + from webflow.client import AsyncWebflow + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + await client.collections.create( + site_id="site_id", + display_name="Blog Posts", + singular_name="Blog Post", + slug="posts", + ) """ _request: typing.Dict[str, typing.Any] = {"displayName": display_name, "singularName": singular_name} if slug is not OMIT: _request["slug"] = slug _response = await self._client_wrapper.httpx_client.request( "POST", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/collections"), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/collections" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Collection, _response.json()) # type: ignore @@ -330,12 +491,14 @@ async def create( raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def get(self, collection_id: str) -> Collection: + async def get(self, collection_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Collection: """ Get the full details of a collection from its ID.

Required scope | `cms:read` Parameters: - collection_id: str. Unique identifier for a Collection + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -343,14 +506,28 @@ async def get(self, collection_id: str) -> Collection: access_token="YOUR_ACCESS_TOKEN", ) await client.collections.get( - collection_id="collection-id", + collection_id="collection_id", ) """ _response = await self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"collections/{collection_id}"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"collections/{jsonable_encoder(collection_id)}" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Collection, _response.json()) # type: ignore @@ -370,12 +547,16 @@ async def get(self, collection_id: str) -> Collection: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def delete_collection(self, collection_id: str) -> None: + async def delete_collection( + self, collection_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> None: """ Delete a collection using its ID.

Required scope | `cms:write` Parameters: - collection_id: str. Unique identifier for a Collection + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -383,14 +564,28 @@ async def delete_collection(self, collection_id: str) -> None: access_token="YOUR_ACCESS_TOKEN", ) await client.collections.delete_collection( - collection_id="collection-id", + collection_id="collection_id", ) """ _response = await self._client_wrapper.httpx_client.request( "DELETE", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"collections/{collection_id}"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"collections/{jsonable_encoder(collection_id)}" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return @@ -410,7 +605,9 @@ async def delete_collection(self, collection_id: str) -> None: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def delete(self, collection_id: str, field_id: str) -> None: + async def delete( + self, collection_id: str, field_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> None: """ Delete a custom field in a collection. This endpoint does not currently support bulk deletion.

Required scope | `cms:write` @@ -418,6 +615,8 @@ async def delete(self, collection_id: str, field_id: str) -> None: - collection_id: str. Unique identifier for a Collection - field_id: str. Unique identifier for a Field in a collection + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -425,17 +624,30 @@ async def delete(self, collection_id: str, field_id: str) -> None: access_token="YOUR_ACCESS_TOKEN", ) await client.collections.delete( - collection_id="collection-id", - field_id="field-id", + collection_id="collection_id", + field_id="field_id", ) """ _response = await self._client_wrapper.httpx_client.request( "DELETE", urllib.parse.urljoin( - f"{self._client_wrapper.get_base_url()}/", f"collections/{collection_id}/fields/{field_id}" + f"{self._client_wrapper.get_base_url()}/", + f"collections/{jsonable_encoder(collection_id)}/fields/{jsonable_encoder(field_id)}", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) ), - headers=self._client_wrapper.get_headers(), - timeout=60, + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return diff --git a/src/webflow/resources/collections/resources/__init__.py b/src/webflow/resources/collections/resources/__init__.py index b288a47..5b63931 100644 --- a/src/webflow/resources/collections/resources/__init__.py +++ b/src/webflow/resources/collections/resources/__init__.py @@ -1,6 +1,7 @@ # This file was auto-generated by Fern from our API Definition. from . import fields, items -from .items import ItemsPublishItemResponse +from .fields import FieldCreateType +from .items import BulkCollectionItemFieldData, ItemsPublishItemResponse -__all__ = ["ItemsPublishItemResponse", "fields", "items"] +__all__ = ["BulkCollectionItemFieldData", "FieldCreateType", "ItemsPublishItemResponse", "fields", "items"] diff --git a/src/webflow/resources/collections/resources/fields/__init__.py b/src/webflow/resources/collections/resources/fields/__init__.py index f3ea265..5a5b167 100644 --- a/src/webflow/resources/collections/resources/fields/__init__.py +++ b/src/webflow/resources/collections/resources/fields/__init__.py @@ -1,2 +1,5 @@ # This file was auto-generated by Fern from our API Definition. +from .types import FieldCreateType + +__all__ = ["FieldCreateType"] diff --git a/src/webflow/resources/collections/resources/fields/client.py b/src/webflow/resources/collections/resources/fields/client.py index 779ece9..9622f64 100644 --- a/src/webflow/resources/collections/resources/fields/client.py +++ b/src/webflow/resources/collections/resources/fields/client.py @@ -7,12 +7,15 @@ from .....core.api_error import ApiError from .....core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from .....core.jsonable_encoder import jsonable_encoder +from .....core.remove_none_from_dict import remove_none_from_dict +from .....core.request_options import RequestOptions from .....errors.bad_request_error import BadRequestError from .....errors.internal_server_error import InternalServerError from .....errors.not_found_error import NotFoundError from .....errors.too_many_requests_error import TooManyRequestsError from .....errors.unauthorized_error import UnauthorizedError from .....types.field import Field +from .types.field_create_type import FieldCreateType try: import pydantic.v1 as pydantic # type: ignore @@ -27,21 +30,76 @@ class FieldsClient: def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper - def create(self, collection_id: str, *, request: Field) -> Field: + def create( + self, + collection_id: str, + *, + is_required: typing.Optional[bool] = OMIT, + type: FieldCreateType, + display_name: str, + help_text: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> Field: """ Create a custom field in a collection.

Slugs must be all lowercase letters without spaces. If you pass a string with uppercase letters and/or spaces to the "Slug" property, Webflow will convert the slug to lowercase and replace spaces with "-."

Only some field types can be created through the API. This endpoint does not currently support bulk creation.

Required scope | `cms:write` Parameters: - collection_id: str. Unique identifier for a Collection - - request: Field. + - is_required: typing.Optional[bool]. define whether a field is required in a collection + + - type: FieldCreateType. Choose these appropriate field type for your collection data + + - display_name: str. The name of a field + + - help_text: typing.Optional[str]. Additional text to help anyone filling out this field + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- + from webflow.client import Webflow + from webflow.resources.collections import FieldCreateType + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.collections.fields.create( + collection_id="collection_id", + is_required=False, + type=FieldCreateType.RICH_TEXT, + display_name="Post Body", + help_text="Add the body of your post here", + ) """ + _request: typing.Dict[str, typing.Any] = {"type": type, "displayName": display_name} + if is_required is not OMIT: + _request["isRequired"] = is_required + if help_text is not OMIT: + _request["helpText"] = help_text _response = self._client_wrapper.httpx_client.request( "POST", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"collections/{collection_id}/fields"), - json=jsonable_encoder(request), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"collections/{jsonable_encoder(collection_id)}/fields" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Field, _response.json()) # type: ignore @@ -69,6 +127,7 @@ def update( is_required: typing.Optional[bool] = OMIT, display_name: typing.Optional[str] = OMIT, help_text: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> Field: """ Update a custom field in a collection.

Required scope | `cms:write` @@ -83,6 +142,21 @@ def update( - display_name: typing.Optional[str]. The name of a field - help_text: typing.Optional[str]. Additional text to help anyone filling out this field + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- + from webflow.client import Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.collections.fields.update( + collection_id="collection_id", + field_id="field_id", + is_required=False, + display_name="Post Body", + help_text="Add the body of your post here", + ) """ _request: typing.Dict[str, typing.Any] = {} if is_required is not OMIT: @@ -94,11 +168,29 @@ def update( _response = self._client_wrapper.httpx_client.request( "PATCH", urllib.parse.urljoin( - f"{self._client_wrapper.get_base_url()}/", f"collections/{collection_id}/fields/{field_id}" + f"{self._client_wrapper.get_base_url()}/", + f"collections/{jsonable_encoder(collection_id)}/fields/{jsonable_encoder(field_id)}", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) ), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Field, _response.json()) # type: ignore @@ -123,21 +215,76 @@ class AsyncFieldsClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): self._client_wrapper = client_wrapper - async def create(self, collection_id: str, *, request: Field) -> Field: + async def create( + self, + collection_id: str, + *, + is_required: typing.Optional[bool] = OMIT, + type: FieldCreateType, + display_name: str, + help_text: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> Field: """ Create a custom field in a collection.

Slugs must be all lowercase letters without spaces. If you pass a string with uppercase letters and/or spaces to the "Slug" property, Webflow will convert the slug to lowercase and replace spaces with "-."

Only some field types can be created through the API. This endpoint does not currently support bulk creation.

Required scope | `cms:write` Parameters: - collection_id: str. Unique identifier for a Collection - - request: Field. + - is_required: typing.Optional[bool]. define whether a field is required in a collection + + - type: FieldCreateType. Choose these appropriate field type for your collection data + + - display_name: str. The name of a field + + - help_text: typing.Optional[str]. Additional text to help anyone filling out this field + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- + from webflow.client import AsyncWebflow + from webflow.resources.collections import FieldCreateType + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + await client.collections.fields.create( + collection_id="collection_id", + is_required=False, + type=FieldCreateType.RICH_TEXT, + display_name="Post Body", + help_text="Add the body of your post here", + ) """ + _request: typing.Dict[str, typing.Any] = {"type": type, "displayName": display_name} + if is_required is not OMIT: + _request["isRequired"] = is_required + if help_text is not OMIT: + _request["helpText"] = help_text _response = await self._client_wrapper.httpx_client.request( "POST", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"collections/{collection_id}/fields"), - json=jsonable_encoder(request), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"collections/{jsonable_encoder(collection_id)}/fields" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Field, _response.json()) # type: ignore @@ -165,6 +312,7 @@ async def update( is_required: typing.Optional[bool] = OMIT, display_name: typing.Optional[str] = OMIT, help_text: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> Field: """ Update a custom field in a collection.

Required scope | `cms:write` @@ -179,6 +327,21 @@ async def update( - display_name: typing.Optional[str]. The name of a field - help_text: typing.Optional[str]. Additional text to help anyone filling out this field + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- + from webflow.client import AsyncWebflow + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + await client.collections.fields.update( + collection_id="collection_id", + field_id="field_id", + is_required=False, + display_name="Post Body", + help_text="Add the body of your post here", + ) """ _request: typing.Dict[str, typing.Any] = {} if is_required is not OMIT: @@ -190,11 +353,29 @@ async def update( _response = await self._client_wrapper.httpx_client.request( "PATCH", urllib.parse.urljoin( - f"{self._client_wrapper.get_base_url()}/", f"collections/{collection_id}/fields/{field_id}" + f"{self._client_wrapper.get_base_url()}/", + f"collections/{jsonable_encoder(collection_id)}/fields/{jsonable_encoder(field_id)}", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) ), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Field, _response.json()) # type: ignore diff --git a/src/webflow/resources/collections/resources/fields/types/__init__.py b/src/webflow/resources/collections/resources/fields/types/__init__.py new file mode 100644 index 0000000..c17230e --- /dev/null +++ b/src/webflow/resources/collections/resources/fields/types/__init__.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +from .field_create_type import FieldCreateType + +__all__ = ["FieldCreateType"] diff --git a/src/webflow/resources/collections/resources/fields/types/field_create_type.py b/src/webflow/resources/collections/resources/fields/types/field_create_type.py new file mode 100644 index 0000000..db7db4a --- /dev/null +++ b/src/webflow/resources/collections/resources/fields/types/field_create_type.py @@ -0,0 +1,69 @@ +# This file was auto-generated by Fern from our API Definition. + +import enum +import typing + +T_Result = typing.TypeVar("T_Result") + + +class FieldCreateType(str, enum.Enum): + """ + Choose these appropriate field type for your collection data + """ + + PLAIN_TEXT = "PlainText" + RICH_TEXT = "RichText" + IMAGE = "Image" + MULTI_IMAGE = "MultiImage" + VIDEO = "Video" + LINK = "Link" + EMAIL = "Email" + PHONE = "Phone" + NUMBER = "Number" + DATE_TIME = "DateTime" + BOOLEAN = "Boolean" + COLOR = "Color" + FILE = "File" + + def visit( + self, + plain_text: typing.Callable[[], T_Result], + rich_text: typing.Callable[[], T_Result], + image: typing.Callable[[], T_Result], + multi_image: typing.Callable[[], T_Result], + video: typing.Callable[[], T_Result], + link: typing.Callable[[], T_Result], + email: typing.Callable[[], T_Result], + phone: typing.Callable[[], T_Result], + number: typing.Callable[[], T_Result], + date_time: typing.Callable[[], T_Result], + boolean: typing.Callable[[], T_Result], + color: typing.Callable[[], T_Result], + file: typing.Callable[[], T_Result], + ) -> T_Result: + if self is FieldCreateType.PLAIN_TEXT: + return plain_text() + if self is FieldCreateType.RICH_TEXT: + return rich_text() + if self is FieldCreateType.IMAGE: + return image() + if self is FieldCreateType.MULTI_IMAGE: + return multi_image() + if self is FieldCreateType.VIDEO: + return video() + if self is FieldCreateType.LINK: + return link() + if self is FieldCreateType.EMAIL: + return email() + if self is FieldCreateType.PHONE: + return phone() + if self is FieldCreateType.NUMBER: + return number() + if self is FieldCreateType.DATE_TIME: + return date_time() + if self is FieldCreateType.BOOLEAN: + return boolean() + if self is FieldCreateType.COLOR: + return color() + if self is FieldCreateType.FILE: + return file() diff --git a/src/webflow/resources/collections/resources/items/__init__.py b/src/webflow/resources/collections/resources/items/__init__.py index f090d60..f9fc28c 100644 --- a/src/webflow/resources/collections/resources/items/__init__.py +++ b/src/webflow/resources/collections/resources/items/__init__.py @@ -1,5 +1,5 @@ # This file was auto-generated by Fern from our API Definition. -from .types import ItemsPublishItemResponse +from .types import BulkCollectionItemFieldData, ItemsPublishItemResponse -__all__ = ["ItemsPublishItemResponse"] +__all__ = ["BulkCollectionItemFieldData", "ItemsPublishItemResponse"] diff --git a/src/webflow/resources/collections/resources/items/client.py b/src/webflow/resources/collections/resources/items/client.py index 83fd760..cfdbae4 100644 --- a/src/webflow/resources/collections/resources/items/client.py +++ b/src/webflow/resources/collections/resources/items/client.py @@ -8,6 +8,7 @@ from .....core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from .....core.jsonable_encoder import jsonable_encoder from .....core.remove_none_from_dict import remove_none_from_dict +from .....core.request_options import RequestOptions from .....errors.bad_request_error import BadRequestError from .....errors.internal_server_error import InternalServerError from .....errors.not_found_error import NotFoundError @@ -15,6 +16,7 @@ from .....errors.unauthorized_error import UnauthorizedError from .....types.collection_item import CollectionItem from .....types.collection_item_list import CollectionItemList +from .types.bulk_collection_item_field_data import BulkCollectionItemFieldData from .types.items_publish_item_response import ItemsPublishItemResponse try: @@ -31,17 +33,27 @@ def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper def list_items( - self, collection_id: str, *, offset: typing.Optional[float] = None, limit: typing.Optional[float] = None + self, + collection_id: str, + *, + cms_locale_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + offset: typing.Optional[float] = None, + limit: typing.Optional[float] = None, + request_options: typing.Optional[RequestOptions] = None, ) -> CollectionItemList: """ - List of all Items within a Collection.

Required scope | `cms:read` + List of all Items within a Collection.

Required scope | `CMS:read` Parameters: - collection_id: str. Unique identifier for a Collection + - cms_locale_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]]. Unique identifiers for CMS Locales. These UIDs are different from the Site locale identifier and are listed as `cmsLocaleId` in the Sites response. Applicable when using localization. + - offset: typing.Optional[float]. Offset used for pagination if the results have more than limit records - limit: typing.Optional[float]. Maximum number of records to be returned (max limit: 100) + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -49,15 +61,39 @@ def list_items( access_token="YOUR_ACCESS_TOKEN", ) client.collections.items.list_items( - collection_id="collection-id", + collection_id="collection_id", ) """ _response = self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"collections/{collection_id}/items"), - params=remove_none_from_dict({"offset": offset, "limit": limit}), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"collections/{jsonable_encoder(collection_id)}/items" + ), + params=jsonable_encoder( + remove_none_from_dict( + { + "cmsLocaleIds": cms_locale_ids, + "offset": offset, + "limit": limit, + **( + request_options.get("additional_query_parameters", {}) + if request_options is not None + else {} + ), + } + ) + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(CollectionItemList, _response.json()) # type: ignore @@ -77,37 +113,258 @@ def list_items( raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def create_item(self, collection_id: str, *, request: CollectionItem) -> None: + def create_item( + self, collection_id: str, *, request: CollectionItem, request_options: typing.Optional[RequestOptions] = None + ) -> None: """ - Create Item in a Collection.

Required scope | `cms:write` + Create Item in a Collection.

To create items across multiple locales, please use this endpoint.

Required scope | `CMS:write` Parameters: - collection_id: str. Unique identifier for a Collection - request: CollectionItem. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- - from webflow import CollectionItem + from webflow import CollectionItem, CollectionItemFieldData from webflow.client import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) client.collections.items.create_item( - collection_id="collection-id", + collection_id="collection_id", request=CollectionItem( id="580e64008c9a982ac9b8b754", + cms_locale_id="653ad57de882f528b32e810e", last_published="2023-03-17T18:47:35.560Z", last_updated="2023-03-17T18:47:35.560Z", created_on="2023-03-17T18:47:35.560Z", + field_data=CollectionItemFieldData( + name="My new item", + slug="my-new-item", + ), ), ) """ _response = self._client_wrapper.httpx_client.request( "POST", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"collections/{collection_id}/items"), - json=jsonable_encoder(request), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"collections/{jsonable_encoder(collection_id)}/items" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, + ) + if 200 <= _response.status_code < 300: + return + if _response.status_code == 400: + raise BadRequestError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 401: + raise UnauthorizedError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 404: + raise NotFoundError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 429: + raise TooManyRequestsError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 500: + raise InternalServerError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + try: + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + def create_item_live( + self, collection_id: str, *, request: CollectionItem, request_options: typing.Optional[RequestOptions] = None + ) -> None: + """ + Create live Item in a Collection. This Item will be published to the live site.

To create items across multiple locales, please use this endpoint.

Required scope | `CMS:write` + + Parameters: + - collection_id: str. Unique identifier for a Collection + + - request: CollectionItem. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- + from webflow import CollectionItem, CollectionItemFieldData + from webflow.client import Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.collections.items.create_item_live( + collection_id="collection_id", + request=CollectionItem( + id="580e64008c9a982ac9b8b754", + cms_locale_id="653ad57de882f528b32e810e", + last_published="2023-03-17T18:47:35.560Z", + last_updated="2023-03-17T18:47:35.560Z", + created_on="2023-03-17T18:47:35.560Z", + field_data=CollectionItemFieldData( + name="My new item", + slug="my-new-item", + ), + ), + ) + """ + _response = self._client_wrapper.httpx_client.request( + "POST", + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"collections/{jsonable_encoder(collection_id)}/items/live" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, + ) + if 200 <= _response.status_code < 300: + return + if _response.status_code == 400: + raise BadRequestError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 401: + raise UnauthorizedError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 404: + raise NotFoundError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 429: + raise TooManyRequestsError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 500: + raise InternalServerError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + try: + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + def create_item_for_multiple_locales( + self, + collection_id: str, + *, + id: str, + cms_locale_ids: typing.Optional[typing.Sequence[str]] = OMIT, + last_published: typing.Optional[str] = OMIT, + last_updated: typing.Optional[str] = OMIT, + created_on: typing.Optional[str] = OMIT, + is_archived: typing.Optional[bool] = OMIT, + is_draft: typing.Optional[bool] = OMIT, + field_data: typing.Optional[BulkCollectionItemFieldData] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> None: + """ + Create single Item in a Collection with multiple corresponding locales.

Required scope | `CMS:write` + + Parameters: + - collection_id: str. Unique identifier for a Collection + + - id: str. Unique identifier for the Item + + - cms_locale_ids: typing.Optional[typing.Sequence[str]]. Array of identifiers for the locales where the item will be crated + + - last_published: typing.Optional[str]. The date the item was last published + + - last_updated: typing.Optional[str]. The date the item was last updated + + - created_on: typing.Optional[str]. The date the item was created + + - is_archived: typing.Optional[bool]. Boolean determining if the Item is set to archived + + - is_draft: typing.Optional[bool]. Boolean determining if the Item is set to draft + + - field_data: typing.Optional[BulkCollectionItemFieldData]. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- + from webflow.client import Webflow + from webflow.resources.collections import BulkCollectionItemFieldData + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.collections.items.create_item_for_multiple_locales( + collection_id="collection_id", + id="580e64008c9a982ac9b8b754", + last_published="2023-03-17T18:47:35.560Z", + last_updated="2023-03-17T18:47:35.560Z", + created_on="2023-03-17T18:47:35.560Z", + field_data=BulkCollectionItemFieldData( + name="My new item", + slug="my-new-item", + ), + ) + """ + _request: typing.Dict[str, typing.Any] = {"id": id} + if cms_locale_ids is not OMIT: + _request["cmsLocaleIds"] = cms_locale_ids + if last_published is not OMIT: + _request["lastPublished"] = last_published + if last_updated is not OMIT: + _request["lastUpdated"] = last_updated + if created_on is not OMIT: + _request["createdOn"] = created_on + if is_archived is not OMIT: + _request["isArchived"] = is_archived + if is_draft is not OMIT: + _request["isDraft"] = is_draft + if field_data is not OMIT: + _request["fieldData"] = field_data + _response = self._client_wrapper.httpx_client.request( + "POST", + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"collections/{jsonable_encoder(collection_id)}/items/bulk" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return @@ -127,14 +384,25 @@ def create_item(self, collection_id: str, *, request: CollectionItem) -> None: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def get_item(self, collection_id: str, item_id: str) -> CollectionItem: + def get_item( + self, + collection_id: str, + item_id: str, + *, + cms_locale_id: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> CollectionItem: """ - Get details of a selected Collection Item.

Required scope | `cms:read` + Get details of a selected Collection Item.

Required scope | `CMS:read` Parameters: - collection_id: str. Unique identifier for a Collection - item_id: str. Unique identifier for an Item + + - cms_locale_id: typing.Optional[str]. Unique identifier for a CMS Locale. These UID is different from the Site locale identifier and is listed as `cmsLocaleId` in the Sites response. Applicable when using localization. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -142,17 +410,39 @@ def get_item(self, collection_id: str, item_id: str) -> CollectionItem: access_token="YOUR_ACCESS_TOKEN", ) client.collections.items.get_item( - collection_id="collection-id", - item_id="item-id", + collection_id="collection_id", + item_id="item_id", ) """ _response = self._client_wrapper.httpx_client.request( "GET", urllib.parse.urljoin( - f"{self._client_wrapper.get_base_url()}/", f"collections/{collection_id}/items/{item_id}" + f"{self._client_wrapper.get_base_url()}/", + f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}", + ), + params=jsonable_encoder( + remove_none_from_dict( + { + "cmsLocaleId": cms_locale_id, + **( + request_options.get("additional_query_parameters", {}) + if request_options is not None + else {} + ), + } + ) ), - headers=self._client_wrapper.get_headers(), - timeout=60, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(CollectionItem, _response.json()) # type: ignore @@ -172,14 +462,25 @@ def get_item(self, collection_id: str, item_id: str) -> CollectionItem: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def delete_item(self, collection_id: str, item_id: str) -> None: + def delete_item( + self, + collection_id: str, + item_id: str, + *, + cms_locale_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> None: """ - Delete an Item from a Collection. This endpoint does not currently support bulk deletion.

Required scope | `cms:write` + Delete an Item from a Collection. This endpoint does not currently support bulk deletion.

Required scope | `CMS:write` Parameters: - collection_id: str. Unique identifier for a Collection - item_id: str. Unique identifier for an Item + + - cms_locale_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]]. Unique identifiers for CMS Locales. These UIDs are different from the Site locale identifier and are listed as `cmsLocaleId` in the Sites response. Applicable when using localization. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -187,17 +488,39 @@ def delete_item(self, collection_id: str, item_id: str) -> None: access_token="YOUR_ACCESS_TOKEN", ) client.collections.items.delete_item( - collection_id="collection-id", - item_id="item-id", + collection_id="collection_id", + item_id="item_id", ) """ _response = self._client_wrapper.httpx_client.request( "DELETE", urllib.parse.urljoin( - f"{self._client_wrapper.get_base_url()}/", f"collections/{collection_id}/items/{item_id}" + f"{self._client_wrapper.get_base_url()}/", + f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}", ), - headers=self._client_wrapper.get_headers(), - timeout=60, + params=jsonable_encoder( + remove_none_from_dict( + { + "cmsLocaleIds": cms_locale_ids, + **( + request_options.get("additional_query_parameters", {}) + if request_options is not None + else {} + ), + } + ) + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return @@ -217,9 +540,16 @@ def delete_item(self, collection_id: str, item_id: str) -> None: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def update_item(self, collection_id: str, item_id: str, *, request: CollectionItem) -> CollectionItem: + def update_item( + self, + collection_id: str, + item_id: str, + *, + request: CollectionItem, + request_options: typing.Optional[RequestOptions] = None, + ) -> CollectionItem: """ - Update a selected Item in a Collection.

Required scope | `cms:write` + Update a selected Item in a Collection.

Required scope | `CMS:write` Parameters: - collection_id: str. Unique identifier for a Collection @@ -227,32 +557,57 @@ def update_item(self, collection_id: str, item_id: str, *, request: CollectionIt - item_id: str. Unique identifier for an Item - request: CollectionItem. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- - from webflow import CollectionItem + from webflow import CollectionItem, CollectionItemFieldData from webflow.client import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) client.collections.items.update_item( - collection_id="collection-id", - item_id="item-id", + collection_id="collection_id", + item_id="item_id", request=CollectionItem( id="580e64008c9a982ac9b8b754", + cms_locale_id="653ad57de882f528b32e810e", last_published="2023-03-17T18:47:35.560Z", last_updated="2023-03-17T18:47:35.560Z", created_on="2023-03-17T18:47:35.560Z", + field_data=CollectionItemFieldData( + name="My new item", + slug="my-new-item", + ), ), ) """ _response = self._client_wrapper.httpx_client.request( "PATCH", urllib.parse.urljoin( - f"{self._client_wrapper.get_base_url()}/", f"collections/{collection_id}/items/{item_id}" + f"{self._client_wrapper.get_base_url()}/", + f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}", ), - json=jsonable_encoder(request), - headers=self._client_wrapper.get_headers(), - timeout=60, + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(CollectionItem, _response.json()) # type: ignore @@ -272,14 +627,171 @@ def update_item(self, collection_id: str, item_id: str, *, request: CollectionIt raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def publish_item(self, collection_id: str, *, item_ids: typing.List[str]) -> ItemsPublishItemResponse: + def delete_item_live( + self, collection_id: str, item_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> None: + """ + Delete a live Item from a Collection. The Item will be unpublished from the live site. This endpoint does not currently support bulk deletion.

Required scope | `CMS:write` + + Parameters: + - collection_id: str. Unique identifier for a Collection + + - item_id: str. Unique identifier for an Item + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- + from webflow.client import Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.collections.items.delete_item_live( + collection_id="collection_id", + item_id="item_id", + ) + """ + _response = self._client_wrapper.httpx_client.request( + "DELETE", + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", + f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}/live", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, + ) + if 200 <= _response.status_code < 300: + return + if _response.status_code == 400: + raise BadRequestError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 401: + raise UnauthorizedError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 404: + raise NotFoundError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 429: + raise TooManyRequestsError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 500: + raise InternalServerError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + try: + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + def update_item_live( + self, + collection_id: str, + item_id: str, + *, + request: CollectionItem, + request_options: typing.Optional[RequestOptions] = None, + ) -> CollectionItem: + """ + Update a selected live Item in a Collection. The updates for this Item will be published to the live site.

Required scope | `CMS:write` + + Parameters: + - collection_id: str. Unique identifier for a Collection + + - item_id: str. Unique identifier for an Item + + - request: CollectionItem. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- + from webflow import CollectionItem, CollectionItemFieldData + from webflow.client import Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.collections.items.update_item_live( + collection_id="collection_id", + item_id="item_id", + request=CollectionItem( + id="580e64008c9a982ac9b8b754", + cms_locale_id="653ad57de882f528b32e810e", + last_published="2023-03-17T18:47:35.560Z", + last_updated="2023-03-17T18:47:35.560Z", + created_on="2023-03-17T18:47:35.560Z", + field_data=CollectionItemFieldData( + name="My new item", + slug="my-new-item", + ), + ), + ) + """ + _response = self._client_wrapper.httpx_client.request( + "PATCH", + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", + f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}/live", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, + ) + if 200 <= _response.status_code < 300: + return pydantic.parse_obj_as(CollectionItem, _response.json()) # type: ignore + if _response.status_code == 400: + raise BadRequestError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 401: + raise UnauthorizedError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 404: + raise NotFoundError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 429: + raise TooManyRequestsError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 500: + raise InternalServerError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + try: + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + def publish_item( + self, + collection_id: str, + *, + item_ids: typing.Sequence[str], + request_options: typing.Optional[RequestOptions] = None, + ) -> ItemsPublishItemResponse: """ Publish an item or multiple items.

Required scope | `cms:write` Parameters: - collection_id: str. Unique identifier for a Collection - - item_ids: typing.List[str]. + - item_ids: typing.Sequence[str]. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -287,18 +799,36 @@ def publish_item(self, collection_id: str, *, item_ids: typing.List[str]) -> Ite access_token="YOUR_ACCESS_TOKEN", ) client.collections.items.publish_item( - collection_id="collection-id", - item_ids=[], + collection_id="collection_id", + item_ids=["itemIds"], ) """ _response = self._client_wrapper.httpx_client.request( "POST", urllib.parse.urljoin( - f"{self._client_wrapper.get_base_url()}/", f"collections/{collection_id}/items/publish" + f"{self._client_wrapper.get_base_url()}/", + f"collections/{jsonable_encoder(collection_id)}/items/publish", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder({"itemIds": item_ids}) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder({"itemIds": item_ids}), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) ), - json=jsonable_encoder({"itemIds": item_ids}), - headers=self._client_wrapper.get_headers(), - timeout=60, + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(ItemsPublishItemResponse, _response.json()) # type: ignore @@ -324,17 +854,27 @@ def __init__(self, *, client_wrapper: AsyncClientWrapper): self._client_wrapper = client_wrapper async def list_items( - self, collection_id: str, *, offset: typing.Optional[float] = None, limit: typing.Optional[float] = None + self, + collection_id: str, + *, + cms_locale_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + offset: typing.Optional[float] = None, + limit: typing.Optional[float] = None, + request_options: typing.Optional[RequestOptions] = None, ) -> CollectionItemList: """ - List of all Items within a Collection.

Required scope | `cms:read` + List of all Items within a Collection.

Required scope | `CMS:read` Parameters: - collection_id: str. Unique identifier for a Collection + - cms_locale_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]]. Unique identifiers for CMS Locales. These UIDs are different from the Site locale identifier and are listed as `cmsLocaleId` in the Sites response. Applicable when using localization. + - offset: typing.Optional[float]. Offset used for pagination if the results have more than limit records - limit: typing.Optional[float]. Maximum number of records to be returned (max limit: 100) + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -342,15 +882,39 @@ async def list_items( access_token="YOUR_ACCESS_TOKEN", ) await client.collections.items.list_items( - collection_id="collection-id", + collection_id="collection_id", ) """ _response = await self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"collections/{collection_id}/items"), - params=remove_none_from_dict({"offset": offset, "limit": limit}), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"collections/{jsonable_encoder(collection_id)}/items" + ), + params=jsonable_encoder( + remove_none_from_dict( + { + "cmsLocaleIds": cms_locale_ids, + "offset": offset, + "limit": limit, + **( + request_options.get("additional_query_parameters", {}) + if request_options is not None + else {} + ), + } + ) + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(CollectionItemList, _response.json()) # type: ignore @@ -370,37 +934,258 @@ async def list_items( raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def create_item(self, collection_id: str, *, request: CollectionItem) -> None: + async def create_item( + self, collection_id: str, *, request: CollectionItem, request_options: typing.Optional[RequestOptions] = None + ) -> None: """ - Create Item in a Collection.

Required scope | `cms:write` + Create Item in a Collection.

To create items across multiple locales, please use this endpoint.

Required scope | `CMS:write` Parameters: - collection_id: str. Unique identifier for a Collection - request: CollectionItem. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- - from webflow import CollectionItem + from webflow import CollectionItem, CollectionItemFieldData from webflow.client import AsyncWebflow client = AsyncWebflow( access_token="YOUR_ACCESS_TOKEN", ) await client.collections.items.create_item( - collection_id="collection-id", + collection_id="collection_id", request=CollectionItem( id="580e64008c9a982ac9b8b754", + cms_locale_id="653ad57de882f528b32e810e", last_published="2023-03-17T18:47:35.560Z", last_updated="2023-03-17T18:47:35.560Z", created_on="2023-03-17T18:47:35.560Z", + field_data=CollectionItemFieldData( + name="My new item", + slug="my-new-item", + ), ), ) """ _response = await self._client_wrapper.httpx_client.request( "POST", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"collections/{collection_id}/items"), - json=jsonable_encoder(request), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"collections/{jsonable_encoder(collection_id)}/items" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, + ) + if 200 <= _response.status_code < 300: + return + if _response.status_code == 400: + raise BadRequestError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 401: + raise UnauthorizedError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 404: + raise NotFoundError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 429: + raise TooManyRequestsError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 500: + raise InternalServerError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + try: + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + async def create_item_live( + self, collection_id: str, *, request: CollectionItem, request_options: typing.Optional[RequestOptions] = None + ) -> None: + """ + Create live Item in a Collection. This Item will be published to the live site.

To create items across multiple locales, please use this endpoint.

Required scope | `CMS:write` + + Parameters: + - collection_id: str. Unique identifier for a Collection + + - request: CollectionItem. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- + from webflow import CollectionItem, CollectionItemFieldData + from webflow.client import AsyncWebflow + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + await client.collections.items.create_item_live( + collection_id="collection_id", + request=CollectionItem( + id="580e64008c9a982ac9b8b754", + cms_locale_id="653ad57de882f528b32e810e", + last_published="2023-03-17T18:47:35.560Z", + last_updated="2023-03-17T18:47:35.560Z", + created_on="2023-03-17T18:47:35.560Z", + field_data=CollectionItemFieldData( + name="My new item", + slug="my-new-item", + ), + ), + ) + """ + _response = await self._client_wrapper.httpx_client.request( + "POST", + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"collections/{jsonable_encoder(collection_id)}/items/live" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, + ) + if 200 <= _response.status_code < 300: + return + if _response.status_code == 400: + raise BadRequestError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 401: + raise UnauthorizedError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 404: + raise NotFoundError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 429: + raise TooManyRequestsError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 500: + raise InternalServerError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + try: + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + async def create_item_for_multiple_locales( + self, + collection_id: str, + *, + id: str, + cms_locale_ids: typing.Optional[typing.Sequence[str]] = OMIT, + last_published: typing.Optional[str] = OMIT, + last_updated: typing.Optional[str] = OMIT, + created_on: typing.Optional[str] = OMIT, + is_archived: typing.Optional[bool] = OMIT, + is_draft: typing.Optional[bool] = OMIT, + field_data: typing.Optional[BulkCollectionItemFieldData] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> None: + """ + Create single Item in a Collection with multiple corresponding locales.

Required scope | `CMS:write` + + Parameters: + - collection_id: str. Unique identifier for a Collection + + - id: str. Unique identifier for the Item + + - cms_locale_ids: typing.Optional[typing.Sequence[str]]. Array of identifiers for the locales where the item will be crated + + - last_published: typing.Optional[str]. The date the item was last published + + - last_updated: typing.Optional[str]. The date the item was last updated + + - created_on: typing.Optional[str]. The date the item was created + + - is_archived: typing.Optional[bool]. Boolean determining if the Item is set to archived + + - is_draft: typing.Optional[bool]. Boolean determining if the Item is set to draft + + - field_data: typing.Optional[BulkCollectionItemFieldData]. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- + from webflow.client import AsyncWebflow + from webflow.resources.collections import BulkCollectionItemFieldData + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + await client.collections.items.create_item_for_multiple_locales( + collection_id="collection_id", + id="580e64008c9a982ac9b8b754", + last_published="2023-03-17T18:47:35.560Z", + last_updated="2023-03-17T18:47:35.560Z", + created_on="2023-03-17T18:47:35.560Z", + field_data=BulkCollectionItemFieldData( + name="My new item", + slug="my-new-item", + ), + ) + """ + _request: typing.Dict[str, typing.Any] = {"id": id} + if cms_locale_ids is not OMIT: + _request["cmsLocaleIds"] = cms_locale_ids + if last_published is not OMIT: + _request["lastPublished"] = last_published + if last_updated is not OMIT: + _request["lastUpdated"] = last_updated + if created_on is not OMIT: + _request["createdOn"] = created_on + if is_archived is not OMIT: + _request["isArchived"] = is_archived + if is_draft is not OMIT: + _request["isDraft"] = is_draft + if field_data is not OMIT: + _request["fieldData"] = field_data + _response = await self._client_wrapper.httpx_client.request( + "POST", + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"collections/{jsonable_encoder(collection_id)}/items/bulk" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return @@ -420,14 +1205,25 @@ async def create_item(self, collection_id: str, *, request: CollectionItem) -> N raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def get_item(self, collection_id: str, item_id: str) -> CollectionItem: + async def get_item( + self, + collection_id: str, + item_id: str, + *, + cms_locale_id: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> CollectionItem: """ - Get details of a selected Collection Item.

Required scope | `cms:read` + Get details of a selected Collection Item.

Required scope | `CMS:read` Parameters: - collection_id: str. Unique identifier for a Collection - item_id: str. Unique identifier for an Item + + - cms_locale_id: typing.Optional[str]. Unique identifier for a CMS Locale. These UID is different from the Site locale identifier and is listed as `cmsLocaleId` in the Sites response. Applicable when using localization. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -435,17 +1231,39 @@ async def get_item(self, collection_id: str, item_id: str) -> CollectionItem: access_token="YOUR_ACCESS_TOKEN", ) await client.collections.items.get_item( - collection_id="collection-id", - item_id="item-id", + collection_id="collection_id", + item_id="item_id", ) """ _response = await self._client_wrapper.httpx_client.request( "GET", urllib.parse.urljoin( - f"{self._client_wrapper.get_base_url()}/", f"collections/{collection_id}/items/{item_id}" + f"{self._client_wrapper.get_base_url()}/", + f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}", + ), + params=jsonable_encoder( + remove_none_from_dict( + { + "cmsLocaleId": cms_locale_id, + **( + request_options.get("additional_query_parameters", {}) + if request_options is not None + else {} + ), + } + ) ), - headers=self._client_wrapper.get_headers(), - timeout=60, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(CollectionItem, _response.json()) # type: ignore @@ -465,14 +1283,25 @@ async def get_item(self, collection_id: str, item_id: str) -> CollectionItem: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def delete_item(self, collection_id: str, item_id: str) -> None: + async def delete_item( + self, + collection_id: str, + item_id: str, + *, + cms_locale_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> None: """ - Delete an Item from a Collection. This endpoint does not currently support bulk deletion.

Required scope | `cms:write` + Delete an Item from a Collection. This endpoint does not currently support bulk deletion.

Required scope | `CMS:write` Parameters: - collection_id: str. Unique identifier for a Collection - item_id: str. Unique identifier for an Item + + - cms_locale_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]]. Unique identifiers for CMS Locales. These UIDs are different from the Site locale identifier and are listed as `cmsLocaleId` in the Sites response. Applicable when using localization. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -480,17 +1309,39 @@ async def delete_item(self, collection_id: str, item_id: str) -> None: access_token="YOUR_ACCESS_TOKEN", ) await client.collections.items.delete_item( - collection_id="collection-id", - item_id="item-id", + collection_id="collection_id", + item_id="item_id", ) """ _response = await self._client_wrapper.httpx_client.request( "DELETE", urllib.parse.urljoin( - f"{self._client_wrapper.get_base_url()}/", f"collections/{collection_id}/items/{item_id}" + f"{self._client_wrapper.get_base_url()}/", + f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}", ), - headers=self._client_wrapper.get_headers(), - timeout=60, + params=jsonable_encoder( + remove_none_from_dict( + { + "cmsLocaleIds": cms_locale_ids, + **( + request_options.get("additional_query_parameters", {}) + if request_options is not None + else {} + ), + } + ) + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return @@ -510,9 +1361,16 @@ async def delete_item(self, collection_id: str, item_id: str) -> None: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def update_item(self, collection_id: str, item_id: str, *, request: CollectionItem) -> CollectionItem: + async def update_item( + self, + collection_id: str, + item_id: str, + *, + request: CollectionItem, + request_options: typing.Optional[RequestOptions] = None, + ) -> CollectionItem: """ - Update a selected Item in a Collection.

Required scope | `cms:write` + Update a selected Item in a Collection.

Required scope | `CMS:write` Parameters: - collection_id: str. Unique identifier for a Collection @@ -520,32 +1378,57 @@ async def update_item(self, collection_id: str, item_id: str, *, request: Collec - item_id: str. Unique identifier for an Item - request: CollectionItem. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- - from webflow import CollectionItem + from webflow import CollectionItem, CollectionItemFieldData from webflow.client import AsyncWebflow client = AsyncWebflow( access_token="YOUR_ACCESS_TOKEN", ) await client.collections.items.update_item( - collection_id="collection-id", - item_id="item-id", + collection_id="collection_id", + item_id="item_id", request=CollectionItem( id="580e64008c9a982ac9b8b754", + cms_locale_id="653ad57de882f528b32e810e", last_published="2023-03-17T18:47:35.560Z", last_updated="2023-03-17T18:47:35.560Z", created_on="2023-03-17T18:47:35.560Z", + field_data=CollectionItemFieldData( + name="My new item", + slug="my-new-item", + ), ), ) """ _response = await self._client_wrapper.httpx_client.request( "PATCH", urllib.parse.urljoin( - f"{self._client_wrapper.get_base_url()}/", f"collections/{collection_id}/items/{item_id}" + f"{self._client_wrapper.get_base_url()}/", + f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}", ), - json=jsonable_encoder(request), - headers=self._client_wrapper.get_headers(), - timeout=60, + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(CollectionItem, _response.json()) # type: ignore @@ -565,14 +1448,171 @@ async def update_item(self, collection_id: str, item_id: str, *, request: Collec raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def publish_item(self, collection_id: str, *, item_ids: typing.List[str]) -> ItemsPublishItemResponse: + async def delete_item_live( + self, collection_id: str, item_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> None: + """ + Delete a live Item from a Collection. The Item will be unpublished from the live site. This endpoint does not currently support bulk deletion.

Required scope | `CMS:write` + + Parameters: + - collection_id: str. Unique identifier for a Collection + + - item_id: str. Unique identifier for an Item + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- + from webflow.client import AsyncWebflow + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + await client.collections.items.delete_item_live( + collection_id="collection_id", + item_id="item_id", + ) + """ + _response = await self._client_wrapper.httpx_client.request( + "DELETE", + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", + f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}/live", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, + ) + if 200 <= _response.status_code < 300: + return + if _response.status_code == 400: + raise BadRequestError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 401: + raise UnauthorizedError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 404: + raise NotFoundError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 429: + raise TooManyRequestsError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 500: + raise InternalServerError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + try: + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + async def update_item_live( + self, + collection_id: str, + item_id: str, + *, + request: CollectionItem, + request_options: typing.Optional[RequestOptions] = None, + ) -> CollectionItem: + """ + Update a selected live Item in a Collection. The updates for this Item will be published to the live site.

Required scope | `CMS:write` + + Parameters: + - collection_id: str. Unique identifier for a Collection + + - item_id: str. Unique identifier for an Item + + - request: CollectionItem. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- + from webflow import CollectionItem, CollectionItemFieldData + from webflow.client import AsyncWebflow + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + await client.collections.items.update_item_live( + collection_id="collection_id", + item_id="item_id", + request=CollectionItem( + id="580e64008c9a982ac9b8b754", + cms_locale_id="653ad57de882f528b32e810e", + last_published="2023-03-17T18:47:35.560Z", + last_updated="2023-03-17T18:47:35.560Z", + created_on="2023-03-17T18:47:35.560Z", + field_data=CollectionItemFieldData( + name="My new item", + slug="my-new-item", + ), + ), + ) + """ + _response = await self._client_wrapper.httpx_client.request( + "PATCH", + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", + f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}/live", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, + ) + if 200 <= _response.status_code < 300: + return pydantic.parse_obj_as(CollectionItem, _response.json()) # type: ignore + if _response.status_code == 400: + raise BadRequestError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 401: + raise UnauthorizedError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 404: + raise NotFoundError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 429: + raise TooManyRequestsError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 500: + raise InternalServerError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + try: + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + async def publish_item( + self, + collection_id: str, + *, + item_ids: typing.Sequence[str], + request_options: typing.Optional[RequestOptions] = None, + ) -> ItemsPublishItemResponse: """ Publish an item or multiple items.

Required scope | `cms:write` Parameters: - collection_id: str. Unique identifier for a Collection - - item_ids: typing.List[str]. + - item_ids: typing.Sequence[str]. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -580,18 +1620,36 @@ async def publish_item(self, collection_id: str, *, item_ids: typing.List[str]) access_token="YOUR_ACCESS_TOKEN", ) await client.collections.items.publish_item( - collection_id="collection-id", - item_ids=[], + collection_id="collection_id", + item_ids=["itemIds"], ) """ _response = await self._client_wrapper.httpx_client.request( "POST", urllib.parse.urljoin( - f"{self._client_wrapper.get_base_url()}/", f"collections/{collection_id}/items/publish" + f"{self._client_wrapper.get_base_url()}/", + f"collections/{jsonable_encoder(collection_id)}/items/publish", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder({"itemIds": item_ids}) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder({"itemIds": item_ids}), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) ), - json=jsonable_encoder({"itemIds": item_ids}), - headers=self._client_wrapper.get_headers(), - timeout=60, + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(ItemsPublishItemResponse, _response.json()) # type: ignore diff --git a/src/webflow/resources/collections/resources/items/types/__init__.py b/src/webflow/resources/collections/resources/items/types/__init__.py index 2917f68..b313482 100644 --- a/src/webflow/resources/collections/resources/items/types/__init__.py +++ b/src/webflow/resources/collections/resources/items/types/__init__.py @@ -1,5 +1,6 @@ # This file was auto-generated by Fern from our API Definition. +from .bulk_collection_item_field_data import BulkCollectionItemFieldData from .items_publish_item_response import ItemsPublishItemResponse -__all__ = ["ItemsPublishItemResponse"] +__all__ = ["BulkCollectionItemFieldData", "ItemsPublishItemResponse"] diff --git a/src/webflow/resources/collections/resources/items/types/bulk_collection_item_field_data.py b/src/webflow/resources/collections/resources/items/types/bulk_collection_item_field_data.py new file mode 100644 index 0000000..18cb175 --- /dev/null +++ b/src/webflow/resources/collections/resources/items/types/bulk_collection_item_field_data.py @@ -0,0 +1,32 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +from ......core.datetime_utils import serialize_datetime + +try: + import pydantic.v1 as pydantic # type: ignore +except ImportError: + import pydantic # type: ignore + + +class BulkCollectionItemFieldData(pydantic.BaseModel): + name: typing.Optional[str] = pydantic.Field(default=None, description="Name of the Item") + slug: typing.Optional[str] = pydantic.Field( + default=None, + description="URL structure of the Item in your site. Note: Updates to an item slug will break all links referencing the old slug.", + ) + + def json(self, **kwargs: typing.Any) -> str: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().json(**kwargs_with_defaults) + + def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().dict(**kwargs_with_defaults) + + class Config: + frozen = True + smart_union = True + json_encoders = {dt.datetime: serialize_datetime} diff --git a/src/webflow/resources/collections/resources/items/types/items_publish_item_response.py b/src/webflow/resources/collections/resources/items/types/items_publish_item_response.py index 8b770e8..0ecc85f 100644 --- a/src/webflow/resources/collections/resources/items/types/items_publish_item_response.py +++ b/src/webflow/resources/collections/resources/items/types/items_publish_item_response.py @@ -12,8 +12,8 @@ class ItemsPublishItemResponse(pydantic.BaseModel): - published_item_ids: typing.Optional[typing.List[str]] = pydantic.Field(alias="publishedItemIds") - errors: typing.Optional[typing.List[str]] + published_item_ids: typing.Optional[typing.List[str]] = pydantic.Field(alias="publishedItemIds", default=None) + errors: typing.Optional[typing.List[str]] = None def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/resources/ecommerce/client.py b/src/webflow/resources/ecommerce/client.py index fc0df7f..d1d7129 100644 --- a/src/webflow/resources/ecommerce/client.py +++ b/src/webflow/resources/ecommerce/client.py @@ -6,6 +6,9 @@ from ...core.api_error import ApiError from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.jsonable_encoder import jsonable_encoder +from ...core.remove_none_from_dict import remove_none_from_dict +from ...core.request_options import RequestOptions from ...errors.bad_request_error import BadRequestError from ...errors.conflict_error import ConflictError from ...errors.forbidden_error import ForbiddenError @@ -25,7 +28,9 @@ class EcommerceClient: def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper - def get_settings(self, site_id: str) -> EcommerceSettings: + def get_settings( + self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> EcommerceSettings: """ Retrieve ecommerce settings for a site. @@ -33,6 +38,8 @@ def get_settings(self, site_id: str) -> EcommerceSettings: Parameters: - site_id: str. Unique identifier for a Site + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -40,14 +47,28 @@ def get_settings(self, site_id: str) -> EcommerceSettings: access_token="YOUR_ACCESS_TOKEN", ) client.ecommerce.get_settings( - site_id="site-id", + site_id="site_id", ) """ _response = self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/ecommerce/settings"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/ecommerce/settings" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(EcommerceSettings, _response.json()) # type: ignore @@ -76,7 +97,9 @@ class AsyncEcommerceClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): self._client_wrapper = client_wrapper - async def get_settings(self, site_id: str) -> EcommerceSettings: + async def get_settings( + self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> EcommerceSettings: """ Retrieve ecommerce settings for a site. @@ -84,6 +107,8 @@ async def get_settings(self, site_id: str) -> EcommerceSettings: Parameters: - site_id: str. Unique identifier for a Site + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -91,14 +116,28 @@ async def get_settings(self, site_id: str) -> EcommerceSettings: access_token="YOUR_ACCESS_TOKEN", ) await client.ecommerce.get_settings( - site_id="site-id", + site_id="site_id", ) """ _response = await self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/ecommerce/settings"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/ecommerce/settings" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(EcommerceSettings, _response.json()) # type: ignore diff --git a/src/webflow/resources/forms/client.py b/src/webflow/resources/forms/client.py index eb570fd..e186f96 100644 --- a/src/webflow/resources/forms/client.py +++ b/src/webflow/resources/forms/client.py @@ -7,6 +7,8 @@ from ...core.api_error import ApiError from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.jsonable_encoder import jsonable_encoder +from ...core.remove_none_from_dict import remove_none_from_dict +from ...core.request_options import RequestOptions from ...errors.bad_request_error import BadRequestError from ...errors.conflict_error import ConflictError from ...errors.forbidden_error import ForbiddenError @@ -32,12 +34,25 @@ class FormsClient: def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper - def list(self, site_id: str) -> FormList: + def list( + self, + site_id: str, + *, + limit: typing.Optional[float] = None, + offset: typing.Optional[float] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> FormList: """ List forms for a given site

Required scope | `forms:read` Parameters: - site_id: str. Unique identifier for a Site + + - limit: typing.Optional[float]. Maximum number of records to be returned (max limit: 100) + + - offset: typing.Optional[float]. Offset used for pagination if the results have more than limit records + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -45,14 +60,36 @@ def list(self, site_id: str) -> FormList: access_token="YOUR_ACCESS_TOKEN", ) client.forms.list( - site_id="site-id", + site_id="site_id", ) """ _response = self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/forms"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/forms"), + params=jsonable_encoder( + remove_none_from_dict( + { + "limit": limit, + "offset": offset, + **( + request_options.get("additional_query_parameters", {}) + if request_options is not None + else {} + ), + } + ) + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(FormList, _response.json()) # type: ignore @@ -76,12 +113,14 @@ def list(self, site_id: str) -> FormList: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def get(self, form_id: str) -> Form: + def get(self, form_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Form: """ Get information about a given form

Required scope | `forms:read` Parameters: - form_id: str. Unique identifier for a Form + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -89,14 +128,26 @@ def get(self, form_id: str) -> Form: access_token="YOUR_ACCESS_TOKEN", ) client.forms.get( - form_id="form-id", + form_id="form_id", ) """ _response = self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"forms/{form_id}"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"forms/{jsonable_encoder(form_id)}"), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Form, _response.json()) # type: ignore @@ -118,12 +169,16 @@ def get(self, form_id: str) -> Form: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def list_submissions(self, form_id: str) -> FormSubmissionList: + def list_submissions( + self, form_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> FormSubmissionList: """ List form submissions for a given form

Required scope | `forms:read` Parameters: - form_id: str. Unique identifier for a Form + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -131,14 +186,28 @@ def list_submissions(self, form_id: str) -> FormSubmissionList: access_token="YOUR_ACCESS_TOKEN", ) client.forms.list_submissions( - form_id="form-id", + form_id="form_id", ) """ _response = self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"forms/{form_id}/submissions"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"forms/{jsonable_encoder(form_id)}/submissions" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(FormSubmissionList, _response.json()) # type: ignore @@ -160,12 +229,16 @@ def list_submissions(self, form_id: str) -> FormSubmissionList: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def get_submission(self, form_submission_id: str) -> FormSubmission: + def get_submission( + self, form_submission_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> FormSubmission: """ Get information about a given form submission

Required scope | `forms:read` Parameters: - form_submission_id: str. Unique identifier for a Form Submission + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -173,14 +246,28 @@ def get_submission(self, form_submission_id: str) -> FormSubmission: access_token="YOUR_ACCESS_TOKEN", ) client.forms.get_submission( - form_submission_id="form-submission-id", + form_submission_id="form_submission_id", ) """ _response = self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"form_submissions/{form_submission_id}"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"form_submissions/{jsonable_encoder(form_submission_id)}" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(FormSubmission, _response.json()) # type: ignore @@ -203,7 +290,11 @@ def get_submission(self, form_submission_id: str) -> FormSubmission: raise ApiError(status_code=_response.status_code, body=_response_json) def update_submission( - self, form_submission_id: str, *, form_submission_data: typing.Optional[typing.Dict[str, typing.Any]] = OMIT + self, + form_submission_id: str, + *, + form_submission_data: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> FormSubmission: """ Update hidden fields on a form submission

Required scope | `forms:write` @@ -212,6 +303,8 @@ def update_submission( - form_submission_id: str. Unique identifier for a Form Submission - form_submission_data: typing.Optional[typing.Dict[str, typing.Any]]. An existing **hidden field** defined on the form schema, and the corresponding value to set + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -219,7 +312,7 @@ def update_submission( access_token="YOUR_ACCESS_TOKEN", ) client.forms.update_submission( - form_submission_id="form-submission-id", + form_submission_id="form_submission_id", ) """ _request: typing.Dict[str, typing.Any] = {} @@ -227,10 +320,29 @@ def update_submission( _request["formSubmissionData"] = form_submission_data _response = self._client_wrapper.httpx_client.request( "PATCH", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"form_submissions/{form_submission_id}"), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"form_submissions/{jsonable_encoder(form_submission_id)}" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(FormSubmission, _response.json()) # type: ignore @@ -259,12 +371,25 @@ class AsyncFormsClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): self._client_wrapper = client_wrapper - async def list(self, site_id: str) -> FormList: + async def list( + self, + site_id: str, + *, + limit: typing.Optional[float] = None, + offset: typing.Optional[float] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> FormList: """ List forms for a given site

Required scope | `forms:read` Parameters: - site_id: str. Unique identifier for a Site + + - limit: typing.Optional[float]. Maximum number of records to be returned (max limit: 100) + + - offset: typing.Optional[float]. Offset used for pagination if the results have more than limit records + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -272,14 +397,36 @@ async def list(self, site_id: str) -> FormList: access_token="YOUR_ACCESS_TOKEN", ) await client.forms.list( - site_id="site-id", + site_id="site_id", ) """ _response = await self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/forms"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/forms"), + params=jsonable_encoder( + remove_none_from_dict( + { + "limit": limit, + "offset": offset, + **( + request_options.get("additional_query_parameters", {}) + if request_options is not None + else {} + ), + } + ) + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(FormList, _response.json()) # type: ignore @@ -303,12 +450,14 @@ async def list(self, site_id: str) -> FormList: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def get(self, form_id: str) -> Form: + async def get(self, form_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Form: """ Get information about a given form

Required scope | `forms:read` Parameters: - form_id: str. Unique identifier for a Form + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -316,14 +465,26 @@ async def get(self, form_id: str) -> Form: access_token="YOUR_ACCESS_TOKEN", ) await client.forms.get( - form_id="form-id", + form_id="form_id", ) """ _response = await self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"forms/{form_id}"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"forms/{jsonable_encoder(form_id)}"), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Form, _response.json()) # type: ignore @@ -345,12 +506,16 @@ async def get(self, form_id: str) -> Form: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def list_submissions(self, form_id: str) -> FormSubmissionList: + async def list_submissions( + self, form_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> FormSubmissionList: """ List form submissions for a given form

Required scope | `forms:read` Parameters: - form_id: str. Unique identifier for a Form + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -358,14 +523,28 @@ async def list_submissions(self, form_id: str) -> FormSubmissionList: access_token="YOUR_ACCESS_TOKEN", ) await client.forms.list_submissions( - form_id="form-id", + form_id="form_id", ) """ _response = await self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"forms/{form_id}/submissions"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"forms/{jsonable_encoder(form_id)}/submissions" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(FormSubmissionList, _response.json()) # type: ignore @@ -387,12 +566,16 @@ async def list_submissions(self, form_id: str) -> FormSubmissionList: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def get_submission(self, form_submission_id: str) -> FormSubmission: + async def get_submission( + self, form_submission_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> FormSubmission: """ Get information about a given form submission

Required scope | `forms:read` Parameters: - form_submission_id: str. Unique identifier for a Form Submission + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -400,14 +583,28 @@ async def get_submission(self, form_submission_id: str) -> FormSubmission: access_token="YOUR_ACCESS_TOKEN", ) await client.forms.get_submission( - form_submission_id="form-submission-id", + form_submission_id="form_submission_id", ) """ _response = await self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"form_submissions/{form_submission_id}"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"form_submissions/{jsonable_encoder(form_submission_id)}" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(FormSubmission, _response.json()) # type: ignore @@ -430,7 +627,11 @@ async def get_submission(self, form_submission_id: str) -> FormSubmission: raise ApiError(status_code=_response.status_code, body=_response_json) async def update_submission( - self, form_submission_id: str, *, form_submission_data: typing.Optional[typing.Dict[str, typing.Any]] = OMIT + self, + form_submission_id: str, + *, + form_submission_data: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> FormSubmission: """ Update hidden fields on a form submission

Required scope | `forms:write` @@ -439,6 +640,8 @@ async def update_submission( - form_submission_id: str. Unique identifier for a Form Submission - form_submission_data: typing.Optional[typing.Dict[str, typing.Any]]. An existing **hidden field** defined on the form schema, and the corresponding value to set + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -446,7 +649,7 @@ async def update_submission( access_token="YOUR_ACCESS_TOKEN", ) await client.forms.update_submission( - form_submission_id="form-submission-id", + form_submission_id="form_submission_id", ) """ _request: typing.Dict[str, typing.Any] = {} @@ -454,10 +657,29 @@ async def update_submission( _request["formSubmissionData"] = form_submission_data _response = await self._client_wrapper.httpx_client.request( "PATCH", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"form_submissions/{form_submission_id}"), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"form_submissions/{jsonable_encoder(form_submission_id)}" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(FormSubmission, _response.json()) # type: ignore diff --git a/src/webflow/resources/inventory/client.py b/src/webflow/resources/inventory/client.py index 4b5d681..9b9589a 100644 --- a/src/webflow/resources/inventory/client.py +++ b/src/webflow/resources/inventory/client.py @@ -7,6 +7,8 @@ from ...core.api_error import ApiError from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.jsonable_encoder import jsonable_encoder +from ...core.remove_none_from_dict import remove_none_from_dict +from ...core.request_options import RequestOptions from ...errors.bad_request_error import BadRequestError from ...errors.conflict_error import ConflictError from ...errors.forbidden_error import ForbiddenError @@ -30,7 +32,9 @@ class InventoryClient: def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper - def list(self, collection_id: str, item_id: str) -> InventoryItem: + def list( + self, collection_id: str, item_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> InventoryItem: """ List the current inventory levels for a particular SKU item. @@ -40,6 +44,8 @@ def list(self, collection_id: str, item_id: str) -> InventoryItem: - collection_id: str. Unique identifier for a Collection - item_id: str. Unique identifier for an Item + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -47,17 +53,30 @@ def list(self, collection_id: str, item_id: str) -> InventoryItem: access_token="YOUR_ACCESS_TOKEN", ) client.inventory.list( - collection_id="collection-id", - item_id="item-id", + collection_id="collection_id", + item_id="item_id", ) """ _response = self._client_wrapper.httpx_client.request( "GET", urllib.parse.urljoin( - f"{self._client_wrapper.get_base_url()}/", f"collections/{collection_id}/items/{item_id}/inventory" + f"{self._client_wrapper.get_base_url()}/", + f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}/inventory", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) ), - headers=self._client_wrapper.get_headers(), - timeout=60, + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(InventoryItem, _response.json()) # type: ignore @@ -89,6 +108,7 @@ def update( inventory_type: InventoryUpdateRequestInventoryType, update_quantity: typing.Optional[float] = OMIT, quantity: typing.Optional[float] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> InventoryItem: """ Updates the current inventory levels for a particular SKU item. Updates may be given in one or two methods, absolutely or incrementally. Absolute updates are done by setting `quantity` directly. Incremental updates are by specifying the inventory delta in `updateQuantity` which is then added to the `quantity` stored on the server. @@ -105,6 +125,8 @@ def update( - update_quantity: typing.Optional[float]. Adds this quantity to currently store quantity. Can be negative. - quantity: typing.Optional[float]. Immediately sets quantity to this value. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow import InventoryUpdateRequestInventoryType from webflow.client import Webflow @@ -113,8 +135,8 @@ def update( access_token="YOUR_ACCESS_TOKEN", ) client.inventory.update( - collection_id="collection-id", - item_id="item-id", + collection_id="collection_id", + item_id="item_id", inventory_type=InventoryUpdateRequestInventoryType.INFINITE, update_quantity=1.0, quantity=100.0, @@ -128,11 +150,29 @@ def update( _response = self._client_wrapper.httpx_client.request( "PATCH", urllib.parse.urljoin( - f"{self._client_wrapper.get_base_url()}/", f"collections/{collection_id}/items/{item_id}/inventory" + f"{self._client_wrapper.get_base_url()}/", + f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}/inventory", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) ), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(InventoryItem, _response.json()) # type: ignore @@ -161,7 +201,9 @@ class AsyncInventoryClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): self._client_wrapper = client_wrapper - async def list(self, collection_id: str, item_id: str) -> InventoryItem: + async def list( + self, collection_id: str, item_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> InventoryItem: """ List the current inventory levels for a particular SKU item. @@ -171,6 +213,8 @@ async def list(self, collection_id: str, item_id: str) -> InventoryItem: - collection_id: str. Unique identifier for a Collection - item_id: str. Unique identifier for an Item + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -178,17 +222,30 @@ async def list(self, collection_id: str, item_id: str) -> InventoryItem: access_token="YOUR_ACCESS_TOKEN", ) await client.inventory.list( - collection_id="collection-id", - item_id="item-id", + collection_id="collection_id", + item_id="item_id", ) """ _response = await self._client_wrapper.httpx_client.request( "GET", urllib.parse.urljoin( - f"{self._client_wrapper.get_base_url()}/", f"collections/{collection_id}/items/{item_id}/inventory" + f"{self._client_wrapper.get_base_url()}/", + f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}/inventory", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) ), - headers=self._client_wrapper.get_headers(), - timeout=60, + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(InventoryItem, _response.json()) # type: ignore @@ -220,6 +277,7 @@ async def update( inventory_type: InventoryUpdateRequestInventoryType, update_quantity: typing.Optional[float] = OMIT, quantity: typing.Optional[float] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> InventoryItem: """ Updates the current inventory levels for a particular SKU item. Updates may be given in one or two methods, absolutely or incrementally. Absolute updates are done by setting `quantity` directly. Incremental updates are by specifying the inventory delta in `updateQuantity` which is then added to the `quantity` stored on the server. @@ -236,6 +294,8 @@ async def update( - update_quantity: typing.Optional[float]. Adds this quantity to currently store quantity. Can be negative. - quantity: typing.Optional[float]. Immediately sets quantity to this value. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow import InventoryUpdateRequestInventoryType from webflow.client import AsyncWebflow @@ -244,8 +304,8 @@ async def update( access_token="YOUR_ACCESS_TOKEN", ) await client.inventory.update( - collection_id="collection-id", - item_id="item-id", + collection_id="collection_id", + item_id="item_id", inventory_type=InventoryUpdateRequestInventoryType.INFINITE, update_quantity=1.0, quantity=100.0, @@ -259,11 +319,29 @@ async def update( _response = await self._client_wrapper.httpx_client.request( "PATCH", urllib.parse.urljoin( - f"{self._client_wrapper.get_base_url()}/", f"collections/{collection_id}/items/{item_id}/inventory" + f"{self._client_wrapper.get_base_url()}/", + f"collections/{jsonable_encoder(collection_id)}/items/{jsonable_encoder(item_id)}/inventory", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) ), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(InventoryItem, _response.json()) # type: ignore diff --git a/src/webflow/resources/orders/client.py b/src/webflow/resources/orders/client.py index 01372bf..5ba994f 100644 --- a/src/webflow/resources/orders/client.py +++ b/src/webflow/resources/orders/client.py @@ -8,6 +8,7 @@ from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.jsonable_encoder import jsonable_encoder from ...core.remove_none_from_dict import remove_none_from_dict +from ...core.request_options import RequestOptions from ...errors.bad_request_error import BadRequestError from ...errors.conflict_error import ConflictError from ...errors.forbidden_error import ForbiddenError @@ -40,6 +41,7 @@ def list( status: typing.Optional[OrdersListRequestStatus] = None, offset: typing.Optional[float] = None, limit: typing.Optional[float] = None, + request_options: typing.Optional[RequestOptions] = None, ) -> OrderList: """ List all orders created for a given site. @@ -54,24 +56,48 @@ def list( - offset: typing.Optional[float]. Offset used for pagination if the results have more than limit records - limit: typing.Optional[float]. Maximum number of records to be returned (max limit: 100) + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- - from webflow import OrdersListRequestStatus from webflow.client import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) client.orders.list( - site_id="site-id", - status=OrdersListRequestStatus.PENDING, + site_id="site_id", ) """ _response = self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/orders"), - params=remove_none_from_dict({"status": status, "offset": offset, "limit": limit}), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/orders" + ), + params=jsonable_encoder( + remove_none_from_dict( + { + "status": status, + "offset": offset, + "limit": limit, + **( + request_options.get("additional_query_parameters", {}) + if request_options is not None + else {} + ), + } + ) + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(OrderList, _response.json()) # type: ignore @@ -95,7 +121,7 @@ def list( raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def get(self, site_id: str, order_id: str) -> Order: + def get(self, site_id: str, order_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Order: """ Retrieve a single product by its id. All of its SKUs will also be retrieved. @@ -105,6 +131,8 @@ def get(self, site_id: str, order_id: str) -> Order: - site_id: str. Unique identifier for a Site - order_id: str. Unique identifier for an Order + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -112,15 +140,30 @@ def get(self, site_id: str, order_id: str) -> Order: access_token="YOUR_ACCESS_TOKEN", ) client.orders.get( - site_id="site-id", - order_id="order-id", + site_id="site_id", + order_id="order_id", ) """ _response = self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/orders/{order_id}"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", + f"sites/{jsonable_encoder(site_id)}/orders/{jsonable_encoder(order_id)}", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Order, _response.json()) # type: ignore @@ -153,6 +196,7 @@ def update( shipping_provider: typing.Optional[str] = OMIT, shipping_tracking: typing.Optional[str] = OMIT, shipping_tracking_url: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> Order: """ This API lets you update the fields, `comment`, `shippingProvider`, and/or `shippingTracking` for a given order. All three fields can be updated simultaneously or independently. @@ -171,6 +215,8 @@ def update( - shipping_tracking: typing.Optional[str]. Tracking number for order shipment - shipping_tracking_url: typing.Optional[str]. URL to track order shipment + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -178,8 +224,8 @@ def update( access_token="YOUR_ACCESS_TOKEN", ) client.orders.update( - site_id="site-id", - order_id="order-id", + site_id="site_id", + order_id="order_id", comment="Example comment to myself", shipping_provider="Shipping Company, Co.", shipping_tracking="tr00000000001", @@ -197,10 +243,30 @@ def update( _request["shippingTrackingURL"] = shipping_tracking_url _response = self._client_wrapper.httpx_client.request( "PATCH", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/orders/{order_id}"), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", + f"sites/{jsonable_encoder(site_id)}/orders/{jsonable_encoder(order_id)}", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Order, _response.json()) # type: ignore @@ -225,7 +291,12 @@ def update( raise ApiError(status_code=_response.status_code, body=_response_json) def update_fulfill( - self, site_id: str, order_id: str, *, send_order_fulfilled_email: typing.Optional[bool] = OMIT + self, + site_id: str, + order_id: str, + *, + send_order_fulfilled_email: typing.Optional[bool] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> Order: """ Updates an order's status to fulfilled @@ -238,6 +309,8 @@ def update_fulfill( - order_id: str. Unique identifier for an Order - send_order_fulfilled_email: typing.Optional[bool]. Whether or not the Order Fulfilled email should be sent + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -245,8 +318,8 @@ def update_fulfill( access_token="YOUR_ACCESS_TOKEN", ) client.orders.update_fulfill( - site_id="site-id", - order_id="order-id", + site_id="site_id", + order_id="order_id", ) """ _request: typing.Dict[str, typing.Any] = {} @@ -255,11 +328,29 @@ def update_fulfill( _response = self._client_wrapper.httpx_client.request( "POST", urllib.parse.urljoin( - f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/orders/{order_id}/fulfill" + f"{self._client_wrapper.get_base_url()}/", + f"sites/{jsonable_encoder(site_id)}/orders/{jsonable_encoder(order_id)}/fulfill", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) ), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Order, _response.json()) # type: ignore @@ -283,7 +374,9 @@ def update_fulfill( raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def update_unfulfill(self, site_id: str, order_id: str) -> Order: + def update_unfulfill( + self, site_id: str, order_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> Order: """ Updates an order's status to unfulfilled @@ -293,6 +386,8 @@ def update_unfulfill(self, site_id: str, order_id: str) -> Order: - site_id: str. Unique identifier for a Site - order_id: str. Unique identifier for an Order + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -300,17 +395,33 @@ def update_unfulfill(self, site_id: str, order_id: str) -> Order: access_token="YOUR_ACCESS_TOKEN", ) client.orders.update_unfulfill( - site_id="site-id", - order_id="order-id", + site_id="site_id", + order_id="order_id", ) """ _response = self._client_wrapper.httpx_client.request( "POST", urllib.parse.urljoin( - f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/orders/{order_id}/unfulfill" + f"{self._client_wrapper.get_base_url()}/", + f"sites/{jsonable_encoder(site_id)}/orders/{jsonable_encoder(order_id)}/unfulfill", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {}))) + if request_options is not None + else None, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) ), - headers=self._client_wrapper.get_headers(), - timeout=60, + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Order, _response.json()) # type: ignore @@ -335,7 +446,12 @@ def update_unfulfill(self, site_id: str, order_id: str) -> Order: raise ApiError(status_code=_response.status_code, body=_response_json) def refund( - self, site_id: str, order_id: str, *, reason: typing.Optional[OrdersRefundRequestReason] = OMIT + self, + site_id: str, + order_id: str, + *, + reason: typing.Optional[OrdersRefundRequestReason] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> Order: """ This API will reverse a Stripe charge and refund an order back to a @@ -349,30 +465,48 @@ def refund( - order_id: str. Unique identifier for an Order - reason: typing.Optional[OrdersRefundRequestReason]. The reason for the refund + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- - from webflow import OrdersRefundRequestReason from webflow.client import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) client.orders.refund( - site_id="site-id", - order_id="order-id", - reason=OrdersRefundRequestReason.DUPLICATE, + site_id="site_id", + order_id="order_id", ) """ _request: typing.Dict[str, typing.Any] = {} if reason is not OMIT: - _request["reason"] = reason + _request["reason"] = reason.value if reason is not None else None _response = self._client_wrapper.httpx_client.request( "POST", urllib.parse.urljoin( - f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/orders/{order_id}/refund" + f"{self._client_wrapper.get_base_url()}/", + f"sites/{jsonable_encoder(site_id)}/orders/{jsonable_encoder(order_id)}/refund", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None ), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Order, _response.json()) # type: ignore @@ -408,6 +542,7 @@ async def list( status: typing.Optional[OrdersListRequestStatus] = None, offset: typing.Optional[float] = None, limit: typing.Optional[float] = None, + request_options: typing.Optional[RequestOptions] = None, ) -> OrderList: """ List all orders created for a given site. @@ -422,24 +557,48 @@ async def list( - offset: typing.Optional[float]. Offset used for pagination if the results have more than limit records - limit: typing.Optional[float]. Maximum number of records to be returned (max limit: 100) + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- - from webflow import OrdersListRequestStatus from webflow.client import AsyncWebflow client = AsyncWebflow( access_token="YOUR_ACCESS_TOKEN", ) await client.orders.list( - site_id="site-id", - status=OrdersListRequestStatus.PENDING, + site_id="site_id", ) """ _response = await self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/orders"), - params=remove_none_from_dict({"status": status, "offset": offset, "limit": limit}), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/orders" + ), + params=jsonable_encoder( + remove_none_from_dict( + { + "status": status, + "offset": offset, + "limit": limit, + **( + request_options.get("additional_query_parameters", {}) + if request_options is not None + else {} + ), + } + ) + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(OrderList, _response.json()) # type: ignore @@ -463,7 +622,9 @@ async def list( raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def get(self, site_id: str, order_id: str) -> Order: + async def get( + self, site_id: str, order_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> Order: """ Retrieve a single product by its id. All of its SKUs will also be retrieved. @@ -473,6 +634,8 @@ async def get(self, site_id: str, order_id: str) -> Order: - site_id: str. Unique identifier for a Site - order_id: str. Unique identifier for an Order + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -480,15 +643,30 @@ async def get(self, site_id: str, order_id: str) -> Order: access_token="YOUR_ACCESS_TOKEN", ) await client.orders.get( - site_id="site-id", - order_id="order-id", + site_id="site_id", + order_id="order_id", ) """ _response = await self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/orders/{order_id}"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", + f"sites/{jsonable_encoder(site_id)}/orders/{jsonable_encoder(order_id)}", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Order, _response.json()) # type: ignore @@ -521,6 +699,7 @@ async def update( shipping_provider: typing.Optional[str] = OMIT, shipping_tracking: typing.Optional[str] = OMIT, shipping_tracking_url: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> Order: """ This API lets you update the fields, `comment`, `shippingProvider`, and/or `shippingTracking` for a given order. All three fields can be updated simultaneously or independently. @@ -539,6 +718,8 @@ async def update( - shipping_tracking: typing.Optional[str]. Tracking number for order shipment - shipping_tracking_url: typing.Optional[str]. URL to track order shipment + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -546,8 +727,8 @@ async def update( access_token="YOUR_ACCESS_TOKEN", ) await client.orders.update( - site_id="site-id", - order_id="order-id", + site_id="site_id", + order_id="order_id", comment="Example comment to myself", shipping_provider="Shipping Company, Co.", shipping_tracking="tr00000000001", @@ -565,10 +746,30 @@ async def update( _request["shippingTrackingURL"] = shipping_tracking_url _response = await self._client_wrapper.httpx_client.request( "PATCH", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/orders/{order_id}"), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", + f"sites/{jsonable_encoder(site_id)}/orders/{jsonable_encoder(order_id)}", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Order, _response.json()) # type: ignore @@ -593,7 +794,12 @@ async def update( raise ApiError(status_code=_response.status_code, body=_response_json) async def update_fulfill( - self, site_id: str, order_id: str, *, send_order_fulfilled_email: typing.Optional[bool] = OMIT + self, + site_id: str, + order_id: str, + *, + send_order_fulfilled_email: typing.Optional[bool] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> Order: """ Updates an order's status to fulfilled @@ -606,6 +812,8 @@ async def update_fulfill( - order_id: str. Unique identifier for an Order - send_order_fulfilled_email: typing.Optional[bool]. Whether or not the Order Fulfilled email should be sent + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -613,8 +821,8 @@ async def update_fulfill( access_token="YOUR_ACCESS_TOKEN", ) await client.orders.update_fulfill( - site_id="site-id", - order_id="order-id", + site_id="site_id", + order_id="order_id", ) """ _request: typing.Dict[str, typing.Any] = {} @@ -623,11 +831,29 @@ async def update_fulfill( _response = await self._client_wrapper.httpx_client.request( "POST", urllib.parse.urljoin( - f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/orders/{order_id}/fulfill" + f"{self._client_wrapper.get_base_url()}/", + f"sites/{jsonable_encoder(site_id)}/orders/{jsonable_encoder(order_id)}/fulfill", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None ), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Order, _response.json()) # type: ignore @@ -651,7 +877,9 @@ async def update_fulfill( raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def update_unfulfill(self, site_id: str, order_id: str) -> Order: + async def update_unfulfill( + self, site_id: str, order_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> Order: """ Updates an order's status to unfulfilled @@ -661,6 +889,8 @@ async def update_unfulfill(self, site_id: str, order_id: str) -> Order: - site_id: str. Unique identifier for a Site - order_id: str. Unique identifier for an Order + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -668,17 +898,33 @@ async def update_unfulfill(self, site_id: str, order_id: str) -> Order: access_token="YOUR_ACCESS_TOKEN", ) await client.orders.update_unfulfill( - site_id="site-id", - order_id="order-id", + site_id="site_id", + order_id="order_id", ) """ _response = await self._client_wrapper.httpx_client.request( "POST", urllib.parse.urljoin( - f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/orders/{order_id}/unfulfill" + f"{self._client_wrapper.get_base_url()}/", + f"sites/{jsonable_encoder(site_id)}/orders/{jsonable_encoder(order_id)}/unfulfill", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None ), - headers=self._client_wrapper.get_headers(), - timeout=60, + json=jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {}))) + if request_options is not None + else None, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Order, _response.json()) # type: ignore @@ -703,7 +949,12 @@ async def update_unfulfill(self, site_id: str, order_id: str) -> Order: raise ApiError(status_code=_response.status_code, body=_response_json) async def refund( - self, site_id: str, order_id: str, *, reason: typing.Optional[OrdersRefundRequestReason] = OMIT + self, + site_id: str, + order_id: str, + *, + reason: typing.Optional[OrdersRefundRequestReason] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> Order: """ This API will reverse a Stripe charge and refund an order back to a @@ -717,30 +968,48 @@ async def refund( - order_id: str. Unique identifier for an Order - reason: typing.Optional[OrdersRefundRequestReason]. The reason for the refund + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- - from webflow import OrdersRefundRequestReason from webflow.client import AsyncWebflow client = AsyncWebflow( access_token="YOUR_ACCESS_TOKEN", ) await client.orders.refund( - site_id="site-id", - order_id="order-id", - reason=OrdersRefundRequestReason.DUPLICATE, + site_id="site_id", + order_id="order_id", ) """ _request: typing.Dict[str, typing.Any] = {} if reason is not OMIT: - _request["reason"] = reason + _request["reason"] = reason.value if reason is not None else None _response = await self._client_wrapper.httpx_client.request( "POST", urllib.parse.urljoin( - f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/orders/{order_id}/refund" + f"{self._client_wrapper.get_base_url()}/", + f"sites/{jsonable_encoder(site_id)}/orders/{jsonable_encoder(order_id)}/refund", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) ), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Order, _response.json()) # type: ignore diff --git a/src/webflow/resources/pages/__init__.py b/src/webflow/resources/pages/__init__.py index 8985ac7..58f0629 100644 --- a/src/webflow/resources/pages/__init__.py +++ b/src/webflow/resources/pages/__init__.py @@ -1,5 +1,6 @@ # This file was auto-generated by Fern from our API Definition. +from .types import DomWriteNodesItem from .resources import scripts -__all__ = ["scripts"] +__all__ = ["DomWriteNodesItem", "scripts"] diff --git a/src/webflow/resources/pages/client.py b/src/webflow/resources/pages/client.py index 1179c37..8b3b1f6 100644 --- a/src/webflow/resources/pages/client.py +++ b/src/webflow/resources/pages/client.py @@ -6,32 +6,57 @@ from ...core.api_error import ApiError from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.jsonable_encoder import jsonable_encoder +from ...core.remove_none_from_dict import remove_none_from_dict +from ...core.request_options import RequestOptions from ...errors.bad_request_error import BadRequestError +from ...errors.forbidden_error import ForbiddenError from ...errors.internal_server_error import InternalServerError from ...errors.not_found_error import NotFoundError from ...errors.too_many_requests_error import TooManyRequestsError from ...errors.unauthorized_error import UnauthorizedError +from ...types.dom import Dom from ...types.page import Page from ...types.page_list import PageList from .resources.scripts.client import AsyncScriptsClient, ScriptsClient +from .types.dom_write_nodes_item import DomWriteNodesItem try: import pydantic.v1 as pydantic # type: ignore except ImportError: import pydantic # type: ignore +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + class PagesClient: def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper self.scripts = ScriptsClient(client_wrapper=self._client_wrapper) - def list(self, site_id: str) -> PageList: + def list( + self, + site_id: str, + *, + locale: typing.Optional[str] = None, + limit: typing.Optional[float] = None, + offset: typing.Optional[float] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> PageList: """ List of all pages for a site

Required scope | `pages:read` Parameters: - site_id: str. Unique identifier for a Site + + - locale: typing.Optional[str]. Unique identifier for a specific locale. Applicable, when using localization. + + - limit: typing.Optional[float]. Maximum number of records to be returned (max limit: 100) + + - offset: typing.Optional[float]. Offset used for pagination if the results have more than limit records + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -39,14 +64,37 @@ def list(self, site_id: str) -> PageList: access_token="YOUR_ACCESS_TOKEN", ) client.pages.list( - site_id="site-id", + site_id="site_id", ) """ _response = self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/pages"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/pages"), + params=jsonable_encoder( + remove_none_from_dict( + { + "locale": locale, + "limit": limit, + "offset": offset, + **( + request_options.get("additional_query_parameters", {}) + if request_options is not None + else {} + ), + } + ) + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(PageList, _response.json()) # type: ignore @@ -66,12 +114,22 @@ def list(self, site_id: str) -> PageList: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def get_metadata(self, page_id: str) -> Page: + def get_metadata( + self, + page_id: str, + *, + locale: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> Page: """ Get metadata information for a single page

Required scope | `pages:read` Parameters: - page_id: str. Unique identifier for a Page + + - locale: typing.Optional[str]. Unique identifier for a specific locale. Applicable, when using localization. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -79,14 +137,146 @@ def get_metadata(self, page_id: str) -> Page: access_token="YOUR_ACCESS_TOKEN", ) client.pages.get_metadata( - page_id="page-id", + page_id="page_id", ) """ _response = self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"pages/{page_id}"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"pages/{jsonable_encoder(page_id)}"), + params=jsonable_encoder( + remove_none_from_dict( + { + "locale": locale, + **( + request_options.get("additional_query_parameters", {}) + if request_options is not None + else {} + ), + } + ) + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, + ) + if 200 <= _response.status_code < 300: + return pydantic.parse_obj_as(Page, _response.json()) # type: ignore + if _response.status_code == 400: + raise BadRequestError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 401: + raise UnauthorizedError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 404: + raise NotFoundError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 429: + raise TooManyRequestsError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 500: + raise InternalServerError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + try: + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + def update_page_settings( + self, + page_id: str, + *, + locale: typing.Optional[str] = None, + request: Page, + request_options: typing.Optional[RequestOptions] = None, + ) -> Page: + """ + Update Page-level metadata, including SEO and Open Graph fields.

Required scope | `pages:write` + + Parameters: + - page_id: str. Unique identifier for a Page + + - locale: typing.Optional[str]. Unique identifier for a specific locale. Applicable, when using localization. + + - request: Page. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- + import datetime + + from webflow import Page, PageOpenGraph, PageSeo + from webflow.client import Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.pages.update_page_settings( + page_id="page_id", + request=Page( + id="6390c49774a71f0e3c1a08ee", + site_id="6390c49674a71f84b51a08d8", + title="Blog Categories Template", + slug="detail_blog-category", + parent_id="6419db964a9c435aa3af6251", + collection_id="6390c49774a71f12831a08e3", + created_on=datetime.datetime.fromisoformat( + "2018-10-14 21:55:49+00:00", + ), + last_updated=datetime.datetime.fromisoformat( + "2022-12-07 16:51:37+00:00", + ), + archived=False, + draft=False, + can_branch=True, + is_members_only=False, + seo=PageSeo( + title="CoffeeStyle eCommerce - Webflow HTML website template", + description="This Webflow template offers a quick start into an e-commerce / memberships site", + ), + open_graph=PageOpenGraph( + title="CoffeeStyle eCommerce - Webflow HTML website template", + title_copied=True, + description="This Webflow template offers a quick start into an e-commerce / memberships site", + description_copied=True, + ), + ), + ) + """ + _response = self._client_wrapper.httpx_client.request( + "PUT", + urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"pages/{jsonable_encoder(page_id)}"), + params=jsonable_encoder( + remove_none_from_dict( + { + "locale": locale, + **( + request_options.get("additional_query_parameters", {}) + if request_options is not None + else {} + ), + } + ) + ), + json=jsonable_encoder(request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Page, _response.json()) # type: ignore @@ -106,18 +296,197 @@ def get_metadata(self, page_id: str) -> Page: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) + def get_content( + self, + page_id: str, + *, + locale: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> Dom: + """ + Get static content from a static page.
If you do not provide a Locale ID in your request, the response will return any content that can be localized from the Primary locale

Required scope | `pages:read` + + Parameters: + - page_id: str. Unique identifier for a Page + + - locale: typing.Optional[str]. Unique identifier for a specific locale. Applicable, when using localization. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- + from webflow.client import Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.pages.get_content( + page_id="page_id", + ) + """ + _response = self._client_wrapper.httpx_client.request( + "GET", + urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"pages/{jsonable_encoder(page_id)}/dom"), + params=jsonable_encoder( + remove_none_from_dict( + { + "locale": locale, + **( + request_options.get("additional_query_parameters", {}) + if request_options is not None + else {} + ), + } + ) + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, + ) + if 200 <= _response.status_code < 300: + return pydantic.parse_obj_as(Dom, _response.json()) # type: ignore + if _response.status_code == 400: + raise BadRequestError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 401: + raise UnauthorizedError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 403: + raise ForbiddenError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 404: + raise NotFoundError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 429: + raise TooManyRequestsError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 500: + raise InternalServerError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + try: + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + def update_static_content( + self, + page_id: str, + *, + locale: str, + nodes: typing.Sequence[DomWriteNodesItem], + request_options: typing.Optional[RequestOptions] = None, + ) -> Dom: + """ + Update static content on a static page. This endpoint supports sending 1000 nodes per request.

Required scope | `pages:write` + + Parameters: + - page_id: str. Unique identifier for a Page + + - locale: str. The locale identifier. + + - nodes: typing.Sequence[DomWriteNodesItem]. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- + from webflow import DomWriteNodesItem + from webflow.client import Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.pages.update_static_content( + page_id="page_id", + locale="locale", + nodes=[ + DomWriteNodesItem( + node_id="guide-title-id", + text="

Hello world

", + ) + ], + ) + """ + _response = self._client_wrapper.httpx_client.request( + "POST", + urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"pages/{jsonable_encoder(page_id)}/dom"), + params=jsonable_encoder( + remove_none_from_dict( + { + "locale": locale, + **( + request_options.get("additional_query_parameters", {}) + if request_options is not None + else {} + ), + } + ) + ), + json=jsonable_encoder({"nodes": nodes}) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder({"nodes": nodes}), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, + ) + if 200 <= _response.status_code < 300: + return pydantic.parse_obj_as(Dom, _response.json()) # type: ignore + if _response.status_code == 400: + raise BadRequestError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 401: + raise UnauthorizedError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 403: + raise ForbiddenError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 404: + raise NotFoundError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 429: + raise TooManyRequestsError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 500: + raise InternalServerError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + try: + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + class AsyncPagesClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): self._client_wrapper = client_wrapper self.scripts = AsyncScriptsClient(client_wrapper=self._client_wrapper) - async def list(self, site_id: str) -> PageList: + async def list( + self, + site_id: str, + *, + locale: typing.Optional[str] = None, + limit: typing.Optional[float] = None, + offset: typing.Optional[float] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> PageList: """ List of all pages for a site

Required scope | `pages:read` Parameters: - site_id: str. Unique identifier for a Site + + - locale: typing.Optional[str]. Unique identifier for a specific locale. Applicable, when using localization. + + - limit: typing.Optional[float]. Maximum number of records to be returned (max limit: 100) + + - offset: typing.Optional[float]. Offset used for pagination if the results have more than limit records + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -125,14 +494,37 @@ async def list(self, site_id: str) -> PageList: access_token="YOUR_ACCESS_TOKEN", ) await client.pages.list( - site_id="site-id", + site_id="site_id", ) """ _response = await self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/pages"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/pages"), + params=jsonable_encoder( + remove_none_from_dict( + { + "locale": locale, + "limit": limit, + "offset": offset, + **( + request_options.get("additional_query_parameters", {}) + if request_options is not None + else {} + ), + } + ) + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(PageList, _response.json()) # type: ignore @@ -152,12 +544,22 @@ async def list(self, site_id: str) -> PageList: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def get_metadata(self, page_id: str) -> Page: + async def get_metadata( + self, + page_id: str, + *, + locale: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> Page: """ Get metadata information for a single page

Required scope | `pages:read` Parameters: - page_id: str. Unique identifier for a Page + + - locale: typing.Optional[str]. Unique identifier for a specific locale. Applicable, when using localization. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -165,14 +567,35 @@ async def get_metadata(self, page_id: str) -> Page: access_token="YOUR_ACCESS_TOKEN", ) await client.pages.get_metadata( - page_id="page-id", + page_id="page_id", ) """ _response = await self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"pages/{page_id}"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"pages/{jsonable_encoder(page_id)}"), + params=jsonable_encoder( + remove_none_from_dict( + { + "locale": locale, + **( + request_options.get("additional_query_parameters", {}) + if request_options is not None + else {} + ), + } + ) + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Page, _response.json()) # type: ignore @@ -191,3 +614,277 @@ async def get_metadata(self, page_id: str) -> Page: except JSONDecodeError: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) + + async def update_page_settings( + self, + page_id: str, + *, + locale: typing.Optional[str] = None, + request: Page, + request_options: typing.Optional[RequestOptions] = None, + ) -> Page: + """ + Update Page-level metadata, including SEO and Open Graph fields.

Required scope | `pages:write` + + Parameters: + - page_id: str. Unique identifier for a Page + + - locale: typing.Optional[str]. Unique identifier for a specific locale. Applicable, when using localization. + + - request: Page. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- + import datetime + + from webflow import Page, PageOpenGraph, PageSeo + from webflow.client import AsyncWebflow + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + await client.pages.update_page_settings( + page_id="page_id", + request=Page( + id="6390c49774a71f0e3c1a08ee", + site_id="6390c49674a71f84b51a08d8", + title="Blog Categories Template", + slug="detail_blog-category", + parent_id="6419db964a9c435aa3af6251", + collection_id="6390c49774a71f12831a08e3", + created_on=datetime.datetime.fromisoformat( + "2018-10-14 21:55:49+00:00", + ), + last_updated=datetime.datetime.fromisoformat( + "2022-12-07 16:51:37+00:00", + ), + archived=False, + draft=False, + can_branch=True, + is_members_only=False, + seo=PageSeo( + title="CoffeeStyle eCommerce - Webflow HTML website template", + description="This Webflow template offers a quick start into an e-commerce / memberships site", + ), + open_graph=PageOpenGraph( + title="CoffeeStyle eCommerce - Webflow HTML website template", + title_copied=True, + description="This Webflow template offers a quick start into an e-commerce / memberships site", + description_copied=True, + ), + ), + ) + """ + _response = await self._client_wrapper.httpx_client.request( + "PUT", + urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"pages/{jsonable_encoder(page_id)}"), + params=jsonable_encoder( + remove_none_from_dict( + { + "locale": locale, + **( + request_options.get("additional_query_parameters", {}) + if request_options is not None + else {} + ), + } + ) + ), + json=jsonable_encoder(request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, + ) + if 200 <= _response.status_code < 300: + return pydantic.parse_obj_as(Page, _response.json()) # type: ignore + if _response.status_code == 400: + raise BadRequestError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 401: + raise UnauthorizedError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 404: + raise NotFoundError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 429: + raise TooManyRequestsError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 500: + raise InternalServerError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + try: + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + async def get_content( + self, + page_id: str, + *, + locale: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> Dom: + """ + Get static content from a static page.
If you do not provide a Locale ID in your request, the response will return any content that can be localized from the Primary locale

Required scope | `pages:read` + + Parameters: + - page_id: str. Unique identifier for a Page + + - locale: typing.Optional[str]. Unique identifier for a specific locale. Applicable, when using localization. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- + from webflow.client import AsyncWebflow + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + await client.pages.get_content( + page_id="page_id", + ) + """ + _response = await self._client_wrapper.httpx_client.request( + "GET", + urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"pages/{jsonable_encoder(page_id)}/dom"), + params=jsonable_encoder( + remove_none_from_dict( + { + "locale": locale, + **( + request_options.get("additional_query_parameters", {}) + if request_options is not None + else {} + ), + } + ) + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, + ) + if 200 <= _response.status_code < 300: + return pydantic.parse_obj_as(Dom, _response.json()) # type: ignore + if _response.status_code == 400: + raise BadRequestError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 401: + raise UnauthorizedError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 403: + raise ForbiddenError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 404: + raise NotFoundError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 429: + raise TooManyRequestsError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 500: + raise InternalServerError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + try: + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + async def update_static_content( + self, + page_id: str, + *, + locale: str, + nodes: typing.Sequence[DomWriteNodesItem], + request_options: typing.Optional[RequestOptions] = None, + ) -> Dom: + """ + Update static content on a static page. This endpoint supports sending 1000 nodes per request.

Required scope | `pages:write` + + Parameters: + - page_id: str. Unique identifier for a Page + + - locale: str. The locale identifier. + + - nodes: typing.Sequence[DomWriteNodesItem]. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- + from webflow import DomWriteNodesItem + from webflow.client import AsyncWebflow + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + await client.pages.update_static_content( + page_id="page_id", + locale="locale", + nodes=[ + DomWriteNodesItem( + node_id="guide-title-id", + text="

Hello world

", + ) + ], + ) + """ + _response = await self._client_wrapper.httpx_client.request( + "POST", + urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"pages/{jsonable_encoder(page_id)}/dom"), + params=jsonable_encoder( + remove_none_from_dict( + { + "locale": locale, + **( + request_options.get("additional_query_parameters", {}) + if request_options is not None + else {} + ), + } + ) + ), + json=jsonable_encoder({"nodes": nodes}) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder({"nodes": nodes}), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, + ) + if 200 <= _response.status_code < 300: + return pydantic.parse_obj_as(Dom, _response.json()) # type: ignore + if _response.status_code == 400: + raise BadRequestError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 401: + raise UnauthorizedError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 403: + raise ForbiddenError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 404: + raise NotFoundError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 429: + raise TooManyRequestsError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 500: + raise InternalServerError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + try: + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) diff --git a/src/webflow/resources/pages/resources/scripts/client.py b/src/webflow/resources/pages/resources/scripts/client.py index be06e25..2d8823a 100644 --- a/src/webflow/resources/pages/resources/scripts/client.py +++ b/src/webflow/resources/pages/resources/scripts/client.py @@ -7,6 +7,8 @@ from .....core.api_error import ApiError from .....core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from .....core.jsonable_encoder import jsonable_encoder +from .....core.remove_none_from_dict import remove_none_from_dict +from .....core.request_options import RequestOptions from .....errors.bad_request_error import BadRequestError from .....errors.internal_server_error import InternalServerError from .....errors.not_found_error import NotFoundError @@ -27,12 +29,16 @@ class ScriptsClient: def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper - def get_custom_code(self, page_id: str) -> ScriptApplyList: + def get_custom_code( + self, page_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> ScriptApplyList: """ Get all registered scripts that have been applied to a specific Page.

In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate `custom_code` endpoints.

Required scope | `custom_code:read` Parameters: - page_id: str. Unique identifier for a Page + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -40,14 +46,28 @@ def get_custom_code(self, page_id: str) -> ScriptApplyList: access_token="YOUR_ACCESS_TOKEN", ) client.pages.scripts.get_custom_code( - page_id="page-id", + page_id="page_id", ) """ _response = self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"pages/{page_id}/custom_code"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"pages/{jsonable_encoder(page_id)}/custom_code" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(ScriptApplyList, _response.json()) # type: ignore @@ -67,7 +87,9 @@ def get_custom_code(self, page_id: str) -> ScriptApplyList: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def upsert_custom_code(self, page_id: str, *, request: ScriptApplyList) -> ScriptApplyList: + def upsert_custom_code( + self, page_id: str, *, request: ScriptApplyList, request_options: typing.Optional[RequestOptions] = None + ) -> ScriptApplyList: """ Add a registered script to a Page.

In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate `custom_code` endpoints.

Required scope | `custom_code:write` @@ -75,24 +97,64 @@ def upsert_custom_code(self, page_id: str, *, request: ScriptApplyList) -> Scrip - page_id: str. Unique identifier for a Page - request: ScriptApplyList. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- - from webflow import ScriptApplyList + from webflow import ScriptApply, ScriptApplyList, ScriptApplyLocation from webflow.client import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) client.pages.scripts.upsert_custom_code( - page_id="page-id", - request=ScriptApplyList(), + page_id="page_id", + request=ScriptApplyList( + scripts=[ + ScriptApply( + id="cms_slider", + location=ScriptApplyLocation.HEADER, + version="1.0.0", + attributes={"my-attribute": "some-value"}, + ), + ScriptApply( + id="alert", + location=ScriptApplyLocation.HEADER, + version="0.0.1", + ), + ScriptApply( + id="id", + location=ScriptApplyLocation.HEADER, + version="version", + ), + ], + ), ) """ _response = self._client_wrapper.httpx_client.request( "PUT", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"pages/{page_id}/custom_code"), - json=jsonable_encoder(request), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"pages/{jsonable_encoder(page_id)}/custom_code" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(ScriptApplyList, _response.json()) # type: ignore @@ -112,12 +174,14 @@ def upsert_custom_code(self, page_id: str, *, request: ScriptApplyList) -> Scrip raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def delete_custom_code(self, page_id: str) -> None: + def delete_custom_code(self, page_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> None: """ Delete the custom code block that an app has created for a page

In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate `custom_code` endpoints.

Required scope | `custom_code:write` Parameters: - page_id: str. Unique identifier for a Page + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -125,14 +189,28 @@ def delete_custom_code(self, page_id: str) -> None: access_token="YOUR_ACCESS_TOKEN", ) client.pages.scripts.delete_custom_code( - page_id="page-id", + page_id="page_id", ) """ _response = self._client_wrapper.httpx_client.request( "DELETE", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"pages/{page_id}/custom_code"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"pages/{jsonable_encoder(page_id)}/custom_code" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return @@ -157,12 +235,16 @@ class AsyncScriptsClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): self._client_wrapper = client_wrapper - async def get_custom_code(self, page_id: str) -> ScriptApplyList: + async def get_custom_code( + self, page_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> ScriptApplyList: """ Get all registered scripts that have been applied to a specific Page.

In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate `custom_code` endpoints.

Required scope | `custom_code:read` Parameters: - page_id: str. Unique identifier for a Page + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -170,14 +252,28 @@ async def get_custom_code(self, page_id: str) -> ScriptApplyList: access_token="YOUR_ACCESS_TOKEN", ) await client.pages.scripts.get_custom_code( - page_id="page-id", + page_id="page_id", ) """ _response = await self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"pages/{page_id}/custom_code"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"pages/{jsonable_encoder(page_id)}/custom_code" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(ScriptApplyList, _response.json()) # type: ignore @@ -197,7 +293,9 @@ async def get_custom_code(self, page_id: str) -> ScriptApplyList: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def upsert_custom_code(self, page_id: str, *, request: ScriptApplyList) -> ScriptApplyList: + async def upsert_custom_code( + self, page_id: str, *, request: ScriptApplyList, request_options: typing.Optional[RequestOptions] = None + ) -> ScriptApplyList: """ Add a registered script to a Page.

In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate `custom_code` endpoints.

Required scope | `custom_code:write` @@ -205,24 +303,64 @@ async def upsert_custom_code(self, page_id: str, *, request: ScriptApplyList) -> - page_id: str. Unique identifier for a Page - request: ScriptApplyList. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- - from webflow import ScriptApplyList + from webflow import ScriptApply, ScriptApplyList, ScriptApplyLocation from webflow.client import AsyncWebflow client = AsyncWebflow( access_token="YOUR_ACCESS_TOKEN", ) await client.pages.scripts.upsert_custom_code( - page_id="page-id", - request=ScriptApplyList(), + page_id="page_id", + request=ScriptApplyList( + scripts=[ + ScriptApply( + id="cms_slider", + location=ScriptApplyLocation.HEADER, + version="1.0.0", + attributes={"my-attribute": "some-value"}, + ), + ScriptApply( + id="alert", + location=ScriptApplyLocation.HEADER, + version="0.0.1", + ), + ScriptApply( + id="id", + location=ScriptApplyLocation.HEADER, + version="version", + ), + ], + ), ) """ _response = await self._client_wrapper.httpx_client.request( "PUT", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"pages/{page_id}/custom_code"), - json=jsonable_encoder(request), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"pages/{jsonable_encoder(page_id)}/custom_code" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(ScriptApplyList, _response.json()) # type: ignore @@ -242,12 +380,16 @@ async def upsert_custom_code(self, page_id: str, *, request: ScriptApplyList) -> raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def delete_custom_code(self, page_id: str) -> None: + async def delete_custom_code( + self, page_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> None: """ Delete the custom code block that an app has created for a page

In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate `custom_code` endpoints.

Required scope | `custom_code:write` Parameters: - page_id: str. Unique identifier for a Page + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -255,14 +397,28 @@ async def delete_custom_code(self, page_id: str) -> None: access_token="YOUR_ACCESS_TOKEN", ) await client.pages.scripts.delete_custom_code( - page_id="page-id", + page_id="page_id", ) """ _response = await self._client_wrapper.httpx_client.request( "DELETE", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"pages/{page_id}/custom_code"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"pages/{jsonable_encoder(page_id)}/custom_code" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return diff --git a/src/webflow/resources/pages/types/__init__.py b/src/webflow/resources/pages/types/__init__.py new file mode 100644 index 0000000..fdefa12 --- /dev/null +++ b/src/webflow/resources/pages/types/__init__.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +from .dom_write_nodes_item import DomWriteNodesItem + +__all__ = ["DomWriteNodesItem"] diff --git a/src/webflow/resources/pages/types/dom_write_nodes_item.py b/src/webflow/resources/pages/types/dom_write_nodes_item.py new file mode 100644 index 0000000..36f7d9b --- /dev/null +++ b/src/webflow/resources/pages/types/dom_write_nodes_item.py @@ -0,0 +1,30 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +from ....core.datetime_utils import serialize_datetime + +try: + import pydantic.v1 as pydantic # type: ignore +except ImportError: + import pydantic # type: ignore + + +class DomWriteNodesItem(pydantic.BaseModel): + node_id: str = pydantic.Field(alias="nodeId", description="Node UUID") + text: str = pydantic.Field(description="HTML content of the node") + + def json(self, **kwargs: typing.Any) -> str: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().json(**kwargs_with_defaults) + + def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().dict(**kwargs_with_defaults) + + class Config: + frozen = True + smart_union = True + allow_population_by_field_name = True + json_encoders = {dt.datetime: serialize_datetime} diff --git a/src/webflow/resources/products/__init__.py b/src/webflow/resources/products/__init__.py index 9fced2c..d1569c5 100644 --- a/src/webflow/resources/products/__init__.py +++ b/src/webflow/resources/products/__init__.py @@ -1,5 +1,31 @@ # This file was auto-generated by Fern from our API Definition. -from .types import ProductsCreateSkuResponse +from .types import ( + ProductSkuCreateProduct, + ProductSkuCreateProductFieldData, + ProductSkuCreateProductFieldDataEcProductType, + ProductSkuCreateProductFieldDataTaxCategory, + ProductSkuCreateSku, + ProductSkuCreateSkuFieldData, + ProductSkuCreateSkuFieldDataCompareAtPrice, + ProductSkuCreateSkuFieldDataEcSkuBillingMethod, + ProductSkuCreateSkuFieldDataEcSkuSubscriptionPlan, + ProductSkuCreateSkuFieldDataEcSkuSubscriptionPlanInterval, + ProductSkuCreateSkuFieldDataPrice, + ProductsCreateSkuResponse, +) -__all__ = ["ProductsCreateSkuResponse"] +__all__ = [ + "ProductSkuCreateProduct", + "ProductSkuCreateProductFieldData", + "ProductSkuCreateProductFieldDataEcProductType", + "ProductSkuCreateProductFieldDataTaxCategory", + "ProductSkuCreateSku", + "ProductSkuCreateSkuFieldData", + "ProductSkuCreateSkuFieldDataCompareAtPrice", + "ProductSkuCreateSkuFieldDataEcSkuBillingMethod", + "ProductSkuCreateSkuFieldDataEcSkuSubscriptionPlan", + "ProductSkuCreateSkuFieldDataEcSkuSubscriptionPlanInterval", + "ProductSkuCreateSkuFieldDataPrice", + "ProductsCreateSkuResponse", +] diff --git a/src/webflow/resources/products/client.py b/src/webflow/resources/products/client.py index 957a7bb..128785d 100644 --- a/src/webflow/resources/products/client.py +++ b/src/webflow/resources/products/client.py @@ -8,6 +8,7 @@ from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.jsonable_encoder import jsonable_encoder from ...core.remove_none_from_dict import remove_none_from_dict +from ...core.request_options import RequestOptions from ...errors.bad_request_error import BadRequestError from ...errors.conflict_error import ConflictError from ...errors.forbidden_error import ForbiddenError @@ -20,6 +21,8 @@ from ...types.product_and_sk_us_list import ProductAndSkUsList from ...types.publish_status import PublishStatus from ...types.sku import Sku +from .types.product_sku_create_product import ProductSkuCreateProduct +from .types.product_sku_create_sku import ProductSkuCreateSku from .types.products_create_sku_response import ProductsCreateSkuResponse try: @@ -36,7 +39,12 @@ def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper def list( - self, site_id: str, *, offset: typing.Optional[float] = None, limit: typing.Optional[float] = None + self, + site_id: str, + *, + offset: typing.Optional[float] = None, + limit: typing.Optional[float] = None, + request_options: typing.Optional[RequestOptions] = None, ) -> ProductAndSkUsList: """ Retrieve all products for a site. Use `limit` and `offset` to page through all products with subsequent requests. All SKUs for each product will also be fetched and returned. The `limit`, `offset` and `total` values represent Products only and do not include any SKUs. @@ -49,6 +57,8 @@ def list( - offset: typing.Optional[float]. Offset used for pagination if the results have more than limit records - limit: typing.Optional[float]. Maximum number of records to be returned (max limit: 100) + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -56,15 +66,38 @@ def list( access_token="YOUR_ACCESS_TOKEN", ) client.products.list( - site_id="site-id", + site_id="site_id", ) """ _response = self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/products"), - params=remove_none_from_dict({"offset": offset, "limit": limit}), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/products" + ), + params=jsonable_encoder( + remove_none_from_dict( + { + "offset": offset, + "limit": limit, + **( + request_options.get("additional_query_parameters", {}) + if request_options is not None + else {} + ), + } + ) + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(ProductAndSkUsList, _response.json()) # type: ignore @@ -89,20 +122,22 @@ def list( raise ApiError(status_code=_response.status_code, body=_response_json) def create( - self, site_id: str, *, publish_status: typing.Optional[PublishStatus] = OMIT, product: Product, sku: Sku + self, + site_id: str, + *, + publish_status: typing.Optional[PublishStatus] = OMIT, + product: typing.Optional[ProductSkuCreateProduct] = OMIT, + sku: typing.Optional[ProductSkuCreateSku] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> ProductAndSkUs: """ - Adding a new Product involves creating both a Product Item and a SKU Item, since a Product Item has to have, at minimum, a SKU Item. + Creating a new Product involves creating both a Product and a SKU, since a Product Item has to have, at minimum, a single SKU. - To create a new Product with multiple SKUs, you must: + In order to create a Product with multiple SKUs - for example a T-shirt in sizes small, medium and large - you'll need to create `sku-properties`. In our T-shirt example, a single `sku-property` would be Color. Within that property, we'll need to list out the various colors a T-shirt could be as an array of `enum` values: `royal-blue`, `crimson-red`, and `forrest-green`. - - Create the Product and Default SKU using this endpoint, making sure to add `sku-properties` in the product data. - - You can't add `sku-values` to the SKU yet, since there are no enum IDs created yet. When this endpoint returns, it will have IDs filled in for the `sku-properties` enums. - - With those IDs, update the default SKU with valid `sku-values` and create any additional SKUs (if needed), with valid `sku-values`. - - You can also create the Product without `sku-properties` and add them in later. - - If you add any `sku` properties, the default SKU will default to the first value of each option. + Once, you've created a Product and its `sku-properties` with `enum` values, you can create your default SKU, which will automatically be a combination of the first `sku-properties` you've created. In our example, the default SKU will be a Royal Blue T-Shirt, because our first `enum` of our Color `sku-property` is Royal Blue. After you've created your product, you can create additional SKUs using the Create SKU endpoint - Upon creation, the default product type will be `Advanced`. The product type is used to determine which Product and SKU fields are shown to users in the `Designer` and the `Editor`. Setting it to `Advanced` ensures that all Product and SKU fields will be shown. The product type can be edited in the `Designer` or the `Editor`. + Upon creation, the default product type will be `Advanced`. The product type is used to determine which Product and SKU fields are shown to users in the `Designer` and the `Editor`. Setting it to `Advanced` ensures that all Product and SKU fields will be shown. Required scope | `ecommerce:write` @@ -111,92 +146,53 @@ def create( - publish_status: typing.Optional[PublishStatus]. - - product: Product. + - product: typing.Optional[ProductSkuCreateProduct]. The Product Object - - sku: Sku. - --- - import datetime + - sku: typing.Optional[ProductSkuCreateSku]. The SKU object - from webflow import ( - Product, - ProductFieldData, - PublishStatus, - Sku, - SkuFieldData, - SkuFieldDataPrice, - SkuPropertyList, - SkuPropertyListEnumItem, - ) + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- from webflow.client import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) client.products.create( - site_id="site-id", - publish_status=PublishStatus.STAGING, - product=Product( - id="580e63fc8c9a982ac9b8b745", - last_published=datetime.datetime.fromisoformat( - "2023-03-17 18:47:35.560000+00:00", - ), - last_updated=datetime.datetime.fromisoformat( - "2023-03-17 18:47:35.560000+00:00", - ), - created_on=datetime.datetime.fromisoformat( - "2023-03-17 18:47:35.560000+00:00", - ), - is_archived=False, - is_draft=False, - field_data=ProductFieldData( - name="My new item", - slug="my-new-item", - sku_properties=[ - SkuPropertyList( - id="ff42fee0113744f693a764e3431a9cc2", - name="Color", - enum=[ - SkuPropertyListEnumItem( - id="64a74715c456e36762fc39a1", - name="Royal Blue", - slug="royal-blue", - ) - ], - ) - ], - ), - ), - sku=Sku( - id="580e63fc8c9a982ac9b8b745", - last_published=datetime.datetime.fromisoformat( - "2023-03-17 18:47:35.560000+00:00", - ), - last_updated=datetime.datetime.fromisoformat( - "2023-03-17 18:47:35.560000+00:00", - ), - created_on=datetime.datetime.fromisoformat( - "2023-03-17 18:47:35.560000+00:00", - ), - field_data=SkuFieldData( - name="My new item", - slug="my-new-item", - price=SkuFieldDataPrice( - value=100.0, - unit="USD", - ), - ), - ), + site_id="site_id", ) """ - _request: typing.Dict[str, typing.Any] = {"product": product, "sku": sku} + _request: typing.Dict[str, typing.Any] = {} if publish_status is not OMIT: - _request["publishStatus"] = publish_status + _request["publishStatus"] = publish_status.value if publish_status is not None else None + if product is not OMIT: + _request["product"] = product + if sku is not OMIT: + _request["sku"] = sku _response = self._client_wrapper.httpx_client.request( "POST", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/products"), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/products" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(ProductAndSkUs, _response.json()) # type: ignore @@ -220,7 +216,9 @@ def create( raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def get(self, site_id: str, product_id: str) -> ProductAndSkUs: + def get( + self, site_id: str, product_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> ProductAndSkUs: """ Retrieve a single product by its id. All of its SKUs will also be retrieved. @@ -230,6 +228,8 @@ def get(self, site_id: str, product_id: str) -> ProductAndSkUs: - site_id: str. Unique identifier for a Site - product_id: str. Unique identifier for a Product + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -237,15 +237,30 @@ def get(self, site_id: str, product_id: str) -> ProductAndSkUs: access_token="YOUR_ACCESS_TOKEN", ) client.products.get( - site_id="site-id", - product_id="product-id", + site_id="site_id", + product_id="product_id", ) """ _response = self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/products/{product_id}"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", + f"sites/{jsonable_encoder(site_id)}/products/{jsonable_encoder(product_id)}", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(ProductAndSkUs, _response.json()) # type: ignore @@ -270,7 +285,13 @@ def get(self, site_id: str, product_id: str) -> ProductAndSkUs: raise ApiError(status_code=_response.status_code, body=_response_json) def update( - self, site_id: str, product_id: str, *, publish_status: typing.Optional[PublishStatus] = OMIT, product: Product + self, + site_id: str, + product_id: str, + *, + publish_status: typing.Optional[PublishStatus] = OMIT, + product: Product, + request_options: typing.Optional[RequestOptions] = None, ) -> Product: """ Updating an existing Product will set the product type to `Advanced`. The product type is used to determine which Product and SKU fields are shown to users in the `Designer` and the `Editor`. Setting it to `Advanced` ensures that all Product and SKU fields will be shown. The product type can be edited in the `Designer` or the `Editor`. @@ -285,13 +306,14 @@ def update( - publish_status: typing.Optional[PublishStatus]. - product: Product. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- import datetime from webflow import ( Product, ProductFieldData, - PublishStatus, SkuPropertyList, SkuPropertyListEnumItem, ) @@ -301,37 +323,64 @@ def update( access_token="YOUR_ACCESS_TOKEN", ) client.products.update( - site_id="site-id", - product_id="product-id", - publish_status=PublishStatus.STAGING, + site_id="site_id", + product_id="product_id", product=Product( id="580e63fc8c9a982ac9b8b745", last_published=datetime.datetime.fromisoformat( - "2023-03-17 18:47:35.560000+00:00", + "2023-03-17 18:47:35+00:00", ), last_updated=datetime.datetime.fromisoformat( - "2023-03-17 18:47:35.560000+00:00", + "2023-03-17 18:47:35+00:00", ), created_on=datetime.datetime.fromisoformat( - "2023-03-17 18:47:35.560000+00:00", + "2023-03-17 18:47:35+00:00", ), is_archived=False, is_draft=False, field_data=ProductFieldData( - name="My new item", - slug="my-new-item", + name="T-Shirt", + slug="t-shirt", + description="A plain cotton t-shirt.", + shippable=True, sku_properties=[ SkuPropertyList( - id="ff42fee0113744f693a764e3431a9cc2", + id="color", name="Color", enum=[ SkuPropertyListEnumItem( - id="64a74715c456e36762fc39a1", + id="royal-blue", name="Royal Blue", slug="royal-blue", + ), + SkuPropertyListEnumItem( + id="crimson-red", + name="Crimson Red", + slug="crimson-red", + ), + SkuPropertyListEnumItem( + id="forrest-green", + name="Forrst Green", + slug="forrest-green", + ), + SkuPropertyListEnumItem( + id="id", + name="name", + slug="slug", + ), + ], + ), + SkuPropertyList( + id="Color", + name="Color", + enum=[ + SkuPropertyListEnumItem( + id="id", + name="name", + slug="slug", ) ], - ) + ), ], ), ), @@ -339,13 +388,33 @@ def update( """ _request: typing.Dict[str, typing.Any] = {"product": product} if publish_status is not OMIT: - _request["publishStatus"] = publish_status + _request["publishStatus"] = publish_status.value if publish_status is not None else None _response = self._client_wrapper.httpx_client.request( "PATCH", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/products/{product_id}"), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", + f"sites/{jsonable_encoder(site_id)}/products/{jsonable_encoder(product_id)}", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Product, _response.json()) # type: ignore @@ -375,7 +444,8 @@ def create_sku( product_id: str, *, publish_status: typing.Optional[PublishStatus] = OMIT, - skus: typing.List[Sku], + skus: typing.Sequence[Sku], + request_options: typing.Optional[RequestOptions] = None, ) -> ProductsCreateSkuResponse: """ Create additional SKUs to cover every variant of your Product. The Default SKU already counts as one of the variants. @@ -391,39 +461,41 @@ def create_sku( - publish_status: typing.Optional[PublishStatus]. - - skus: typing.List[Sku]. An array of the SKU data your are adding + - skus: typing.Sequence[Sku]. An array of the SKU data your are adding + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- import datetime - from webflow import PublishStatus, Sku, SkuFieldData, SkuFieldDataPrice + from webflow import Sku, SkuFieldData, SkuFieldDataPrice from webflow.client import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) client.products.create_sku( - site_id="site-id", - product_id="product-id", - publish_status=PublishStatus.STAGING, + site_id="site_id", + product_id="product_id", skus=[ Sku( id="580e63fc8c9a982ac9b8b745", last_published=datetime.datetime.fromisoformat( - "2023-03-17 18:47:35.560000+00:00", + "2023-03-17 18:47:35+00:00", ), last_updated=datetime.datetime.fromisoformat( - "2023-03-17 18:47:35.560000+00:00", + "2023-03-17 18:47:35+00:00", ), created_on=datetime.datetime.fromisoformat( - "2023-03-17 18:47:35.560000+00:00", + "2023-03-17 18:47:35+00:00", ), field_data=SkuFieldData( - name="My new item", - slug="my-new-item", + name="Blue T-shirt", + slug="t-shirt-blue", price=SkuFieldDataPrice( value=100.0, unit="USD", ), + quantity=10.0, ), ) ], @@ -431,15 +503,33 @@ def create_sku( """ _request: typing.Dict[str, typing.Any] = {"skus": skus} if publish_status is not OMIT: - _request["publishStatus"] = publish_status + _request["publishStatus"] = publish_status.value if publish_status is not None else None _response = self._client_wrapper.httpx_client.request( "POST", urllib.parse.urljoin( - f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/products/{product_id}/skus" + f"{self._client_wrapper.get_base_url()}/", + f"sites/{jsonable_encoder(site_id)}/products/{jsonable_encoder(product_id)}/skus", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None ), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(ProductsCreateSkuResponse, _response.json()) # type: ignore @@ -471,6 +561,7 @@ def update_sku( *, publish_status: typing.Optional[PublishStatus] = OMIT, sku: Sku, + request_options: typing.Optional[RequestOptions] = None, ) -> Sku: """ Updating an existing SKU will set the product type to `Advanced` for the product associated with the SKU. The product type is used to determine which Product and SKU fields are shown to users in the `Designer` and the `Editor`. Setting it to `Advanced` ensures that all Product and SKU fields will be shown. The product type can be edited in the `Designer` or the `Editor`. @@ -487,53 +578,73 @@ def update_sku( - publish_status: typing.Optional[PublishStatus]. - sku: Sku. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- import datetime - from webflow import PublishStatus, Sku, SkuFieldData, SkuFieldDataPrice + from webflow import Sku, SkuFieldData, SkuFieldDataPrice from webflow.client import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) client.products.update_sku( - site_id="site-id", - product_id="product-id", - sku_id="sku-id", - publish_status=PublishStatus.STAGING, + site_id="site_id", + product_id="product_id", + sku_id="sku_id", sku=Sku( id="580e63fc8c9a982ac9b8b745", last_published=datetime.datetime.fromisoformat( - "2023-03-17 18:47:35.560000+00:00", + "2023-03-17 18:47:35+00:00", ), last_updated=datetime.datetime.fromisoformat( - "2023-03-17 18:47:35.560000+00:00", + "2023-03-17 18:47:35+00:00", ), created_on=datetime.datetime.fromisoformat( - "2023-03-17 18:47:35.560000+00:00", + "2023-03-17 18:47:35+00:00", ), field_data=SkuFieldData( - name="My new item", - slug="my-new-item", + name="Blue T-shirt", + slug="t-shirt-blue", price=SkuFieldDataPrice( value=100.0, unit="USD", ), + quantity=10.0, ), ), ) """ _request: typing.Dict[str, typing.Any] = {"sku": sku} if publish_status is not OMIT: - _request["publishStatus"] = publish_status + _request["publishStatus"] = publish_status.value if publish_status is not None else None _response = self._client_wrapper.httpx_client.request( "PATCH", urllib.parse.urljoin( - f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/products/{product_id}/skus/{sku_id}" + f"{self._client_wrapper.get_base_url()}/", + f"sites/{jsonable_encoder(site_id)}/products/{jsonable_encoder(product_id)}/skus/{jsonable_encoder(sku_id)}", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) ), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Sku, _response.json()) # type: ignore @@ -563,7 +674,12 @@ def __init__(self, *, client_wrapper: AsyncClientWrapper): self._client_wrapper = client_wrapper async def list( - self, site_id: str, *, offset: typing.Optional[float] = None, limit: typing.Optional[float] = None + self, + site_id: str, + *, + offset: typing.Optional[float] = None, + limit: typing.Optional[float] = None, + request_options: typing.Optional[RequestOptions] = None, ) -> ProductAndSkUsList: """ Retrieve all products for a site. Use `limit` and `offset` to page through all products with subsequent requests. All SKUs for each product will also be fetched and returned. The `limit`, `offset` and `total` values represent Products only and do not include any SKUs. @@ -576,6 +692,8 @@ async def list( - offset: typing.Optional[float]. Offset used for pagination if the results have more than limit records - limit: typing.Optional[float]. Maximum number of records to be returned (max limit: 100) + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -583,15 +701,38 @@ async def list( access_token="YOUR_ACCESS_TOKEN", ) await client.products.list( - site_id="site-id", + site_id="site_id", ) """ _response = await self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/products"), - params=remove_none_from_dict({"offset": offset, "limit": limit}), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/products" + ), + params=jsonable_encoder( + remove_none_from_dict( + { + "offset": offset, + "limit": limit, + **( + request_options.get("additional_query_parameters", {}) + if request_options is not None + else {} + ), + } + ) + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(ProductAndSkUsList, _response.json()) # type: ignore @@ -616,20 +757,22 @@ async def list( raise ApiError(status_code=_response.status_code, body=_response_json) async def create( - self, site_id: str, *, publish_status: typing.Optional[PublishStatus] = OMIT, product: Product, sku: Sku + self, + site_id: str, + *, + publish_status: typing.Optional[PublishStatus] = OMIT, + product: typing.Optional[ProductSkuCreateProduct] = OMIT, + sku: typing.Optional[ProductSkuCreateSku] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> ProductAndSkUs: """ - Adding a new Product involves creating both a Product Item and a SKU Item, since a Product Item has to have, at minimum, a SKU Item. + Creating a new Product involves creating both a Product and a SKU, since a Product Item has to have, at minimum, a single SKU. - To create a new Product with multiple SKUs, you must: + In order to create a Product with multiple SKUs - for example a T-shirt in sizes small, medium and large - you'll need to create `sku-properties`. In our T-shirt example, a single `sku-property` would be Color. Within that property, we'll need to list out the various colors a T-shirt could be as an array of `enum` values: `royal-blue`, `crimson-red`, and `forrest-green`. - - Create the Product and Default SKU using this endpoint, making sure to add `sku-properties` in the product data. - - You can't add `sku-values` to the SKU yet, since there are no enum IDs created yet. When this endpoint returns, it will have IDs filled in for the `sku-properties` enums. - - With those IDs, update the default SKU with valid `sku-values` and create any additional SKUs (if needed), with valid `sku-values`. - - You can also create the Product without `sku-properties` and add them in later. - - If you add any `sku` properties, the default SKU will default to the first value of each option. + Once, you've created a Product and its `sku-properties` with `enum` values, you can create your default SKU, which will automatically be a combination of the first `sku-properties` you've created. In our example, the default SKU will be a Royal Blue T-Shirt, because our first `enum` of our Color `sku-property` is Royal Blue. After you've created your product, you can create additional SKUs using the Create SKU endpoint - Upon creation, the default product type will be `Advanced`. The product type is used to determine which Product and SKU fields are shown to users in the `Designer` and the `Editor`. Setting it to `Advanced` ensures that all Product and SKU fields will be shown. The product type can be edited in the `Designer` or the `Editor`. + Upon creation, the default product type will be `Advanced`. The product type is used to determine which Product and SKU fields are shown to users in the `Designer` and the `Editor`. Setting it to `Advanced` ensures that all Product and SKU fields will be shown. Required scope | `ecommerce:write` @@ -638,92 +781,53 @@ async def create( - publish_status: typing.Optional[PublishStatus]. - - product: Product. + - product: typing.Optional[ProductSkuCreateProduct]. The Product Object - - sku: Sku. - --- - import datetime + - sku: typing.Optional[ProductSkuCreateSku]. The SKU object - from webflow import ( - Product, - ProductFieldData, - PublishStatus, - Sku, - SkuFieldData, - SkuFieldDataPrice, - SkuPropertyList, - SkuPropertyListEnumItem, - ) + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- from webflow.client import AsyncWebflow client = AsyncWebflow( access_token="YOUR_ACCESS_TOKEN", ) await client.products.create( - site_id="site-id", - publish_status=PublishStatus.STAGING, - product=Product( - id="580e63fc8c9a982ac9b8b745", - last_published=datetime.datetime.fromisoformat( - "2023-03-17 18:47:35.560000+00:00", - ), - last_updated=datetime.datetime.fromisoformat( - "2023-03-17 18:47:35.560000+00:00", - ), - created_on=datetime.datetime.fromisoformat( - "2023-03-17 18:47:35.560000+00:00", - ), - is_archived=False, - is_draft=False, - field_data=ProductFieldData( - name="My new item", - slug="my-new-item", - sku_properties=[ - SkuPropertyList( - id="ff42fee0113744f693a764e3431a9cc2", - name="Color", - enum=[ - SkuPropertyListEnumItem( - id="64a74715c456e36762fc39a1", - name="Royal Blue", - slug="royal-blue", - ) - ], - ) - ], - ), - ), - sku=Sku( - id="580e63fc8c9a982ac9b8b745", - last_published=datetime.datetime.fromisoformat( - "2023-03-17 18:47:35.560000+00:00", - ), - last_updated=datetime.datetime.fromisoformat( - "2023-03-17 18:47:35.560000+00:00", - ), - created_on=datetime.datetime.fromisoformat( - "2023-03-17 18:47:35.560000+00:00", - ), - field_data=SkuFieldData( - name="My new item", - slug="my-new-item", - price=SkuFieldDataPrice( - value=100.0, - unit="USD", - ), - ), - ), + site_id="site_id", ) """ - _request: typing.Dict[str, typing.Any] = {"product": product, "sku": sku} + _request: typing.Dict[str, typing.Any] = {} if publish_status is not OMIT: - _request["publishStatus"] = publish_status + _request["publishStatus"] = publish_status.value if publish_status is not None else None + if product is not OMIT: + _request["product"] = product + if sku is not OMIT: + _request["sku"] = sku _response = await self._client_wrapper.httpx_client.request( "POST", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/products"), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/products" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(ProductAndSkUs, _response.json()) # type: ignore @@ -747,7 +851,9 @@ async def create( raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def get(self, site_id: str, product_id: str) -> ProductAndSkUs: + async def get( + self, site_id: str, product_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> ProductAndSkUs: """ Retrieve a single product by its id. All of its SKUs will also be retrieved. @@ -757,6 +863,8 @@ async def get(self, site_id: str, product_id: str) -> ProductAndSkUs: - site_id: str. Unique identifier for a Site - product_id: str. Unique identifier for a Product + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -764,15 +872,30 @@ async def get(self, site_id: str, product_id: str) -> ProductAndSkUs: access_token="YOUR_ACCESS_TOKEN", ) await client.products.get( - site_id="site-id", - product_id="product-id", + site_id="site_id", + product_id="product_id", ) """ _response = await self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/products/{product_id}"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", + f"sites/{jsonable_encoder(site_id)}/products/{jsonable_encoder(product_id)}", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(ProductAndSkUs, _response.json()) # type: ignore @@ -797,7 +920,13 @@ async def get(self, site_id: str, product_id: str) -> ProductAndSkUs: raise ApiError(status_code=_response.status_code, body=_response_json) async def update( - self, site_id: str, product_id: str, *, publish_status: typing.Optional[PublishStatus] = OMIT, product: Product + self, + site_id: str, + product_id: str, + *, + publish_status: typing.Optional[PublishStatus] = OMIT, + product: Product, + request_options: typing.Optional[RequestOptions] = None, ) -> Product: """ Updating an existing Product will set the product type to `Advanced`. The product type is used to determine which Product and SKU fields are shown to users in the `Designer` and the `Editor`. Setting it to `Advanced` ensures that all Product and SKU fields will be shown. The product type can be edited in the `Designer` or the `Editor`. @@ -812,13 +941,14 @@ async def update( - publish_status: typing.Optional[PublishStatus]. - product: Product. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- import datetime from webflow import ( Product, ProductFieldData, - PublishStatus, SkuPropertyList, SkuPropertyListEnumItem, ) @@ -828,37 +958,64 @@ async def update( access_token="YOUR_ACCESS_TOKEN", ) await client.products.update( - site_id="site-id", - product_id="product-id", - publish_status=PublishStatus.STAGING, + site_id="site_id", + product_id="product_id", product=Product( id="580e63fc8c9a982ac9b8b745", last_published=datetime.datetime.fromisoformat( - "2023-03-17 18:47:35.560000+00:00", + "2023-03-17 18:47:35+00:00", ), last_updated=datetime.datetime.fromisoformat( - "2023-03-17 18:47:35.560000+00:00", + "2023-03-17 18:47:35+00:00", ), created_on=datetime.datetime.fromisoformat( - "2023-03-17 18:47:35.560000+00:00", + "2023-03-17 18:47:35+00:00", ), is_archived=False, is_draft=False, field_data=ProductFieldData( - name="My new item", - slug="my-new-item", + name="T-Shirt", + slug="t-shirt", + description="A plain cotton t-shirt.", + shippable=True, sku_properties=[ SkuPropertyList( - id="ff42fee0113744f693a764e3431a9cc2", + id="color", name="Color", enum=[ SkuPropertyListEnumItem( - id="64a74715c456e36762fc39a1", + id="royal-blue", name="Royal Blue", slug="royal-blue", + ), + SkuPropertyListEnumItem( + id="crimson-red", + name="Crimson Red", + slug="crimson-red", + ), + SkuPropertyListEnumItem( + id="forrest-green", + name="Forrst Green", + slug="forrest-green", + ), + SkuPropertyListEnumItem( + id="id", + name="name", + slug="slug", + ), + ], + ), + SkuPropertyList( + id="Color", + name="Color", + enum=[ + SkuPropertyListEnumItem( + id="id", + name="name", + slug="slug", ) ], - ) + ), ], ), ), @@ -866,13 +1023,33 @@ async def update( """ _request: typing.Dict[str, typing.Any] = {"product": product} if publish_status is not OMIT: - _request["publishStatus"] = publish_status + _request["publishStatus"] = publish_status.value if publish_status is not None else None _response = await self._client_wrapper.httpx_client.request( "PATCH", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/products/{product_id}"), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", + f"sites/{jsonable_encoder(site_id)}/products/{jsonable_encoder(product_id)}", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Product, _response.json()) # type: ignore @@ -902,7 +1079,8 @@ async def create_sku( product_id: str, *, publish_status: typing.Optional[PublishStatus] = OMIT, - skus: typing.List[Sku], + skus: typing.Sequence[Sku], + request_options: typing.Optional[RequestOptions] = None, ) -> ProductsCreateSkuResponse: """ Create additional SKUs to cover every variant of your Product. The Default SKU already counts as one of the variants. @@ -918,39 +1096,41 @@ async def create_sku( - publish_status: typing.Optional[PublishStatus]. - - skus: typing.List[Sku]. An array of the SKU data your are adding + - skus: typing.Sequence[Sku]. An array of the SKU data your are adding + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- import datetime - from webflow import PublishStatus, Sku, SkuFieldData, SkuFieldDataPrice + from webflow import Sku, SkuFieldData, SkuFieldDataPrice from webflow.client import AsyncWebflow client = AsyncWebflow( access_token="YOUR_ACCESS_TOKEN", ) await client.products.create_sku( - site_id="site-id", - product_id="product-id", - publish_status=PublishStatus.STAGING, + site_id="site_id", + product_id="product_id", skus=[ Sku( id="580e63fc8c9a982ac9b8b745", last_published=datetime.datetime.fromisoformat( - "2023-03-17 18:47:35.560000+00:00", + "2023-03-17 18:47:35+00:00", ), last_updated=datetime.datetime.fromisoformat( - "2023-03-17 18:47:35.560000+00:00", + "2023-03-17 18:47:35+00:00", ), created_on=datetime.datetime.fromisoformat( - "2023-03-17 18:47:35.560000+00:00", + "2023-03-17 18:47:35+00:00", ), field_data=SkuFieldData( - name="My new item", - slug="my-new-item", + name="Blue T-shirt", + slug="t-shirt-blue", price=SkuFieldDataPrice( value=100.0, unit="USD", ), + quantity=10.0, ), ) ], @@ -958,15 +1138,33 @@ async def create_sku( """ _request: typing.Dict[str, typing.Any] = {"skus": skus} if publish_status is not OMIT: - _request["publishStatus"] = publish_status + _request["publishStatus"] = publish_status.value if publish_status is not None else None _response = await self._client_wrapper.httpx_client.request( "POST", urllib.parse.urljoin( - f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/products/{product_id}/skus" + f"{self._client_wrapper.get_base_url()}/", + f"sites/{jsonable_encoder(site_id)}/products/{jsonable_encoder(product_id)}/skus", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None ), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(ProductsCreateSkuResponse, _response.json()) # type: ignore @@ -998,6 +1196,7 @@ async def update_sku( *, publish_status: typing.Optional[PublishStatus] = OMIT, sku: Sku, + request_options: typing.Optional[RequestOptions] = None, ) -> Sku: """ Updating an existing SKU will set the product type to `Advanced` for the product associated with the SKU. The product type is used to determine which Product and SKU fields are shown to users in the `Designer` and the `Editor`. Setting it to `Advanced` ensures that all Product and SKU fields will be shown. The product type can be edited in the `Designer` or the `Editor`. @@ -1014,53 +1213,73 @@ async def update_sku( - publish_status: typing.Optional[PublishStatus]. - sku: Sku. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- import datetime - from webflow import PublishStatus, Sku, SkuFieldData, SkuFieldDataPrice + from webflow import Sku, SkuFieldData, SkuFieldDataPrice from webflow.client import AsyncWebflow client = AsyncWebflow( access_token="YOUR_ACCESS_TOKEN", ) await client.products.update_sku( - site_id="site-id", - product_id="product-id", - sku_id="sku-id", - publish_status=PublishStatus.STAGING, + site_id="site_id", + product_id="product_id", + sku_id="sku_id", sku=Sku( id="580e63fc8c9a982ac9b8b745", last_published=datetime.datetime.fromisoformat( - "2023-03-17 18:47:35.560000+00:00", + "2023-03-17 18:47:35+00:00", ), last_updated=datetime.datetime.fromisoformat( - "2023-03-17 18:47:35.560000+00:00", + "2023-03-17 18:47:35+00:00", ), created_on=datetime.datetime.fromisoformat( - "2023-03-17 18:47:35.560000+00:00", + "2023-03-17 18:47:35+00:00", ), field_data=SkuFieldData( - name="My new item", - slug="my-new-item", + name="Blue T-shirt", + slug="t-shirt-blue", price=SkuFieldDataPrice( value=100.0, unit="USD", ), + quantity=10.0, ), ), ) """ _request: typing.Dict[str, typing.Any] = {"sku": sku} if publish_status is not OMIT: - _request["publishStatus"] = publish_status + _request["publishStatus"] = publish_status.value if publish_status is not None else None _response = await self._client_wrapper.httpx_client.request( "PATCH", urllib.parse.urljoin( - f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/products/{product_id}/skus/{sku_id}" + f"{self._client_wrapper.get_base_url()}/", + f"sites/{jsonable_encoder(site_id)}/products/{jsonable_encoder(product_id)}/skus/{jsonable_encoder(sku_id)}", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) ), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Sku, _response.json()) # type: ignore diff --git a/src/webflow/resources/products/types/__init__.py b/src/webflow/resources/products/types/__init__.py index b078afe..55ac9d6 100644 --- a/src/webflow/resources/products/types/__init__.py +++ b/src/webflow/resources/products/types/__init__.py @@ -1,5 +1,33 @@ # This file was auto-generated by Fern from our API Definition. +from .product_sku_create_product import ProductSkuCreateProduct +from .product_sku_create_product_field_data import ProductSkuCreateProductFieldData +from .product_sku_create_product_field_data_ec_product_type import ProductSkuCreateProductFieldDataEcProductType +from .product_sku_create_product_field_data_tax_category import ProductSkuCreateProductFieldDataTaxCategory +from .product_sku_create_sku import ProductSkuCreateSku +from .product_sku_create_sku_field_data import ProductSkuCreateSkuFieldData +from .product_sku_create_sku_field_data_compare_at_price import ProductSkuCreateSkuFieldDataCompareAtPrice +from .product_sku_create_sku_field_data_ec_sku_billing_method import ProductSkuCreateSkuFieldDataEcSkuBillingMethod +from .product_sku_create_sku_field_data_ec_sku_subscription_plan import ( + ProductSkuCreateSkuFieldDataEcSkuSubscriptionPlan, +) +from .product_sku_create_sku_field_data_ec_sku_subscription_plan_interval import ( + ProductSkuCreateSkuFieldDataEcSkuSubscriptionPlanInterval, +) +from .product_sku_create_sku_field_data_price import ProductSkuCreateSkuFieldDataPrice from .products_create_sku_response import ProductsCreateSkuResponse -__all__ = ["ProductsCreateSkuResponse"] +__all__ = [ + "ProductSkuCreateProduct", + "ProductSkuCreateProductFieldData", + "ProductSkuCreateProductFieldDataEcProductType", + "ProductSkuCreateProductFieldDataTaxCategory", + "ProductSkuCreateSku", + "ProductSkuCreateSkuFieldData", + "ProductSkuCreateSkuFieldDataCompareAtPrice", + "ProductSkuCreateSkuFieldDataEcSkuBillingMethod", + "ProductSkuCreateSkuFieldDataEcSkuSubscriptionPlan", + "ProductSkuCreateSkuFieldDataEcSkuSubscriptionPlanInterval", + "ProductSkuCreateSkuFieldDataPrice", + "ProductsCreateSkuResponse", +] diff --git a/src/webflow/resources/products/types/product_sku_create_product.py b/src/webflow/resources/products/types/product_sku_create_product.py new file mode 100644 index 0000000..6e410b8 --- /dev/null +++ b/src/webflow/resources/products/types/product_sku_create_product.py @@ -0,0 +1,50 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +from ....core.datetime_utils import serialize_datetime +from .product_sku_create_product_field_data import ProductSkuCreateProductFieldData + +try: + import pydantic.v1 as pydantic # type: ignore +except ImportError: + import pydantic # type: ignore + + +class ProductSkuCreateProduct(pydantic.BaseModel): + """ + The Product Object + """ + + id: typing.Optional[str] = pydantic.Field(default=None, description="Unique identifier for the Product") + last_published: typing.Optional[dt.datetime] = pydantic.Field( + alias="lastPublished", default=None, description="The date the Product was last published" + ) + last_updated: typing.Optional[dt.datetime] = pydantic.Field( + alias="lastUpdated", default=None, description="The date the Product was last updated" + ) + created_on: typing.Optional[dt.datetime] = pydantic.Field( + alias="createdOn", default=None, description="The date the Product was created" + ) + is_archived: typing.Optional[bool] = pydantic.Field( + alias="isArchived", default=None, description="Boolean determining if the Product is set to archived" + ) + is_draft: typing.Optional[bool] = pydantic.Field( + alias="isDraft", default=None, description="Boolean determining if the Product is set to draft" + ) + field_data: typing.Optional[ProductSkuCreateProductFieldData] = pydantic.Field(alias="fieldData", default=None) + + def json(self, **kwargs: typing.Any) -> str: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().json(**kwargs_with_defaults) + + def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().dict(**kwargs_with_defaults) + + class Config: + frozen = True + smart_union = True + allow_population_by_field_name = True + json_encoders = {dt.datetime: serialize_datetime} diff --git a/src/webflow/resources/products/types/product_sku_create_product_field_data.py b/src/webflow/resources/products/types/product_sku_create_product_field_data.py new file mode 100644 index 0000000..2748896 --- /dev/null +++ b/src/webflow/resources/products/types/product_sku_create_product_field_data.py @@ -0,0 +1,52 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +from ....core.datetime_utils import serialize_datetime +from ....types.sku_property_list import SkuPropertyList +from .product_sku_create_product_field_data_ec_product_type import ProductSkuCreateProductFieldDataEcProductType +from .product_sku_create_product_field_data_tax_category import ProductSkuCreateProductFieldDataTaxCategory + +try: + import pydantic.v1 as pydantic # type: ignore +except ImportError: + import pydantic # type: ignore + + +class ProductSkuCreateProductFieldData(pydantic.BaseModel): + name: str = pydantic.Field(description="Name of the Product") + slug: str = pydantic.Field(description="URL structure of the Product in your site.") + description: typing.Optional[str] = pydantic.Field(default=None, description="A description of your product") + shippable: typing.Optional[bool] = pydantic.Field( + default=None, description="Boolean determining if the Product is shippable" + ) + sku_properties: typing.Optional[typing.List[SkuPropertyList]] = pydantic.Field( + alias="sku-properties", default=None, description="Variant types to include in SKUs" + ) + categories: typing.Optional[typing.List[typing.Any]] = pydantic.Field( + default=None, description="The categories your product belongs to." + ) + tax_category: typing.Optional[ProductSkuCreateProductFieldDataTaxCategory] = pydantic.Field( + alias="tax-category", default=None, description="Product tax class" + ) + ec_product_type: typing.Optional[ProductSkuCreateProductFieldDataEcProductType] = pydantic.Field( + alias="ec-product-type", + default=None, + description='Product types. Enums reflect the following values in order: Physical, Digital, Service, Advanced"', + ) + additional_properties: typing.Optional[typing.Any] = pydantic.Field(alias="additionalProperties", default=None) + + def json(self, **kwargs: typing.Any) -> str: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().json(**kwargs_with_defaults) + + def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().dict(**kwargs_with_defaults) + + class Config: + frozen = True + smart_union = True + allow_population_by_field_name = True + json_encoders = {dt.datetime: serialize_datetime} diff --git a/src/webflow/resources/products/types/product_sku_create_product_field_data_ec_product_type.py b/src/webflow/resources/products/types/product_sku_create_product_field_data_ec_product_type.py new file mode 100644 index 0000000..05f521c --- /dev/null +++ b/src/webflow/resources/products/types/product_sku_create_product_field_data_ec_product_type.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +import enum +import typing + +T_Result = typing.TypeVar("T_Result") + + +class ProductSkuCreateProductFieldDataEcProductType(str, enum.Enum): + """ + Product types. Enums reflect the following values in order: Physical, Digital, Service, Advanced" + """ + + FF_42_FEE_0113744_F_693_A_764_E_3431_A_9_CC_2 = "ff42fee0113744f693a764e3431a9cc2" + F_22027_DB_68002190_AEF_89_A_4_A_2_B_7_AC_8_A_1 = "f22027db68002190aef89a4a2b7ac8a1" + C_599_E_43_B_1_A_1_C_34_D_5_A_323_AEDF_75_D_3_ADF_6 = "c599e43b1a1c34d5a323aedf75d3adf6" + B_6_CCC_1830_DB_4_B_1_BABEB_06_A_9_AC_5_F_6_DD_76 = "b6ccc1830db4b1babeb06a9ac5f6dd76" + + def visit( + self, + ff_42_fee_0113744_f_693_a_764_e_3431_a_9_cc_2: typing.Callable[[], T_Result], + f_22027_db_68002190_aef_89_a_4_a_2_b_7_ac_8_a_1: typing.Callable[[], T_Result], + c_599_e_43_b_1_a_1_c_34_d_5_a_323_aedf_75_d_3_adf_6: typing.Callable[[], T_Result], + b_6_ccc_1830_db_4_b_1_babeb_06_a_9_ac_5_f_6_dd_76: typing.Callable[[], T_Result], + ) -> T_Result: + if self is ProductSkuCreateProductFieldDataEcProductType.FF_42_FEE_0113744_F_693_A_764_E_3431_A_9_CC_2: + return ff_42_fee_0113744_f_693_a_764_e_3431_a_9_cc_2() + if self is ProductSkuCreateProductFieldDataEcProductType.F_22027_DB_68002190_AEF_89_A_4_A_2_B_7_AC_8_A_1: + return f_22027_db_68002190_aef_89_a_4_a_2_b_7_ac_8_a_1() + if self is ProductSkuCreateProductFieldDataEcProductType.C_599_E_43_B_1_A_1_C_34_D_5_A_323_AEDF_75_D_3_ADF_6: + return c_599_e_43_b_1_a_1_c_34_d_5_a_323_aedf_75_d_3_adf_6() + if self is ProductSkuCreateProductFieldDataEcProductType.B_6_CCC_1830_DB_4_B_1_BABEB_06_A_9_AC_5_F_6_DD_76: + return b_6_ccc_1830_db_4_b_1_babeb_06_a_9_ac_5_f_6_dd_76() diff --git a/src/webflow/resources/products/types/product_sku_create_product_field_data_tax_category.py b/src/webflow/resources/products/types/product_sku_create_product_field_data_tax_category.py new file mode 100644 index 0000000..a2eb210 --- /dev/null +++ b/src/webflow/resources/products/types/product_sku_create_product_field_data_tax_category.py @@ -0,0 +1,133 @@ +# This file was auto-generated by Fern from our API Definition. + +import enum +import typing + +T_Result = typing.TypeVar("T_Result") + + +class ProductSkuCreateProductFieldDataTaxCategory(str, enum.Enum): + """ + Product tax class + """ + + STANDARD_TAXABLE = "standard-taxable" + STANDARD_EXEMPT = "standard-exempt" + BOOKS_RELIGIOUS = "books-religious" + BOOKS_TEXTBOOK = "books-textbook" + CLOTHING = "clothing" + CLOTHING_SWIMWEAR = "clothing-swimwear" + DIGITAL_GOODS = "digital-goods" + DIGITAL_SERVICE = "digital-service" + DRUGS_NON_PRESCRIPTION = "drugs-non-prescription" + DRUGS_PRESCRIPTION = "drugs-prescription" + FOOD_BOTTLED_WATER = "food-bottled-water" + FOOD_CANDY = "food-candy" + FOOD_GROCERIES = "food-groceries" + FOOD_PREPARED = "food-prepared" + FOOD_SODA = "food-soda" + FOOD_SUPPLEMENTS = "food-supplements" + MAGAZINE_INDIVIDUAL = "magazine-individual" + MAGAZINE_SUBSCRIPTION = "magazine-subscription" + SERVICE_ADMISSION = "service-admission" + SERVICE_ADVERTISING = "service-advertising" + SERVICE_DRY_CLEANING = "service-dry-cleaning" + SERVICE_HAIRDRESSING = "service-hairdressing" + SERVICE_INSTALLATION = "service-installation" + SERVICE_MISCELLANEOUS = "service-miscellaneous" + SERVICE_PARKING = "service-parking" + SERVICE_PRINTING = "service-printing" + SERVICE_PROFESSIONAL = "service-professional" + SERVICE_REPAIR = "service-repair" + SERVICE_TRAINING = "service-training" + + def visit( + self, + standard_taxable: typing.Callable[[], T_Result], + standard_exempt: typing.Callable[[], T_Result], + books_religious: typing.Callable[[], T_Result], + books_textbook: typing.Callable[[], T_Result], + clothing: typing.Callable[[], T_Result], + clothing_swimwear: typing.Callable[[], T_Result], + digital_goods: typing.Callable[[], T_Result], + digital_service: typing.Callable[[], T_Result], + drugs_non_prescription: typing.Callable[[], T_Result], + drugs_prescription: typing.Callable[[], T_Result], + food_bottled_water: typing.Callable[[], T_Result], + food_candy: typing.Callable[[], T_Result], + food_groceries: typing.Callable[[], T_Result], + food_prepared: typing.Callable[[], T_Result], + food_soda: typing.Callable[[], T_Result], + food_supplements: typing.Callable[[], T_Result], + magazine_individual: typing.Callable[[], T_Result], + magazine_subscription: typing.Callable[[], T_Result], + service_admission: typing.Callable[[], T_Result], + service_advertising: typing.Callable[[], T_Result], + service_dry_cleaning: typing.Callable[[], T_Result], + service_hairdressing: typing.Callable[[], T_Result], + service_installation: typing.Callable[[], T_Result], + service_miscellaneous: typing.Callable[[], T_Result], + service_parking: typing.Callable[[], T_Result], + service_printing: typing.Callable[[], T_Result], + service_professional: typing.Callable[[], T_Result], + service_repair: typing.Callable[[], T_Result], + service_training: typing.Callable[[], T_Result], + ) -> T_Result: + if self is ProductSkuCreateProductFieldDataTaxCategory.STANDARD_TAXABLE: + return standard_taxable() + if self is ProductSkuCreateProductFieldDataTaxCategory.STANDARD_EXEMPT: + return standard_exempt() + if self is ProductSkuCreateProductFieldDataTaxCategory.BOOKS_RELIGIOUS: + return books_religious() + if self is ProductSkuCreateProductFieldDataTaxCategory.BOOKS_TEXTBOOK: + return books_textbook() + if self is ProductSkuCreateProductFieldDataTaxCategory.CLOTHING: + return clothing() + if self is ProductSkuCreateProductFieldDataTaxCategory.CLOTHING_SWIMWEAR: + return clothing_swimwear() + if self is ProductSkuCreateProductFieldDataTaxCategory.DIGITAL_GOODS: + return digital_goods() + if self is ProductSkuCreateProductFieldDataTaxCategory.DIGITAL_SERVICE: + return digital_service() + if self is ProductSkuCreateProductFieldDataTaxCategory.DRUGS_NON_PRESCRIPTION: + return drugs_non_prescription() + if self is ProductSkuCreateProductFieldDataTaxCategory.DRUGS_PRESCRIPTION: + return drugs_prescription() + if self is ProductSkuCreateProductFieldDataTaxCategory.FOOD_BOTTLED_WATER: + return food_bottled_water() + if self is ProductSkuCreateProductFieldDataTaxCategory.FOOD_CANDY: + return food_candy() + if self is ProductSkuCreateProductFieldDataTaxCategory.FOOD_GROCERIES: + return food_groceries() + if self is ProductSkuCreateProductFieldDataTaxCategory.FOOD_PREPARED: + return food_prepared() + if self is ProductSkuCreateProductFieldDataTaxCategory.FOOD_SODA: + return food_soda() + if self is ProductSkuCreateProductFieldDataTaxCategory.FOOD_SUPPLEMENTS: + return food_supplements() + if self is ProductSkuCreateProductFieldDataTaxCategory.MAGAZINE_INDIVIDUAL: + return magazine_individual() + if self is ProductSkuCreateProductFieldDataTaxCategory.MAGAZINE_SUBSCRIPTION: + return magazine_subscription() + if self is ProductSkuCreateProductFieldDataTaxCategory.SERVICE_ADMISSION: + return service_admission() + if self is ProductSkuCreateProductFieldDataTaxCategory.SERVICE_ADVERTISING: + return service_advertising() + if self is ProductSkuCreateProductFieldDataTaxCategory.SERVICE_DRY_CLEANING: + return service_dry_cleaning() + if self is ProductSkuCreateProductFieldDataTaxCategory.SERVICE_HAIRDRESSING: + return service_hairdressing() + if self is ProductSkuCreateProductFieldDataTaxCategory.SERVICE_INSTALLATION: + return service_installation() + if self is ProductSkuCreateProductFieldDataTaxCategory.SERVICE_MISCELLANEOUS: + return service_miscellaneous() + if self is ProductSkuCreateProductFieldDataTaxCategory.SERVICE_PARKING: + return service_parking() + if self is ProductSkuCreateProductFieldDataTaxCategory.SERVICE_PRINTING: + return service_printing() + if self is ProductSkuCreateProductFieldDataTaxCategory.SERVICE_PROFESSIONAL: + return service_professional() + if self is ProductSkuCreateProductFieldDataTaxCategory.SERVICE_REPAIR: + return service_repair() + if self is ProductSkuCreateProductFieldDataTaxCategory.SERVICE_TRAINING: + return service_training() diff --git a/src/webflow/resources/products/types/product_sku_create_sku.py b/src/webflow/resources/products/types/product_sku_create_sku.py new file mode 100644 index 0000000..2877e3c --- /dev/null +++ b/src/webflow/resources/products/types/product_sku_create_sku.py @@ -0,0 +1,46 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +from ....core.datetime_utils import serialize_datetime +from .product_sku_create_sku_field_data import ProductSkuCreateSkuFieldData + +try: + import pydantic.v1 as pydantic # type: ignore +except ImportError: + import pydantic # type: ignore + + +class ProductSkuCreateSku(pydantic.BaseModel): + """ + The SKU object + """ + + id: typing.Optional[str] = pydantic.Field(default=None, description="Unique identifier for the Product") + last_published: typing.Optional[dt.datetime] = pydantic.Field( + alias="lastPublished", default=None, description="The date the Product was last published" + ) + last_updated: typing.Optional[dt.datetime] = pydantic.Field( + alias="lastUpdated", default=None, description="The date the Product was last updated" + ) + created_on: typing.Optional[dt.datetime] = pydantic.Field( + alias="createdOn", default=None, description="The date the Product was created" + ) + field_data: typing.Optional[ProductSkuCreateSkuFieldData] = pydantic.Field( + alias="fieldData", default=None, description="Standard and Custom fields for a SKU" + ) + + def json(self, **kwargs: typing.Any) -> str: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().json(**kwargs_with_defaults) + + def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().dict(**kwargs_with_defaults) + + class Config: + frozen = True + smart_union = True + allow_population_by_field_name = True + json_encoders = {dt.datetime: serialize_datetime} diff --git a/src/webflow/resources/products/types/product_sku_create_sku_field_data.py b/src/webflow/resources/products/types/product_sku_create_sku_field_data.py new file mode 100644 index 0000000..621cba9 --- /dev/null +++ b/src/webflow/resources/products/types/product_sku_create_sku_field_data.py @@ -0,0 +1,62 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +from ....core.datetime_utils import serialize_datetime +from ....types.sku_value_list import SkuValueList +from .product_sku_create_sku_field_data_compare_at_price import ProductSkuCreateSkuFieldDataCompareAtPrice +from .product_sku_create_sku_field_data_ec_sku_billing_method import ProductSkuCreateSkuFieldDataEcSkuBillingMethod +from .product_sku_create_sku_field_data_ec_sku_subscription_plan import ( + ProductSkuCreateSkuFieldDataEcSkuSubscriptionPlan, +) +from .product_sku_create_sku_field_data_price import ProductSkuCreateSkuFieldDataPrice + +try: + import pydantic.v1 as pydantic # type: ignore +except ImportError: + import pydantic # type: ignore + + +class ProductSkuCreateSkuFieldData(pydantic.BaseModel): + """ + Standard and Custom fields for a SKU + """ + + sku_values: typing.Optional[SkuValueList] = pydantic.Field(alias="sku-values", default=None) + name: str = pydantic.Field(description="Name of the Product") + slug: str = pydantic.Field(description="URL structure of the Product in your site.") + price: ProductSkuCreateSkuFieldDataPrice = pydantic.Field(description="price of SKU") + compare_at_price: typing.Optional[ProductSkuCreateSkuFieldDataCompareAtPrice] = pydantic.Field( + alias="compare-at-price", default=None, description="comparison price of SKU" + ) + ec_sku_billing_method: typing.Optional[ProductSkuCreateSkuFieldDataEcSkuBillingMethod] = pydantic.Field( + alias="ec-sku-billing-method", default=None, description="The billing method for your SKU" + ) + ec_sku_subscription_plan: typing.Optional[ProductSkuCreateSkuFieldDataEcSkuSubscriptionPlan] = pydantic.Field( + alias="ec-sku-subscription-plan", + default=None, + description="If your billing method is a Subscription Plan, outline the type and frequency of the subscription.", + ) + track_inventory: typing.Optional[bool] = pydantic.Field( + alias="track-inventory", + default=None, + description="A boolean indicating whether inventory for this product should be tracked.", + ) + quantity: typing.Optional[float] = pydantic.Field( + default=None, description="Quantity of SKU that will be tracked as items are ordered." + ) + + def json(self, **kwargs: typing.Any) -> str: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().json(**kwargs_with_defaults) + + def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().dict(**kwargs_with_defaults) + + class Config: + frozen = True + smart_union = True + allow_population_by_field_name = True + json_encoders = {dt.datetime: serialize_datetime} diff --git a/src/webflow/resources/products/types/product_sku_create_sku_field_data_compare_at_price.py b/src/webflow/resources/products/types/product_sku_create_sku_field_data_compare_at_price.py new file mode 100644 index 0000000..ea8c8b8 --- /dev/null +++ b/src/webflow/resources/products/types/product_sku_create_sku_field_data_compare_at_price.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +from ....core.datetime_utils import serialize_datetime + +try: + import pydantic.v1 as pydantic # type: ignore +except ImportError: + import pydantic # type: ignore + + +class ProductSkuCreateSkuFieldDataCompareAtPrice(pydantic.BaseModel): + """ + comparison price of SKU + """ + + value: typing.Optional[float] = pydantic.Field(default=None, description="Price of SKU") + unit: typing.Optional[str] = pydantic.Field(default=None, description="Currency of Item") + + def json(self, **kwargs: typing.Any) -> str: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().json(**kwargs_with_defaults) + + def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().dict(**kwargs_with_defaults) + + class Config: + frozen = True + smart_union = True + json_encoders = {dt.datetime: serialize_datetime} diff --git a/src/webflow/resources/products/types/product_sku_create_sku_field_data_ec_sku_billing_method.py b/src/webflow/resources/products/types/product_sku_create_sku_field_data_ec_sku_billing_method.py new file mode 100644 index 0000000..9b4e545 --- /dev/null +++ b/src/webflow/resources/products/types/product_sku_create_sku_field_data_ec_sku_billing_method.py @@ -0,0 +1,21 @@ +# This file was auto-generated by Fern from our API Definition. + +import enum +import typing + +T_Result = typing.TypeVar("T_Result") + + +class ProductSkuCreateSkuFieldDataEcSkuBillingMethod(str, enum.Enum): + """ + The billing method for your SKU + """ + + ONE_TIME = "one-time" + SUBSCRIPTION = "subscription" + + def visit(self, one_time: typing.Callable[[], T_Result], subscription: typing.Callable[[], T_Result]) -> T_Result: + if self is ProductSkuCreateSkuFieldDataEcSkuBillingMethod.ONE_TIME: + return one_time() + if self is ProductSkuCreateSkuFieldDataEcSkuBillingMethod.SUBSCRIPTION: + return subscription() diff --git a/src/webflow/resources/products/types/product_sku_create_sku_field_data_ec_sku_subscription_plan.py b/src/webflow/resources/products/types/product_sku_create_sku_field_data_ec_sku_subscription_plan.py new file mode 100644 index 0000000..16df5eb --- /dev/null +++ b/src/webflow/resources/products/types/product_sku_create_sku_field_data_ec_sku_subscription_plan.py @@ -0,0 +1,39 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +from ....core.datetime_utils import serialize_datetime +from .product_sku_create_sku_field_data_ec_sku_subscription_plan_interval import ( + ProductSkuCreateSkuFieldDataEcSkuSubscriptionPlanInterval, +) + +try: + import pydantic.v1 as pydantic # type: ignore +except ImportError: + import pydantic # type: ignore + + +class ProductSkuCreateSkuFieldDataEcSkuSubscriptionPlan(pydantic.BaseModel): + """ + If your billing method is a Subscription Plan, outline the type and frequency of the subscription. + """ + + interval: typing.Optional[ProductSkuCreateSkuFieldDataEcSkuSubscriptionPlanInterval] = pydantic.Field( + default=None, description="Interval of subscription renewal" + ) + frequency: typing.Optional[float] = pydantic.Field(default=None, description="Frequncy of billing within interval") + trial: typing.Optional[float] = pydantic.Field(default=None, description="Number of days of a trial") + + def json(self, **kwargs: typing.Any) -> str: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().json(**kwargs_with_defaults) + + def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().dict(**kwargs_with_defaults) + + class Config: + frozen = True + smart_union = True + json_encoders = {dt.datetime: serialize_datetime} diff --git a/src/webflow/resources/products/types/product_sku_create_sku_field_data_ec_sku_subscription_plan_interval.py b/src/webflow/resources/products/types/product_sku_create_sku_field_data_ec_sku_subscription_plan_interval.py new file mode 100644 index 0000000..07093ba --- /dev/null +++ b/src/webflow/resources/products/types/product_sku_create_sku_field_data_ec_sku_subscription_plan_interval.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +import enum +import typing + +T_Result = typing.TypeVar("T_Result") + + +class ProductSkuCreateSkuFieldDataEcSkuSubscriptionPlanInterval(str, enum.Enum): + """ + Interval of subscription renewal + """ + + DAY = "day" + WEEK = "week" + MONTH = "month" + YEAR = "year" + + def visit( + self, + day: typing.Callable[[], T_Result], + week: typing.Callable[[], T_Result], + month: typing.Callable[[], T_Result], + year: typing.Callable[[], T_Result], + ) -> T_Result: + if self is ProductSkuCreateSkuFieldDataEcSkuSubscriptionPlanInterval.DAY: + return day() + if self is ProductSkuCreateSkuFieldDataEcSkuSubscriptionPlanInterval.WEEK: + return week() + if self is ProductSkuCreateSkuFieldDataEcSkuSubscriptionPlanInterval.MONTH: + return month() + if self is ProductSkuCreateSkuFieldDataEcSkuSubscriptionPlanInterval.YEAR: + return year() diff --git a/src/webflow/resources/products/types/product_sku_create_sku_field_data_price.py b/src/webflow/resources/products/types/product_sku_create_sku_field_data_price.py new file mode 100644 index 0000000..9a430e4 --- /dev/null +++ b/src/webflow/resources/products/types/product_sku_create_sku_field_data_price.py @@ -0,0 +1,34 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +from ....core.datetime_utils import serialize_datetime + +try: + import pydantic.v1 as pydantic # type: ignore +except ImportError: + import pydantic # type: ignore + + +class ProductSkuCreateSkuFieldDataPrice(pydantic.BaseModel): + """ + price of SKU + """ + + required: typing.Optional[typing.Any] = None + value: typing.Optional[float] = pydantic.Field(default=None, description="Price of SKU") + unit: typing.Optional[str] = pydantic.Field(default=None, description="Currency of Item") + + def json(self, **kwargs: typing.Any) -> str: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().json(**kwargs_with_defaults) + + def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().dict(**kwargs_with_defaults) + + class Config: + frozen = True + smart_union = True + json_encoders = {dt.datetime: serialize_datetime} diff --git a/src/webflow/resources/products/types/products_create_sku_response.py b/src/webflow/resources/products/types/products_create_sku_response.py index d415ced..c176596 100644 --- a/src/webflow/resources/products/types/products_create_sku_response.py +++ b/src/webflow/resources/products/types/products_create_sku_response.py @@ -13,7 +13,7 @@ class ProductsCreateSkuResponse(pydantic.BaseModel): - skus: typing.Optional[typing.List[Sku]] + skus: typing.Optional[typing.List[Sku]] = None def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/resources/scripts/client.py b/src/webflow/resources/scripts/client.py index 846257c..abdab23 100644 --- a/src/webflow/resources/scripts/client.py +++ b/src/webflow/resources/scripts/client.py @@ -7,6 +7,8 @@ from ...core.api_error import ApiError from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.jsonable_encoder import jsonable_encoder +from ...core.remove_none_from_dict import remove_none_from_dict +from ...core.request_options import RequestOptions from ...errors.bad_request_error import BadRequestError from ...errors.internal_server_error import InternalServerError from ...errors.not_found_error import NotFoundError @@ -28,12 +30,14 @@ class ScriptsClient: def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper - def list(self, site_id: str) -> RegisteredScriptList: + def list(self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> RegisteredScriptList: """ List of scripts registered to a Site.

In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate `custom_code` endpoints. Additionally, Scripts can be remotely hosted, or registered as inline snippets.

Required scope | `custom_code:read` Parameters: - site_id: str. Unique identifier for a Site + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -41,14 +45,28 @@ def list(self, site_id: str) -> RegisteredScriptList: access_token="YOUR_ACCESS_TOKEN", ) client.scripts.list( - site_id="site-id", + site_id="site_id", ) """ _response = self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/registered_scripts"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/registered_scripts" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(RegisteredScriptList, _response.json()) # type: ignore @@ -77,6 +95,7 @@ def register_hosted( can_copy: typing.Optional[bool] = OMIT, version: str, display_name: str, + request_options: typing.Optional[RequestOptions] = None, ) -> CustomCodeResponse: """ Add a script to a Site's Custom Code registry.

In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate `custom_code` endpoints. Additionally, Scripts can be remotely hosted, or registered as inline snippets.

Required scope | `custom_code:write` @@ -93,6 +112,21 @@ def register_hosted( - version: str. A Semantic Version (SemVer) string, denoting the version of the script - display_name: str. User-facing name for the script + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- + from webflow.client import Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.scripts.register_hosted( + site_id="site_id", + hosted_location="hostedLocation", + integrity_hash="integrityHash", + version="version", + display_name="displayName", + ) """ _request: typing.Dict[str, typing.Any] = { "hostedLocation": hosted_location, @@ -105,11 +139,29 @@ def register_hosted( _response = self._client_wrapper.httpx_client.request( "POST", urllib.parse.urljoin( - f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/registered_scripts/hosted" + f"{self._client_wrapper.get_base_url()}/", + f"sites/{jsonable_encoder(site_id)}/registered_scripts/hosted", ), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(CustomCodeResponse, _response.json()) # type: ignore @@ -138,6 +190,7 @@ def register_inline( can_copy: typing.Optional[bool] = OMIT, version: str, display_name: str, + request_options: typing.Optional[RequestOptions] = None, ) -> CustomCodeResponse: """ Add a script to a Site's Custom Code registry. Inline scripts can be between 1 and 2000 characters.

In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate `custom_code` endpoints.

Required scope | `custom_code:write` @@ -154,6 +207,20 @@ def register_inline( - version: str. A Semantic Version (SemVer) string, denoting the version of the script - display_name: str. User-facing name for the script + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- + from webflow.client import Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.scripts.register_inline( + site_id="site_id", + source_code="alert('hello world');", + version="0.0.1", + display_name="Alert", + ) """ _request: typing.Dict[str, typing.Any] = { "sourceCode": source_code, @@ -167,11 +234,29 @@ def register_inline( _response = self._client_wrapper.httpx_client.request( "POST", urllib.parse.urljoin( - f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/registered_scripts/inline" + f"{self._client_wrapper.get_base_url()}/", + f"sites/{jsonable_encoder(site_id)}/registered_scripts/inline", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) ), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(CustomCodeResponse, _response.json()) # type: ignore @@ -196,12 +281,16 @@ class AsyncScriptsClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): self._client_wrapper = client_wrapper - async def list(self, site_id: str) -> RegisteredScriptList: + async def list( + self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> RegisteredScriptList: """ List of scripts registered to a Site.

In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate `custom_code` endpoints. Additionally, Scripts can be remotely hosted, or registered as inline snippets.

Required scope | `custom_code:read` Parameters: - site_id: str. Unique identifier for a Site + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -209,14 +298,28 @@ async def list(self, site_id: str) -> RegisteredScriptList: access_token="YOUR_ACCESS_TOKEN", ) await client.scripts.list( - site_id="site-id", + site_id="site_id", ) """ _response = await self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/registered_scripts"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/registered_scripts" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(RegisteredScriptList, _response.json()) # type: ignore @@ -245,6 +348,7 @@ async def register_hosted( can_copy: typing.Optional[bool] = OMIT, version: str, display_name: str, + request_options: typing.Optional[RequestOptions] = None, ) -> CustomCodeResponse: """ Add a script to a Site's Custom Code registry.

In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate `custom_code` endpoints. Additionally, Scripts can be remotely hosted, or registered as inline snippets.

Required scope | `custom_code:write` @@ -261,6 +365,21 @@ async def register_hosted( - version: str. A Semantic Version (SemVer) string, denoting the version of the script - display_name: str. User-facing name for the script + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- + from webflow.client import AsyncWebflow + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + await client.scripts.register_hosted( + site_id="site_id", + hosted_location="hostedLocation", + integrity_hash="integrityHash", + version="version", + display_name="displayName", + ) """ _request: typing.Dict[str, typing.Any] = { "hostedLocation": hosted_location, @@ -273,11 +392,29 @@ async def register_hosted( _response = await self._client_wrapper.httpx_client.request( "POST", urllib.parse.urljoin( - f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/registered_scripts/hosted" + f"{self._client_wrapper.get_base_url()}/", + f"sites/{jsonable_encoder(site_id)}/registered_scripts/hosted", ), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(CustomCodeResponse, _response.json()) # type: ignore @@ -306,6 +443,7 @@ async def register_inline( can_copy: typing.Optional[bool] = OMIT, version: str, display_name: str, + request_options: typing.Optional[RequestOptions] = None, ) -> CustomCodeResponse: """ Add a script to a Site's Custom Code registry. Inline scripts can be between 1 and 2000 characters.

In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate `custom_code` endpoints.

Required scope | `custom_code:write` @@ -322,6 +460,20 @@ async def register_inline( - version: str. A Semantic Version (SemVer) string, denoting the version of the script - display_name: str. User-facing name for the script + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- + from webflow.client import AsyncWebflow + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + await client.scripts.register_inline( + site_id="site_id", + source_code="alert('hello world');", + version="0.0.1", + display_name="Alert", + ) """ _request: typing.Dict[str, typing.Any] = { "sourceCode": source_code, @@ -335,11 +487,29 @@ async def register_inline( _response = await self._client_wrapper.httpx_client.request( "POST", urllib.parse.urljoin( - f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/registered_scripts/inline" + f"{self._client_wrapper.get_base_url()}/", + f"sites/{jsonable_encoder(site_id)}/registered_scripts/inline", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) ), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(CustomCodeResponse, _response.json()) # type: ignore diff --git a/src/webflow/resources/sites/__init__.py b/src/webflow/resources/sites/__init__.py index 8985ac7..c4ea3e7 100644 --- a/src/webflow/resources/sites/__init__.py +++ b/src/webflow/resources/sites/__init__.py @@ -1,5 +1,5 @@ # This file was auto-generated by Fern from our API Definition. -from .resources import scripts +from .resources import activity_logs, scripts -__all__ = ["scripts"] +__all__ = ["activity_logs", "scripts"] diff --git a/src/webflow/resources/sites/client.py b/src/webflow/resources/sites/client.py index f171dc9..0cc373d 100644 --- a/src/webflow/resources/sites/client.py +++ b/src/webflow/resources/sites/client.py @@ -7,6 +7,8 @@ from ...core.api_error import ApiError from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.jsonable_encoder import jsonable_encoder +from ...core.remove_none_from_dict import remove_none_from_dict +from ...core.request_options import RequestOptions from ...errors.bad_request_error import BadRequestError from ...errors.forbidden_error import ForbiddenError from ...errors.internal_server_error import InternalServerError @@ -16,6 +18,7 @@ from ...types.domain import Domain from ...types.site import Site from ...types.sites import Sites +from .resources.activity_logs.client import ActivityLogsClient, AsyncActivityLogsClient from .resources.scripts.client import AsyncScriptsClient, ScriptsClient try: @@ -30,12 +33,15 @@ class SitesClient: def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper + self.activity_logs = ActivityLogsClient(client_wrapper=self._client_wrapper) self.scripts = ScriptsClient(client_wrapper=self._client_wrapper) - def list(self) -> Sites: + def list(self, *, request_options: typing.Optional[RequestOptions] = None) -> Sites: """ List of all sites the provided access token is able to access.

Required scope | `sites:read` + Parameters: + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -47,8 +53,20 @@ def list(self) -> Sites: _response = self._client_wrapper.httpx_client.request( "GET", urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "sites"), - headers=self._client_wrapper.get_headers(), - timeout=60, + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Sites, _response.json()) # type: ignore @@ -68,12 +86,14 @@ def list(self) -> Sites: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def get(self, site_id: str) -> Site: + def get(self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Site: """ Get a site by site id

Required scope | `sites:read` Parameters: - site_id: str. Unique identifier for a Site + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -81,14 +101,26 @@ def get(self, site_id: str) -> Site: access_token="YOUR_ACCESS_TOKEN", ) client.sites.get( - site_id="site-id", + site_id="site_id", ) """ _response = self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}"), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Site, _response.json()) # type: ignore @@ -108,12 +140,14 @@ def get(self, site_id: str) -> Site: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def get_custom_domain(self, site_id: str) -> Domain: + def get_custom_domain(self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Domain: """ Get a list of all custom domains related to site.

Required scope | `sites:read` Parameters: - site_id: str. Unique identifier for a Site + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -121,14 +155,28 @@ def get_custom_domain(self, site_id: str) -> Domain: access_token="YOUR_ACCESS_TOKEN", ) client.sites.get_custom_domain( - site_id="site-id", + site_id="site_id", ) """ _response = self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/custom_domains"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/custom_domains" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Domain, _response.json()) # type: ignore @@ -152,8 +200,9 @@ def publish( self, site_id: str, *, - custom_domains: typing.Optional[typing.List[str]] = OMIT, + custom_domains: typing.Optional[typing.Sequence[str]] = OMIT, publish_to_webflow_subdomain: typing.Optional[bool] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> None: """ Publish a site to one more more domains.

Required scope | `sites:write` @@ -161,9 +210,11 @@ def publish( Parameters: - site_id: str. Unique identifier for a Site - - custom_domains: typing.Optional[typing.List[str]]. Array of Custom Domain ids to publish + - custom_domains: typing.Optional[typing.Sequence[str]]. Array of Custom Domain ids to publish - publish_to_webflow_subdomain: typing.Optional[bool]. Choice of whether to publish to the default Webflow Subdomain + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -171,7 +222,7 @@ def publish( access_token="YOUR_ACCESS_TOKEN", ) client.sites.publish( - site_id="site-id", + site_id="site_id", publish_to_webflow_subdomain=False, ) """ @@ -182,10 +233,29 @@ def publish( _request["publishToWebflowSubdomain"] = publish_to_webflow_subdomain _response = self._client_wrapper.httpx_client.request( "POST", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/publish"), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/publish" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return @@ -209,12 +279,15 @@ def publish( class AsyncSitesClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): self._client_wrapper = client_wrapper + self.activity_logs = AsyncActivityLogsClient(client_wrapper=self._client_wrapper) self.scripts = AsyncScriptsClient(client_wrapper=self._client_wrapper) - async def list(self) -> Sites: + async def list(self, *, request_options: typing.Optional[RequestOptions] = None) -> Sites: """ List of all sites the provided access token is able to access.

Required scope | `sites:read` + Parameters: + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -226,8 +299,20 @@ async def list(self) -> Sites: _response = await self._client_wrapper.httpx_client.request( "GET", urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "sites"), - headers=self._client_wrapper.get_headers(), - timeout=60, + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Sites, _response.json()) # type: ignore @@ -247,12 +332,14 @@ async def list(self) -> Sites: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def get(self, site_id: str) -> Site: + async def get(self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Site: """ Get a site by site id

Required scope | `sites:read` Parameters: - site_id: str. Unique identifier for a Site + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -260,14 +347,26 @@ async def get(self, site_id: str) -> Site: access_token="YOUR_ACCESS_TOKEN", ) await client.sites.get( - site_id="site-id", + site_id="site_id", ) """ _response = await self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}"), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Site, _response.json()) # type: ignore @@ -287,12 +386,16 @@ async def get(self, site_id: str) -> Site: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def get_custom_domain(self, site_id: str) -> Domain: + async def get_custom_domain( + self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> Domain: """ Get a list of all custom domains related to site.

Required scope | `sites:read` Parameters: - site_id: str. Unique identifier for a Site + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -300,14 +403,28 @@ async def get_custom_domain(self, site_id: str) -> Domain: access_token="YOUR_ACCESS_TOKEN", ) await client.sites.get_custom_domain( - site_id="site-id", + site_id="site_id", ) """ _response = await self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/custom_domains"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/custom_domains" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Domain, _response.json()) # type: ignore @@ -331,8 +448,9 @@ async def publish( self, site_id: str, *, - custom_domains: typing.Optional[typing.List[str]] = OMIT, + custom_domains: typing.Optional[typing.Sequence[str]] = OMIT, publish_to_webflow_subdomain: typing.Optional[bool] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> None: """ Publish a site to one more more domains.

Required scope | `sites:write` @@ -340,9 +458,11 @@ async def publish( Parameters: - site_id: str. Unique identifier for a Site - - custom_domains: typing.Optional[typing.List[str]]. Array of Custom Domain ids to publish + - custom_domains: typing.Optional[typing.Sequence[str]]. Array of Custom Domain ids to publish - publish_to_webflow_subdomain: typing.Optional[bool]. Choice of whether to publish to the default Webflow Subdomain + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -350,7 +470,7 @@ async def publish( access_token="YOUR_ACCESS_TOKEN", ) await client.sites.publish( - site_id="site-id", + site_id="site_id", publish_to_webflow_subdomain=False, ) """ @@ -361,10 +481,29 @@ async def publish( _request["publishToWebflowSubdomain"] = publish_to_webflow_subdomain _response = await self._client_wrapper.httpx_client.request( "POST", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/publish"), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/publish" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return diff --git a/src/webflow/resources/sites/resources/__init__.py b/src/webflow/resources/sites/resources/__init__.py index 58b2c01..b143a1f 100644 --- a/src/webflow/resources/sites/resources/__init__.py +++ b/src/webflow/resources/sites/resources/__init__.py @@ -1,5 +1,5 @@ # This file was auto-generated by Fern from our API Definition. -from . import scripts +from . import activity_logs, scripts -__all__ = ["scripts"] +__all__ = ["activity_logs", "scripts"] diff --git a/src/webflow/resources/sites/resources/activity_logs/__init__.py b/src/webflow/resources/sites/resources/activity_logs/__init__.py new file mode 100644 index 0000000..f3ea265 --- /dev/null +++ b/src/webflow/resources/sites/resources/activity_logs/__init__.py @@ -0,0 +1,2 @@ +# This file was auto-generated by Fern from our API Definition. + diff --git a/src/webflow/resources/sites/resources/activity_logs/client.py b/src/webflow/resources/sites/resources/activity_logs/client.py new file mode 100644 index 0000000..a0edffd --- /dev/null +++ b/src/webflow/resources/sites/resources/activity_logs/client.py @@ -0,0 +1,181 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +import urllib.parse +from json.decoder import JSONDecodeError + +from .....core.api_error import ApiError +from .....core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from .....core.jsonable_encoder import jsonable_encoder +from .....core.remove_none_from_dict import remove_none_from_dict +from .....core.request_options import RequestOptions +from .....errors.forbidden_error import ForbiddenError +from .....errors.internal_server_error import InternalServerError +from .....errors.not_found_error import NotFoundError +from .....errors.too_many_requests_error import TooManyRequestsError +from .....types.site_activity_log_response import SiteActivityLogResponse + +try: + import pydantic.v1 as pydantic # type: ignore +except ImportError: + import pydantic # type: ignore + + +class ActivityLogsClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def list( + self, + site_id: str, + *, + limit: typing.Optional[float] = None, + offset: typing.Optional[float] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SiteActivityLogResponse: + """ + Retrieve Activity Logs for a specific Site. Requires Site to be on an Enterprise plan.

Required scope | `site_activity:read` + + Parameters: + - site_id: str. Unique identifier for a Site + + - limit: typing.Optional[float]. Maximum number of records to be returned (max limit: 100) + + - offset: typing.Optional[float]. Offset used for pagination if the results have more than limit records + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- + from webflow.client import Webflow + + client = Webflow( + access_token="YOUR_ACCESS_TOKEN", + ) + client.sites.activity_logs.list( + site_id="site_id", + ) + """ + _response = self._client_wrapper.httpx_client.request( + "GET", + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/activity_logs" + ), + params=jsonable_encoder( + remove_none_from_dict( + { + "limit": limit, + "offset": offset, + **( + request_options.get("additional_query_parameters", {}) + if request_options is not None + else {} + ), + } + ) + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, + ) + if 200 <= _response.status_code < 300: + return pydantic.parse_obj_as(SiteActivityLogResponse, _response.json()) # type: ignore + if _response.status_code == 403: + raise ForbiddenError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 404: + raise NotFoundError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 429: + raise TooManyRequestsError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 500: + raise InternalServerError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + try: + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + +class AsyncActivityLogsClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def list( + self, + site_id: str, + *, + limit: typing.Optional[float] = None, + offset: typing.Optional[float] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SiteActivityLogResponse: + """ + Retrieve Activity Logs for a specific Site. Requires Site to be on an Enterprise plan.

Required scope | `site_activity:read` + + Parameters: + - site_id: str. Unique identifier for a Site + + - limit: typing.Optional[float]. Maximum number of records to be returned (max limit: 100) + + - offset: typing.Optional[float]. Offset used for pagination if the results have more than limit records + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- + from webflow.client import AsyncWebflow + + client = AsyncWebflow( + access_token="YOUR_ACCESS_TOKEN", + ) + await client.sites.activity_logs.list( + site_id="site_id", + ) + """ + _response = await self._client_wrapper.httpx_client.request( + "GET", + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/activity_logs" + ), + params=jsonable_encoder( + remove_none_from_dict( + { + "limit": limit, + "offset": offset, + **( + request_options.get("additional_query_parameters", {}) + if request_options is not None + else {} + ), + } + ) + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, + ) + if 200 <= _response.status_code < 300: + return pydantic.parse_obj_as(SiteActivityLogResponse, _response.json()) # type: ignore + if _response.status_code == 403: + raise ForbiddenError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 404: + raise NotFoundError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 429: + raise TooManyRequestsError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 500: + raise InternalServerError(pydantic.parse_obj_as(typing.Any, _response.json())) # type: ignore + try: + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) diff --git a/src/webflow/resources/sites/resources/scripts/client.py b/src/webflow/resources/sites/resources/scripts/client.py index 928c15c..8128b13 100644 --- a/src/webflow/resources/sites/resources/scripts/client.py +++ b/src/webflow/resources/sites/resources/scripts/client.py @@ -8,6 +8,7 @@ from .....core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from .....core.jsonable_encoder import jsonable_encoder from .....core.remove_none_from_dict import remove_none_from_dict +from .....core.request_options import RequestOptions from .....errors.bad_request_error import BadRequestError from .....errors.internal_server_error import InternalServerError from .....errors.not_found_error import NotFoundError @@ -29,12 +30,16 @@ class ScriptsClient: def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper - def get_custom_code(self, site_id: str) -> ScriptApplyList: + def get_custom_code( + self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> ScriptApplyList: """ Get all registered scripts that have been applied to a specific Site. Required scope | `custom_code:read` Parameters: - site_id: str. Unique identifier for a Site + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -42,14 +47,28 @@ def get_custom_code(self, site_id: str) -> ScriptApplyList: access_token="YOUR_ACCESS_TOKEN", ) client.sites.scripts.get_custom_code( - site_id="site-id", + site_id="site_id", ) """ _response = self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/custom_code"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/custom_code" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(ScriptApplyList, _response.json()) # type: ignore @@ -69,7 +88,9 @@ def get_custom_code(self, site_id: str) -> ScriptApplyList: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def upsert_custom_code(self, site_id: str, *, request: ScriptApplyList) -> ScriptApplyList: + def upsert_custom_code( + self, site_id: str, *, request: ScriptApplyList, request_options: typing.Optional[RequestOptions] = None + ) -> ScriptApplyList: """ Add a registered script to a Site.

In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate `custom_code` endpoints.

Required scope | `custom_code:write` @@ -77,24 +98,64 @@ def upsert_custom_code(self, site_id: str, *, request: ScriptApplyList) -> Scrip - site_id: str. Unique identifier for a Site - request: ScriptApplyList. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- - from webflow import ScriptApplyList + from webflow import ScriptApply, ScriptApplyList, ScriptApplyLocation from webflow.client import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) client.sites.scripts.upsert_custom_code( - site_id="site-id", - request=ScriptApplyList(), + site_id="site_id", + request=ScriptApplyList( + scripts=[ + ScriptApply( + id="cms_slider", + location=ScriptApplyLocation.HEADER, + version="1.0.0", + attributes={"my-attribute": "some-value"}, + ), + ScriptApply( + id="alert", + location=ScriptApplyLocation.HEADER, + version="0.0.1", + ), + ScriptApply( + id="id", + location=ScriptApplyLocation.HEADER, + version="version", + ), + ], + ), ) """ _response = self._client_wrapper.httpx_client.request( "PUT", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/custom_code"), - json=jsonable_encoder(request), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/custom_code" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(ScriptApplyList, _response.json()) # type: ignore @@ -114,12 +175,14 @@ def upsert_custom_code(self, site_id: str, *, request: ScriptApplyList) -> Scrip raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def delete_custom_code(self, site_id: str) -> None: + def delete_custom_code(self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> None: """ Delete the custom code block that an app created for a Site Parameters: - site_id: str. Unique identifier for a Site + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -127,14 +190,28 @@ def delete_custom_code(self, site_id: str) -> None: access_token="YOUR_ACCESS_TOKEN", ) client.sites.scripts.delete_custom_code( - site_id="site-id", + site_id="site_id", ) """ _response = self._client_wrapper.httpx_client.request( "DELETE", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/custom_code"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/custom_code" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return @@ -155,7 +232,12 @@ def delete_custom_code(self, site_id: str) -> None: raise ApiError(status_code=_response.status_code, body=_response_json) def list_custom_code_blocks( - self, site_id: str, *, offset: typing.Optional[float] = None, limit: typing.Optional[float] = None + self, + site_id: str, + *, + offset: typing.Optional[float] = None, + limit: typing.Optional[float] = None, + request_options: typing.Optional[RequestOptions] = None, ) -> ListCustomCodeBlocks: """ Get all instances of Custom Code applied to a Site or Pages. Required scope | `custom_code:read` @@ -166,6 +248,8 @@ def list_custom_code_blocks( - offset: typing.Optional[float]. Offset used for pagination if the results have more than limit records - limit: typing.Optional[float]. Maximum number of records to be returned (max limit: 100) + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -173,15 +257,38 @@ def list_custom_code_blocks( access_token="YOUR_ACCESS_TOKEN", ) client.sites.scripts.list_custom_code_blocks( - site_id="site-id", + site_id="site_id", ) """ _response = self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/custom_code/blocks"), - params=remove_none_from_dict({"offset": offset, "limit": limit}), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/custom_code/blocks" + ), + params=jsonable_encoder( + remove_none_from_dict( + { + "offset": offset, + "limit": limit, + **( + request_options.get("additional_query_parameters", {}) + if request_options is not None + else {} + ), + } + ) + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(ListCustomCodeBlocks, _response.json()) # type: ignore @@ -206,12 +313,16 @@ class AsyncScriptsClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): self._client_wrapper = client_wrapper - async def get_custom_code(self, site_id: str) -> ScriptApplyList: + async def get_custom_code( + self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> ScriptApplyList: """ Get all registered scripts that have been applied to a specific Site. Required scope | `custom_code:read` Parameters: - site_id: str. Unique identifier for a Site + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -219,14 +330,28 @@ async def get_custom_code(self, site_id: str) -> ScriptApplyList: access_token="YOUR_ACCESS_TOKEN", ) await client.sites.scripts.get_custom_code( - site_id="site-id", + site_id="site_id", ) """ _response = await self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/custom_code"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/custom_code" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(ScriptApplyList, _response.json()) # type: ignore @@ -246,7 +371,9 @@ async def get_custom_code(self, site_id: str) -> ScriptApplyList: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def upsert_custom_code(self, site_id: str, *, request: ScriptApplyList) -> ScriptApplyList: + async def upsert_custom_code( + self, site_id: str, *, request: ScriptApplyList, request_options: typing.Optional[RequestOptions] = None + ) -> ScriptApplyList: """ Add a registered script to a Site.

In order to use the Custom Code APIs for Sites and Pages, Custom Code Scripts must first be registered to a Site via the `registered_scripts` endpoints, and then applied to a Site or Page using the appropriate `custom_code` endpoints.

Required scope | `custom_code:write` @@ -254,24 +381,64 @@ async def upsert_custom_code(self, site_id: str, *, request: ScriptApplyList) -> - site_id: str. Unique identifier for a Site - request: ScriptApplyList. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- - from webflow import ScriptApplyList + from webflow import ScriptApply, ScriptApplyList, ScriptApplyLocation from webflow.client import AsyncWebflow client = AsyncWebflow( access_token="YOUR_ACCESS_TOKEN", ) await client.sites.scripts.upsert_custom_code( - site_id="site-id", - request=ScriptApplyList(), + site_id="site_id", + request=ScriptApplyList( + scripts=[ + ScriptApply( + id="cms_slider", + location=ScriptApplyLocation.HEADER, + version="1.0.0", + attributes={"my-attribute": "some-value"}, + ), + ScriptApply( + id="alert", + location=ScriptApplyLocation.HEADER, + version="0.0.1", + ), + ScriptApply( + id="id", + location=ScriptApplyLocation.HEADER, + version="version", + ), + ], + ), ) """ _response = await self._client_wrapper.httpx_client.request( "PUT", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/custom_code"), - json=jsonable_encoder(request), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/custom_code" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(ScriptApplyList, _response.json()) # type: ignore @@ -291,12 +458,16 @@ async def upsert_custom_code(self, site_id: str, *, request: ScriptApplyList) -> raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def delete_custom_code(self, site_id: str) -> None: + async def delete_custom_code( + self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> None: """ Delete the custom code block that an app created for a Site Parameters: - site_id: str. Unique identifier for a Site + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -304,14 +475,28 @@ async def delete_custom_code(self, site_id: str) -> None: access_token="YOUR_ACCESS_TOKEN", ) await client.sites.scripts.delete_custom_code( - site_id="site-id", + site_id="site_id", ) """ _response = await self._client_wrapper.httpx_client.request( "DELETE", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/custom_code"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/custom_code" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return @@ -332,7 +517,12 @@ async def delete_custom_code(self, site_id: str) -> None: raise ApiError(status_code=_response.status_code, body=_response_json) async def list_custom_code_blocks( - self, site_id: str, *, offset: typing.Optional[float] = None, limit: typing.Optional[float] = None + self, + site_id: str, + *, + offset: typing.Optional[float] = None, + limit: typing.Optional[float] = None, + request_options: typing.Optional[RequestOptions] = None, ) -> ListCustomCodeBlocks: """ Get all instances of Custom Code applied to a Site or Pages. Required scope | `custom_code:read` @@ -343,6 +533,8 @@ async def list_custom_code_blocks( - offset: typing.Optional[float]. Offset used for pagination if the results have more than limit records - limit: typing.Optional[float]. Maximum number of records to be returned (max limit: 100) + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -350,15 +542,38 @@ async def list_custom_code_blocks( access_token="YOUR_ACCESS_TOKEN", ) await client.sites.scripts.list_custom_code_blocks( - site_id="site-id", + site_id="site_id", ) """ _response = await self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/custom_code/blocks"), - params=remove_none_from_dict({"offset": offset, "limit": limit}), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/custom_code/blocks" + ), + params=jsonable_encoder( + remove_none_from_dict( + { + "offset": offset, + "limit": limit, + **( + request_options.get("additional_query_parameters", {}) + if request_options is not None + else {} + ), + } + ) + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(ListCustomCodeBlocks, _response.json()) # type: ignore diff --git a/src/webflow/resources/token/client.py b/src/webflow/resources/token/client.py index a47e263..06fc514 100644 --- a/src/webflow/resources/token/client.py +++ b/src/webflow/resources/token/client.py @@ -6,6 +6,9 @@ from ...core.api_error import ApiError from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.jsonable_encoder import jsonable_encoder +from ...core.remove_none_from_dict import remove_none_from_dict +from ...core.request_options import RequestOptions from ...errors.forbidden_error import ForbiddenError from ...errors.unauthorized_error import UnauthorizedError from ...types.authorization import Authorization @@ -21,10 +24,12 @@ class TokenClient: def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper - def authorized_by(self) -> AuthorizedUser: + def authorized_by(self, *, request_options: typing.Optional[RequestOptions] = None) -> AuthorizedUser: """ Information about the Authorized User

Required Scope | `authorized_user:read` + Parameters: + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -36,8 +41,20 @@ def authorized_by(self) -> AuthorizedUser: _response = self._client_wrapper.httpx_client.request( "GET", urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "token/authorized_by"), - headers=self._client_wrapper.get_headers(), - timeout=60, + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(AuthorizedUser, _response.json()) # type: ignore @@ -51,10 +68,12 @@ def authorized_by(self) -> AuthorizedUser: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def introspect(self) -> Authorization: + def introspect(self, *, request_options: typing.Optional[RequestOptions] = None) -> Authorization: """ Information about the authorization token + Parameters: + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -66,8 +85,20 @@ def introspect(self) -> Authorization: _response = self._client_wrapper.httpx_client.request( "GET", urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "token/introspect"), - headers=self._client_wrapper.get_headers(), - timeout=60, + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Authorization, _response.json()) # type: ignore @@ -84,10 +115,12 @@ class AsyncTokenClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): self._client_wrapper = client_wrapper - async def authorized_by(self) -> AuthorizedUser: + async def authorized_by(self, *, request_options: typing.Optional[RequestOptions] = None) -> AuthorizedUser: """ Information about the Authorized User

Required Scope | `authorized_user:read` + Parameters: + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -99,8 +132,20 @@ async def authorized_by(self) -> AuthorizedUser: _response = await self._client_wrapper.httpx_client.request( "GET", urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "token/authorized_by"), - headers=self._client_wrapper.get_headers(), - timeout=60, + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(AuthorizedUser, _response.json()) # type: ignore @@ -114,10 +159,12 @@ async def authorized_by(self) -> AuthorizedUser: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def introspect(self) -> Authorization: + async def introspect(self, *, request_options: typing.Optional[RequestOptions] = None) -> Authorization: """ Information about the authorization token + Parameters: + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -129,8 +176,20 @@ async def introspect(self) -> Authorization: _response = await self._client_wrapper.httpx_client.request( "GET", urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "token/introspect"), - headers=self._client_wrapper.get_headers(), - timeout=60, + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Authorization, _response.json()) # type: ignore diff --git a/src/webflow/resources/users/__init__.py b/src/webflow/resources/users/__init__.py index 75665c6..88e72a2 100644 --- a/src/webflow/resources/users/__init__.py +++ b/src/webflow/resources/users/__init__.py @@ -1,5 +1,5 @@ # This file was auto-generated by Fern from our API Definition. -from .types import UsersListRequestSort +from .types import UsersListRequestSort, UsersUpdateRequestData -__all__ = ["UsersListRequestSort"] +__all__ = ["UsersListRequestSort", "UsersUpdateRequestData"] diff --git a/src/webflow/resources/users/client.py b/src/webflow/resources/users/client.py index 87cf17c..f3d62bf 100644 --- a/src/webflow/resources/users/client.py +++ b/src/webflow/resources/users/client.py @@ -8,6 +8,7 @@ from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.jsonable_encoder import jsonable_encoder from ...core.remove_none_from_dict import remove_none_from_dict +from ...core.request_options import RequestOptions from ...errors.bad_request_error import BadRequestError from ...errors.conflict_error import ConflictError from ...errors.forbidden_error import ForbiddenError @@ -18,6 +19,7 @@ from ...types.user import User from ...types.user_list import UserList from .types.users_list_request_sort import UsersListRequestSort +from .types.users_update_request_data import UsersUpdateRequestData try: import pydantic.v1 as pydantic # type: ignore @@ -39,6 +41,7 @@ def list( offset: typing.Optional[float] = None, limit: typing.Optional[float] = None, sort: typing.Optional[UsersListRequestSort] = None, + request_options: typing.Optional[RequestOptions] = None, ) -> UserList: """ Get a list of users for a site

Required scope | `users:read` @@ -54,24 +57,46 @@ def list( Example(`CreatedOn`, `Email`, `Status`, `LastLogin`, `UpdatedOn`). - Can be prefixed with a `-` to reverse the sort (ex. `-CreatedOn`)--- - from webflow import UsersListRequestSort + Can be prefixed with a `-` to reverse the sort (ex. `-CreatedOn`) + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- from webflow.client import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) client.users.list( - site_id="site-id", - sort=UsersListRequestSort.CREATED_ON_ASCENDING, + site_id="site_id", ) """ _response = self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/users"), - params=remove_none_from_dict({"offset": offset, "limit": limit, "sort": sort}), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/users"), + params=jsonable_encoder( + remove_none_from_dict( + { + "offset": offset, + "limit": limit, + "sort": sort, + **( + request_options.get("additional_query_parameters", {}) + if request_options is not None + else {} + ), + } + ) + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(UserList, _response.json()) # type: ignore @@ -93,7 +118,7 @@ def list( raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def get(self, site_id: str, user_id: str) -> User: + def get(self, site_id: str, user_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> User: """ Get a User by ID

Required scope | `users:read` @@ -101,6 +126,8 @@ def get(self, site_id: str, user_id: str) -> User: - site_id: str. Unique identifier for a Site - user_id: str. Unique identifier for a User + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -108,15 +135,30 @@ def get(self, site_id: str, user_id: str) -> User: access_token="YOUR_ACCESS_TOKEN", ) client.users.get( - site_id="site-id", - user_id="user-id", + site_id="site_id", + user_id="user_id", ) """ _response = self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/users/{user_id}"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", + f"sites/{jsonable_encoder(site_id)}/users/{jsonable_encoder(user_id)}", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(User, _response.json()) # type: ignore @@ -138,7 +180,7 @@ def get(self, site_id: str, user_id: str) -> User: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def delete(self, site_id: str, user_id: str) -> None: + def delete(self, site_id: str, user_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> None: """ Delete a User by ID

Required scope | `users:write` @@ -146,6 +188,8 @@ def delete(self, site_id: str, user_id: str) -> None: - site_id: str. Unique identifier for a Site - user_id: str. Unique identifier for a User + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -153,15 +197,30 @@ def delete(self, site_id: str, user_id: str) -> None: access_token="YOUR_ACCESS_TOKEN", ) client.users.delete( - site_id="site-id", - user_id="user-id", + site_id="site_id", + user_id="user_id", ) """ _response = self._client_wrapper.httpx_client.request( "DELETE", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/users/{user_id}"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", + f"sites/{jsonable_encoder(site_id)}/users/{jsonable_encoder(user_id)}", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return @@ -183,7 +242,15 @@ def delete(self, site_id: str, user_id: str) -> None: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def update(self, site_id: str, user_id: str, *, request: User) -> User: + def update( + self, + site_id: str, + user_id: str, + *, + data: typing.Optional[UsersUpdateRequestData] = OMIT, + access_groups: typing.Optional[typing.Sequence[str]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> User: """ Update a User by ID

Required scope | `users:write` @@ -194,53 +261,60 @@ def update(self, site_id: str, user_id: str, *, request: User) -> User: - user_id: str. Unique identifier for a User - - request: User. - --- - import datetime + - data: typing.Optional[UsersUpdateRequestData]. - from webflow import ( - User, - UserAccessGroupsItem, - UserAccessGroupsItemType, - UserStatus, - ) + - access_groups: typing.Optional[typing.Sequence[str]]. An array of access group slugs. Access groups are assigned to the user as type `admin` and the user remains in the group until removed. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- + from webflow import UsersUpdateRequestData from webflow.client import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) client.users.update( - site_id="site-id", - user_id="user-id", - request=User( - id="6287ec36a841b25637c663df", - last_updated=datetime.datetime.fromisoformat( - "2016-10-24 19:41:29.156000+00:00", - ), - invited_on=datetime.datetime.fromisoformat( - "2016-10-24 19:41:29.156000+00:00", - ), - created_on=datetime.datetime.fromisoformat( - "2016-10-24 19:41:29.156000+00:00", - ), - last_login=datetime.datetime.fromisoformat( - "2016-10-24 19:41:29.156000+00:00", - ), - status=UserStatus.INVITED, - access_groups=[ - UserAccessGroupsItem( - type=UserAccessGroupsItemType.ADMIN, - ) - ], + site_id="site_id", + user_id="user_id", + data=UsersUpdateRequestData( + name="Some One", + accept_privacy=False, + accept_communications=False, ), + access_groups=["webflowers", "platinum", "free-tier", "accessGroups"], ) """ + _request: typing.Dict[str, typing.Any] = {} + if data is not OMIT: + _request["data"] = data + if access_groups is not OMIT: + _request["accessGroups"] = access_groups _response = self._client_wrapper.httpx_client.request( "PATCH", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/users/{user_id}"), - json=jsonable_encoder(request), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", + f"sites/{jsonable_encoder(site_id)}/users/{jsonable_encoder(user_id)}", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(User, _response.json()) # type: ignore @@ -262,7 +336,14 @@ def update(self, site_id: str, user_id: str, *, request: User) -> User: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def invite(self, site_id: str, *, email: str, access_groups: typing.Optional[typing.List[str]] = OMIT) -> User: + def invite( + self, + site_id: str, + *, + email: str, + access_groups: typing.Optional[typing.Sequence[str]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> User: """ Create and invite a user with an email address. The user will be sent and invite via email, which they will need to accept in order to join paid Access Groups.

Required scope | `users:write` @@ -271,16 +352,19 @@ def invite(self, site_id: str, *, email: str, access_groups: typing.Optional[typ - email: str. Email address of user to send invite to - - access_groups: typing.Optional[typing.List[str]]. An array of access group slugs. Access groups are assigned to the user as type `admin` and the user remains in the group until removed. - --- + - access_groups: typing.Optional[typing.Sequence[str]]. An array of access group slugs. Access groups are assigned to the user as type `admin` and the user remains in the group until removed. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- from webflow.client import Webflow client = Webflow( access_token="YOUR_ACCESS_TOKEN", ) client.users.invite( - site_id="site-id", + site_id="site_id", email="some.one@home.com", + access_groups=["webflowers", "accessGroups"], ) """ _request: typing.Dict[str, typing.Any] = {"email": email} @@ -288,10 +372,29 @@ def invite(self, site_id: str, *, email: str, access_groups: typing.Optional[typ _request["accessGroups"] = access_groups _response = self._client_wrapper.httpx_client.request( "POST", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/users/invite"), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/users/invite" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(User, _response.json()) # type: ignore @@ -327,6 +430,7 @@ async def list( offset: typing.Optional[float] = None, limit: typing.Optional[float] = None, sort: typing.Optional[UsersListRequestSort] = None, + request_options: typing.Optional[RequestOptions] = None, ) -> UserList: """ Get a list of users for a site

Required scope | `users:read` @@ -342,24 +446,46 @@ async def list( Example(`CreatedOn`, `Email`, `Status`, `LastLogin`, `UpdatedOn`). - Can be prefixed with a `-` to reverse the sort (ex. `-CreatedOn`)--- - from webflow import UsersListRequestSort + Can be prefixed with a `-` to reverse the sort (ex. `-CreatedOn`) + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- from webflow.client import AsyncWebflow client = AsyncWebflow( access_token="YOUR_ACCESS_TOKEN", ) await client.users.list( - site_id="site-id", - sort=UsersListRequestSort.CREATED_ON_ASCENDING, + site_id="site_id", ) """ _response = await self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/users"), - params=remove_none_from_dict({"offset": offset, "limit": limit, "sort": sort}), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/users"), + params=jsonable_encoder( + remove_none_from_dict( + { + "offset": offset, + "limit": limit, + "sort": sort, + **( + request_options.get("additional_query_parameters", {}) + if request_options is not None + else {} + ), + } + ) + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(UserList, _response.json()) # type: ignore @@ -381,7 +507,7 @@ async def list( raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def get(self, site_id: str, user_id: str) -> User: + async def get(self, site_id: str, user_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> User: """ Get a User by ID

Required scope | `users:read` @@ -389,6 +515,8 @@ async def get(self, site_id: str, user_id: str) -> User: - site_id: str. Unique identifier for a Site - user_id: str. Unique identifier for a User + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -396,15 +524,30 @@ async def get(self, site_id: str, user_id: str) -> User: access_token="YOUR_ACCESS_TOKEN", ) await client.users.get( - site_id="site-id", - user_id="user-id", + site_id="site_id", + user_id="user_id", ) """ _response = await self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/users/{user_id}"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", + f"sites/{jsonable_encoder(site_id)}/users/{jsonable_encoder(user_id)}", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(User, _response.json()) # type: ignore @@ -426,7 +569,9 @@ async def get(self, site_id: str, user_id: str) -> User: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def delete(self, site_id: str, user_id: str) -> None: + async def delete( + self, site_id: str, user_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> None: """ Delete a User by ID

Required scope | `users:write` @@ -434,6 +579,8 @@ async def delete(self, site_id: str, user_id: str) -> None: - site_id: str. Unique identifier for a Site - user_id: str. Unique identifier for a User + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -441,15 +588,30 @@ async def delete(self, site_id: str, user_id: str) -> None: access_token="YOUR_ACCESS_TOKEN", ) await client.users.delete( - site_id="site-id", - user_id="user-id", + site_id="site_id", + user_id="user_id", ) """ _response = await self._client_wrapper.httpx_client.request( "DELETE", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/users/{user_id}"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", + f"sites/{jsonable_encoder(site_id)}/users/{jsonable_encoder(user_id)}", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return @@ -471,7 +633,15 @@ async def delete(self, site_id: str, user_id: str) -> None: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def update(self, site_id: str, user_id: str, *, request: User) -> User: + async def update( + self, + site_id: str, + user_id: str, + *, + data: typing.Optional[UsersUpdateRequestData] = OMIT, + access_groups: typing.Optional[typing.Sequence[str]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> User: """ Update a User by ID

Required scope | `users:write` @@ -482,53 +652,60 @@ async def update(self, site_id: str, user_id: str, *, request: User) -> User: - user_id: str. Unique identifier for a User - - request: User. - --- - import datetime + - data: typing.Optional[UsersUpdateRequestData]. - from webflow import ( - User, - UserAccessGroupsItem, - UserAccessGroupsItemType, - UserStatus, - ) + - access_groups: typing.Optional[typing.Sequence[str]]. An array of access group slugs. Access groups are assigned to the user as type `admin` and the user remains in the group until removed. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- + from webflow import UsersUpdateRequestData from webflow.client import AsyncWebflow client = AsyncWebflow( access_token="YOUR_ACCESS_TOKEN", ) await client.users.update( - site_id="site-id", - user_id="user-id", - request=User( - id="6287ec36a841b25637c663df", - last_updated=datetime.datetime.fromisoformat( - "2016-10-24 19:41:29.156000+00:00", - ), - invited_on=datetime.datetime.fromisoformat( - "2016-10-24 19:41:29.156000+00:00", - ), - created_on=datetime.datetime.fromisoformat( - "2016-10-24 19:41:29.156000+00:00", - ), - last_login=datetime.datetime.fromisoformat( - "2016-10-24 19:41:29.156000+00:00", - ), - status=UserStatus.INVITED, - access_groups=[ - UserAccessGroupsItem( - type=UserAccessGroupsItemType.ADMIN, - ) - ], + site_id="site_id", + user_id="user_id", + data=UsersUpdateRequestData( + name="Some One", + accept_privacy=False, + accept_communications=False, ), + access_groups=["webflowers", "platinum", "free-tier", "accessGroups"], ) """ + _request: typing.Dict[str, typing.Any] = {} + if data is not OMIT: + _request["data"] = data + if access_groups is not OMIT: + _request["accessGroups"] = access_groups _response = await self._client_wrapper.httpx_client.request( "PATCH", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/users/{user_id}"), - json=jsonable_encoder(request), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", + f"sites/{jsonable_encoder(site_id)}/users/{jsonable_encoder(user_id)}", + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(User, _response.json()) # type: ignore @@ -551,7 +728,12 @@ async def update(self, site_id: str, user_id: str, *, request: User) -> User: raise ApiError(status_code=_response.status_code, body=_response_json) async def invite( - self, site_id: str, *, email: str, access_groups: typing.Optional[typing.List[str]] = OMIT + self, + site_id: str, + *, + email: str, + access_groups: typing.Optional[typing.Sequence[str]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> User: """ Create and invite a user with an email address. The user will be sent and invite via email, which they will need to accept in order to join paid Access Groups.

Required scope | `users:write` @@ -561,16 +743,19 @@ async def invite( - email: str. Email address of user to send invite to - - access_groups: typing.Optional[typing.List[str]]. An array of access group slugs. Access groups are assigned to the user as type `admin` and the user remains in the group until removed. - --- + - access_groups: typing.Optional[typing.Sequence[str]]. An array of access group slugs. Access groups are assigned to the user as type `admin` and the user remains in the group until removed. + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- from webflow.client import AsyncWebflow client = AsyncWebflow( access_token="YOUR_ACCESS_TOKEN", ) await client.users.invite( - site_id="site-id", + site_id="site_id", email="some.one@home.com", + access_groups=["webflowers", "accessGroups"], ) """ _request: typing.Dict[str, typing.Any] = {"email": email} @@ -578,10 +763,29 @@ async def invite( _request["accessGroups"] = access_groups _response = await self._client_wrapper.httpx_client.request( "POST", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/users/invite"), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/users/invite" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(User, _response.json()) # type: ignore diff --git a/src/webflow/resources/users/types/__init__.py b/src/webflow/resources/users/types/__init__.py index 3717bf5..cadf367 100644 --- a/src/webflow/resources/users/types/__init__.py +++ b/src/webflow/resources/users/types/__init__.py @@ -1,5 +1,6 @@ # This file was auto-generated by Fern from our API Definition. from .users_list_request_sort import UsersListRequestSort +from .users_update_request_data import UsersUpdateRequestData -__all__ = ["UsersListRequestSort"] +__all__ = ["UsersListRequestSort", "UsersUpdateRequestData"] diff --git a/src/webflow/resources/users/types/users_update_request_data.py b/src/webflow/resources/users/types/users_update_request_data.py new file mode 100644 index 0000000..cb99ef6 --- /dev/null +++ b/src/webflow/resources/users/types/users_update_request_data.py @@ -0,0 +1,39 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +from ....core.datetime_utils import serialize_datetime + +try: + import pydantic.v1 as pydantic # type: ignore +except ImportError: + import pydantic # type: ignore + + +class UsersUpdateRequestData(pydantic.BaseModel): + name: typing.Optional[str] = pydantic.Field(default=None, description="The name of the user") + accept_privacy: typing.Optional[bool] = pydantic.Field( + alias="accept-privacy", + default=None, + description="Boolean indicating if the user has accepted the privacy policy", + ) + accept_communications: typing.Optional[bool] = pydantic.Field( + alias="accept-communications", + default=None, + description="Boolean indicating if the user has accepted to receive communications", + ) + + def json(self, **kwargs: typing.Any) -> str: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().json(**kwargs_with_defaults) + + def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().dict(**kwargs_with_defaults) + + class Config: + frozen = True + smart_union = True + allow_population_by_field_name = True + json_encoders = {dt.datetime: serialize_datetime} diff --git a/src/webflow/resources/webhooks/client.py b/src/webflow/resources/webhooks/client.py index ef9b65c..64b77b0 100644 --- a/src/webflow/resources/webhooks/client.py +++ b/src/webflow/resources/webhooks/client.py @@ -7,6 +7,8 @@ from ...core.api_error import ApiError from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.jsonable_encoder import jsonable_encoder +from ...core.remove_none_from_dict import remove_none_from_dict +from ...core.request_options import RequestOptions from ...errors.bad_request_error import BadRequestError from ...errors.internal_server_error import InternalServerError from ...errors.not_found_error import NotFoundError @@ -28,12 +30,14 @@ class WebhooksClient: def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper - def list(self, site_id: str) -> typing.List[Webhook]: + def list(self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> typing.List[Webhook]: """ List all App-created Webhooks registered for a given site Parameters: - site_id: str. Unique identifier for a Site + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -41,14 +45,28 @@ def list(self, site_id: str) -> typing.List[Webhook]: access_token="YOUR_ACCESS_TOKEN", ) client.webhooks.list( - site_id="site-id", + site_id="site_id", ) """ _response = self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/webhooks"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/webhooks" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(typing.List[Webhook], _response.json()) # type: ignore @@ -75,6 +93,7 @@ def create( trigger_type: TriggerType, url: str, filter: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> Webhook: """ Create a new Webhook, to be notified when Webflow resources change. Limit of 75 registrations per `triggerType`, per site. @@ -88,7 +107,9 @@ def create( - filter: typing.Optional[typing.Dict[str, typing.Any]]. Filter for selecting which events you want Webhooks to be triggered for. ** Only available for `form_submission` trigger types. ** - --- + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- from webflow import TriggerType from webflow.client import Webflow @@ -96,7 +117,7 @@ def create( access_token="YOUR_ACCESS_TOKEN", ) client.webhooks.create( - site_id="site-id", + site_id="site_id", trigger_type=TriggerType.FORM_SUBMISSION, url="https://api.mydomain.com/webhook", ) @@ -106,10 +127,29 @@ def create( _request["filter"] = filter _response = self._client_wrapper.httpx_client.request( "POST", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/webhooks"), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/webhooks" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Webhook, _response.json()) # type: ignore @@ -129,12 +169,14 @@ def create( raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def get(self, webhook_id: str) -> Webhook: + def get(self, webhook_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Webhook: """ Get a specific Webhook instance Parameters: - webhook_id: str. Unique identifier for a Webhook + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -142,14 +184,26 @@ def get(self, webhook_id: str) -> Webhook: access_token="YOUR_ACCESS_TOKEN", ) client.webhooks.get( - webhook_id="webhook-id", + webhook_id="webhook_id", ) """ _response = self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"webhooks/{webhook_id}"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"webhooks/{jsonable_encoder(webhook_id)}"), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Webhook, _response.json()) # type: ignore @@ -169,12 +223,14 @@ def get(self, webhook_id: str) -> Webhook: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - def delete(self, webhook_id: str) -> None: + def delete(self, webhook_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> None: """ Remove a Webhook Parameters: - webhook_id: str. Unique identifier for a Webhook + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import Webflow @@ -182,14 +238,26 @@ def delete(self, webhook_id: str) -> None: access_token="YOUR_ACCESS_TOKEN", ) client.webhooks.delete( - webhook_id="webhook-id", + webhook_id="webhook_id", ) """ _response = self._client_wrapper.httpx_client.request( "DELETE", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"webhooks/{webhook_id}"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"webhooks/{jsonable_encoder(webhook_id)}"), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return @@ -214,12 +282,16 @@ class AsyncWebhooksClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): self._client_wrapper = client_wrapper - async def list(self, site_id: str) -> typing.List[Webhook]: + async def list( + self, site_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> typing.List[Webhook]: """ List all App-created Webhooks registered for a given site Parameters: - site_id: str. Unique identifier for a Site + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -227,14 +299,28 @@ async def list(self, site_id: str) -> typing.List[Webhook]: access_token="YOUR_ACCESS_TOKEN", ) await client.webhooks.list( - site_id="site-id", + site_id="site_id", ) """ _response = await self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/webhooks"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/webhooks" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(typing.List[Webhook], _response.json()) # type: ignore @@ -261,6 +347,7 @@ async def create( trigger_type: TriggerType, url: str, filter: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> Webhook: """ Create a new Webhook, to be notified when Webflow resources change. Limit of 75 registrations per `triggerType`, per site. @@ -274,7 +361,9 @@ async def create( - filter: typing.Optional[typing.Dict[str, typing.Any]]. Filter for selecting which events you want Webhooks to be triggered for. ** Only available for `form_submission` trigger types. ** - --- + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. + --- from webflow import TriggerType from webflow.client import AsyncWebflow @@ -282,7 +371,7 @@ async def create( access_token="YOUR_ACCESS_TOKEN", ) await client.webhooks.create( - site_id="site-id", + site_id="site_id", trigger_type=TriggerType.FORM_SUBMISSION, url="https://api.mydomain.com/webhook", ) @@ -292,10 +381,29 @@ async def create( _request["filter"] = filter _response = await self._client_wrapper.httpx_client.request( "POST", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"sites/{site_id}/webhooks"), - json=jsonable_encoder(_request), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin( + f"{self._client_wrapper.get_base_url()}/", f"sites/{jsonable_encoder(site_id)}/webhooks" + ), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + json=jsonable_encoder(_request) + if request_options is None or request_options.get("additional_body_parameters") is None + else { + **jsonable_encoder(_request), + **(jsonable_encoder(remove_none_from_dict(request_options.get("additional_body_parameters", {})))), + }, + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Webhook, _response.json()) # type: ignore @@ -315,12 +423,14 @@ async def create( raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def get(self, webhook_id: str) -> Webhook: + async def get(self, webhook_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Webhook: """ Get a specific Webhook instance Parameters: - webhook_id: str. Unique identifier for a Webhook + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -328,14 +438,26 @@ async def get(self, webhook_id: str) -> Webhook: access_token="YOUR_ACCESS_TOKEN", ) await client.webhooks.get( - webhook_id="webhook-id", + webhook_id="webhook_id", ) """ _response = await self._client_wrapper.httpx_client.request( "GET", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"webhooks/{webhook_id}"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"webhooks/{jsonable_encoder(webhook_id)}"), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return pydantic.parse_obj_as(Webhook, _response.json()) # type: ignore @@ -355,12 +477,14 @@ async def get(self, webhook_id: str) -> Webhook: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) - async def delete(self, webhook_id: str) -> None: + async def delete(self, webhook_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> None: """ Remove a Webhook Parameters: - webhook_id: str. Unique identifier for a Webhook + + - request_options: typing.Optional[RequestOptions]. Request-specific configuration. --- from webflow.client import AsyncWebflow @@ -368,14 +492,26 @@ async def delete(self, webhook_id: str) -> None: access_token="YOUR_ACCESS_TOKEN", ) await client.webhooks.delete( - webhook_id="webhook-id", + webhook_id="webhook_id", ) """ _response = await self._client_wrapper.httpx_client.request( "DELETE", - urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"webhooks/{webhook_id}"), - headers=self._client_wrapper.get_headers(), - timeout=60, + urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"webhooks/{jsonable_encoder(webhook_id)}"), + params=jsonable_encoder( + request_options.get("additional_query_parameters") if request_options is not None else None + ), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self._client_wrapper.get_headers(), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), + timeout=request_options.get("timeout_in_seconds") + if request_options is not None and request_options.get("timeout_in_seconds") is not None + else 60, ) if 200 <= _response.status_code < 300: return diff --git a/src/webflow/types/__init__.py b/src/webflow/types/__init__.py index 7282f1c..03cf0fd 100644 --- a/src/webflow/types/__init__.py +++ b/src/webflow/types/__init__.py @@ -25,6 +25,7 @@ from .custom_code_block import CustomCodeBlock from .custom_code_block_type import CustomCodeBlockType from .custom_code_response import CustomCodeResponse +from .dom import Dom from .domain import Domain from .duplicate_user_email import DuplicateUserEmail from .ecommerce_settings import EcommerceSettings @@ -43,12 +44,17 @@ from .form_submission_list import FormSubmissionList from .form_submission_trigger import FormSubmissionTrigger from .form_submission_trigger_payload import FormSubmissionTriggerPayload +from .image_node import ImageNode from .invalid_domain import InvalidDomain +from .invalid_scopes import InvalidScopes from .inventory_item import InventoryItem from .inventory_item_inventory_type import InventoryItemInventoryType from .list_custom_code_blocks import ListCustomCodeBlocks from .missing_scopes import MissingScopes from .no_domains import NoDomains +from .node import Node +from .node_type import NodeType +from .not_enterprise_plan_site import NotEnterprisePlanSite from .oauth_scope import OauthScope from .order import Order from .order_address import OrderAddress @@ -84,6 +90,8 @@ from .product_and_sk_us import ProductAndSkUs from .product_and_sk_us_list import ProductAndSkUsList from .product_field_data import ProductFieldData +from .product_field_data_ec_product_type import ProductFieldDataEcProductType +from .product_field_data_tax_category import ProductFieldDataTaxCategory from .publish_status import PublishStatus from .published_items import PublishedItems from .published_site import PublishedSite @@ -95,12 +103,17 @@ from .site import Site from .site_activity_log_item import SiteActivityLogItem from .site_activity_log_item_resource_operation import SiteActivityLogItemResourceOperation +from .site_activity_log_item_user import SiteActivityLogItemUser from .site_activity_log_response import SiteActivityLogResponse from .site_publish import SitePublish from .site_publish_payload import SitePublishPayload from .sites import Sites from .sku import Sku from .sku_field_data import SkuFieldData +from .sku_field_data_compare_at_price import SkuFieldDataCompareAtPrice +from .sku_field_data_ec_sku_billing_method import SkuFieldDataEcSkuBillingMethod +from .sku_field_data_ec_sku_subscription_plan import SkuFieldDataEcSkuSubscriptionPlan +from .sku_field_data_ec_sku_subscription_plan_interval import SkuFieldDataEcSkuSubscriptionPlanInterval from .sku_field_data_price import SkuFieldDataPrice from .sku_property_list import SkuPropertyList from .sku_property_list_enum_item import SkuPropertyListEnumItem @@ -109,6 +122,7 @@ from .stripe_card_brand import StripeCardBrand from .stripe_card_expires import StripeCardExpires from .stripe_details import StripeDetails +from .text_node import TextNode from .trigger_type import TriggerType from .user import User from .user_access_groups_item import UserAccessGroupsItem @@ -150,6 +164,7 @@ "CustomCodeBlock", "CustomCodeBlockType", "CustomCodeResponse", + "Dom", "Domain", "DuplicateUserEmail", "EcommerceSettings", @@ -168,12 +183,17 @@ "FormSubmissionList", "FormSubmissionTrigger", "FormSubmissionTriggerPayload", + "ImageNode", "InvalidDomain", + "InvalidScopes", "InventoryItem", "InventoryItemInventoryType", "ListCustomCodeBlocks", "MissingScopes", "NoDomains", + "Node", + "NodeType", + "NotEnterprisePlanSite", "OauthScope", "Order", "OrderAddress", @@ -209,6 +229,8 @@ "ProductAndSkUs", "ProductAndSkUsList", "ProductFieldData", + "ProductFieldDataEcProductType", + "ProductFieldDataTaxCategory", "PublishStatus", "PublishedItems", "PublishedSite", @@ -220,12 +242,17 @@ "Site", "SiteActivityLogItem", "SiteActivityLogItemResourceOperation", + "SiteActivityLogItemUser", "SiteActivityLogResponse", "SitePublish", "SitePublishPayload", "Sites", "Sku", "SkuFieldData", + "SkuFieldDataCompareAtPrice", + "SkuFieldDataEcSkuBillingMethod", + "SkuFieldDataEcSkuSubscriptionPlan", + "SkuFieldDataEcSkuSubscriptionPlanInterval", "SkuFieldDataPrice", "SkuPropertyList", "SkuPropertyListEnumItem", @@ -234,6 +261,7 @@ "StripeCardBrand", "StripeCardExpires", "StripeDetails", + "TextNode", "TriggerType", "User", "UserAccessGroupsItem", diff --git a/src/webflow/types/access_group.py b/src/webflow/types/access_group.py index b016511..f76637e 100644 --- a/src/webflow/types/access_group.py +++ b/src/webflow/types/access_group.py @@ -12,17 +12,21 @@ class AccessGroup(pydantic.BaseModel): - id: typing.Optional[str] = pydantic.Field(alias="_id", description="Unique identifier for the Access Group") - name: typing.Optional[str] = pydantic.Field(description="Name of the the Access Group") + id: typing.Optional[str] = pydantic.Field( + alias="_id", default=None, description="Unique identifier for the Access Group" + ) + name: typing.Optional[str] = pydantic.Field(default=None, description="Name of the the Access Group") short_id: typing.Optional[str] = pydantic.Field( alias="shortId", + default=None, description="Shortened unique identifier based on name, optimized for its use in the user’s JWT", ) slug: typing.Optional[str] = pydantic.Field( - description="Shortened unique identifier based on name, optimized for human readability and public API use" + default=None, + description="Shortened unique identifier based on name, optimized for human readability and public API use", ) created_on: typing.Optional[dt.datetime] = pydantic.Field( - alias="createdOn", description="The date the Access Group was created" + alias="createdOn", default=None, description="The date the Access Group was created" ) def json(self, **kwargs: typing.Any) -> str: diff --git a/src/webflow/types/access_group_list.py b/src/webflow/types/access_group_list.py index e40da06..aa36c97 100644 --- a/src/webflow/types/access_group_list.py +++ b/src/webflow/types/access_group_list.py @@ -17,12 +17,14 @@ class AccessGroupList(pydantic.BaseModel): The list access groups results """ - count: typing.Optional[float] = pydantic.Field(description="Number of access groups returned") - limit: typing.Optional[float] = pydantic.Field(description="The limit specified in the request") - offset: typing.Optional[float] = pydantic.Field(description="The offset specified for pagination") - total: typing.Optional[float] = pydantic.Field(description="Total number of access groups in the collection") + count: typing.Optional[float] = pydantic.Field(default=None, description="Number of access groups returned") + limit: typing.Optional[float] = pydantic.Field(default=None, description="The limit specified in the request") + offset: typing.Optional[float] = pydantic.Field(default=None, description="The offset specified for pagination") + total: typing.Optional[float] = pydantic.Field( + default=None, description="Total number of access groups in the collection" + ) access_groups: typing.Optional[typing.List[AccessGroup]] = pydantic.Field( - alias="accessGroups", description="List of Site Access Groups" + alias="accessGroups", default=None, description="List of Site Access Groups" ) def json(self, **kwargs: typing.Any) -> str: diff --git a/src/webflow/types/application.py b/src/webflow/types/application.py index 9a5b73d..e056b65 100644 --- a/src/webflow/types/application.py +++ b/src/webflow/types/application.py @@ -12,11 +12,15 @@ class Application(pydantic.BaseModel): - id: typing.Optional[str] = pydantic.Field(description="Unique identifier for the Application") - description: typing.Optional[str] = pydantic.Field(description="Application description provided by the developer") - homepage: typing.Optional[str] = pydantic.Field(description="Application homepage URL provided by the developer") + id: typing.Optional[str] = pydantic.Field(default=None, description="Unique identifier for the Application") + description: typing.Optional[str] = pydantic.Field( + default=None, description="Application description provided by the developer" + ) + homepage: typing.Optional[str] = pydantic.Field( + default=None, description="Application homepage URL provided by the developer" + ) display_name: typing.Optional[str] = pydantic.Field( - alias="displayName", description="Application name provided by the developer" + alias="displayName", default=None, description="Application name provided by the developer" ) def json(self, **kwargs: typing.Any) -> str: diff --git a/src/webflow/types/asset.py b/src/webflow/types/asset.py index b3eaf06..0d80162 100644 --- a/src/webflow/types/asset.py +++ b/src/webflow/types/asset.py @@ -13,24 +13,28 @@ class Asset(pydantic.BaseModel): - id: typing.Optional[str] = pydantic.Field(description="Unique identifier for this asset") - content_type: typing.Optional[str] = pydantic.Field(alias="contentType", description="File format type") - size: typing.Optional[int] = pydantic.Field(description="size in bytes") + id: typing.Optional[str] = pydantic.Field(default=None, description="Unique identifier for this asset") + content_type: typing.Optional[str] = pydantic.Field( + alias="contentType", default=None, description="File format type" + ) + size: typing.Optional[int] = pydantic.Field(default=None, description="size in bytes") site_id: typing.Optional[str] = pydantic.Field( - alias="siteId", description="Unique identifier for the site that hosts this asset" + alias="siteId", default=None, description="Unique identifier for the site that hosts this asset" ) - hosted_url: typing.Optional[str] = pydantic.Field(alias="hostedUrl", description="Link to the asset") + hosted_url: typing.Optional[str] = pydantic.Field(alias="hostedUrl", default=None, description="Link to the asset") original_file_name: typing.Optional[str] = pydantic.Field( - alias="originalFileName", description="Original file name at the time of upload" + alias="originalFileName", default=None, description="Original file name at the time of upload" + ) + display_name: typing.Optional[str] = pydantic.Field( + alias="displayName", default=None, description="Display name of the asset" ) - display_name: typing.Optional[str] = pydantic.Field(alias="displayName", description="Display name of the asset") last_updated: typing.Optional[dt.datetime] = pydantic.Field( - alias="lastUpdated", description="Date the asset metadata was last updated" + alias="lastUpdated", default=None, description="Date the asset metadata was last updated" ) created_on: typing.Optional[dt.datetime] = pydantic.Field( - alias="createdOn", description="Date the asset metadata was created" + alias="createdOn", default=None, description="Date the asset metadata was created" ) - variants: typing.Optional[typing.List[AssetVariant]] + variants: typing.Optional[typing.List[AssetVariant]] = None def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/asset_folder.py b/src/webflow/types/asset_folder.py index 739abe0..130b755 100644 --- a/src/webflow/types/asset_folder.py +++ b/src/webflow/types/asset_folder.py @@ -12,22 +12,28 @@ class AssetFolder(pydantic.BaseModel): + """ + Asset Folder details + """ + display_name: typing.Optional[str] = pydantic.Field( - alias="displayName", description="User visible name for the Asset Folder" + alias="displayName", default=None, description="User visible name for the Asset Folder" ) - id: typing.Optional[str] = pydantic.Field(description="Unique identifier for the Asset Folder") + id: typing.Optional[str] = pydantic.Field(default=None, description="Unique identifier for the Asset Folder") parent_folder: typing.Optional[str] = pydantic.Field( - alias="parentFolder", description="Pointer to parent Asset Folder (or null if root)" + alias="parentFolder", default=None, description="Pointer to parent Asset Folder (or null if root)" + ) + assets: typing.Optional[typing.List[str]] = pydantic.Field( + default=None, description="Array of Asset instances in the folder" ) - assets: typing.Optional[typing.List[str]] = pydantic.Field(description="Array of Asset instances in the folder") site_id: typing.Optional[str] = pydantic.Field( - alias="siteId", description="The unique id of the site the Asset Folder belongs to" + alias="siteId", default=None, description="The unique id of the site the Asset Folder belongs to" ) created_on: typing.Optional[dt.datetime] = pydantic.Field( - alias="createdOn", description="Date that the Asset Folder was created on" + alias="createdOn", default=None, description="Date that the Asset Folder was created on" ) last_updated: typing.Optional[dt.datetime] = pydantic.Field( - alias="lastUpdated", description="Date that the Asset Folder was last updated on" + alias="lastUpdated", default=None, description="Date that the Asset Folder was last updated on" ) def json(self, **kwargs: typing.Any) -> str: diff --git a/src/webflow/types/asset_folder_list.py b/src/webflow/types/asset_folder_list.py index 244fba0..89e533d 100644 --- a/src/webflow/types/asset_folder_list.py +++ b/src/webflow/types/asset_folder_list.py @@ -18,8 +18,10 @@ class AssetFolderList(pydantic.BaseModel): The Asset Folders object """ - pagination: typing.Optional[Pagination] - pages: typing.Optional[typing.List[AssetFolder]] + asset_folders: typing.Optional[typing.List[AssetFolder]] = pydantic.Field( + alias="assetFolders", default=None, description="A list of Asset folders" + ) + pagination: typing.Optional[Pagination] = None def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} @@ -32,4 +34,5 @@ def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]: class Config: frozen = True smart_union = True + allow_population_by_field_name = True json_encoders = {dt.datetime: serialize_datetime} diff --git a/src/webflow/types/asset_upload.py b/src/webflow/types/asset_upload.py index 336d112..299f032 100644 --- a/src/webflow/types/asset_upload.py +++ b/src/webflow/types/asset_upload.py @@ -14,25 +14,28 @@ class AssetUpload(pydantic.BaseModel): upload_details: typing.Optional[AssetUploadUploadDetails] = pydantic.Field( - alias="uploadDetails", description="Metadata for uploading the asset binary" + alias="uploadDetails", default=None, description="Metadata for uploading the asset binary" ) - id: typing.Optional[str] - content_type: typing.Optional[str] = pydantic.Field(alias="contentType") + id: typing.Optional[str] = None + content_type: typing.Optional[str] = pydantic.Field(alias="contentType", default=None) parent_folder: typing.Optional[str] = pydantic.Field( - alias="parentFolder", description="Parent folder for the asset" + alias="parentFolder", default=None, description="Parent folder for the asset" ) - hosted_url: typing.Optional[str] = pydantic.Field(alias="hostedUrl", description="Represents the link to the asset") - upload_url: typing.Optional[str] = pydantic.Field(alias="uploadUrl") - asset_url: typing.Optional[str] = pydantic.Field(alias="assetUrl", description="S3 link to the asset") + hosted_url: typing.Optional[str] = pydantic.Field( + alias="hostedUrl", default=None, description="Represents the link to the asset" + ) + upload_url: typing.Optional[str] = pydantic.Field(alias="uploadUrl", default=None) + asset_url: typing.Optional[str] = pydantic.Field(alias="assetUrl", default=None, description="S3 link to the asset") original_file_name: typing.Optional[str] = pydantic.Field( alias="originalFileName", + default=None, description="Original file name when uploaded. If not specified at time of upload, it may be extracted from the raw file name", ) last_updated: typing.Optional[dt.datetime] = pydantic.Field( - alias="lastUpdated", description="Date the asset metadata was last updated" + alias="lastUpdated", default=None, description="Date the asset metadata was last updated" ) created_on: typing.Optional[dt.datetime] = pydantic.Field( - alias="createdOn", description="Date the asset metadata was created" + alias="createdOn", default=None, description="Date the asset metadata was created" ) def json(self, **kwargs: typing.Any) -> str: diff --git a/src/webflow/types/asset_upload_upload_details.py b/src/webflow/types/asset_upload_upload_details.py index 7fc5630..244ad84 100644 --- a/src/webflow/types/asset_upload_upload_details.py +++ b/src/webflow/types/asset_upload_upload_details.py @@ -16,21 +16,22 @@ class AssetUploadUploadDetails(pydantic.BaseModel): Metadata for uploading the asset binary """ - acl: typing.Optional[str] - bucket: typing.Optional[str] - key: typing.Optional[str] - policy: typing.Optional[str] = pydantic.Field(alias="Policy") - x_amz_algorithm: typing.Optional[str] = pydantic.Field(alias="X-Amz-Algorithm") - x_amz_credential: typing.Optional[str] = pydantic.Field(alias="X-Amz-Credential") - x_amz_date: typing.Optional[str] = pydantic.Field(alias="X-Amz-Date") + acl: typing.Optional[str] = None + bucket: typing.Optional[str] = None + key: typing.Optional[str] = None + policy: typing.Optional[str] = pydantic.Field(alias="Policy", default=None) + x_amz_algorithm: typing.Optional[str] = pydantic.Field(alias="X-Amz-Algorithm", default=None) + x_amz_credential: typing.Optional[str] = pydantic.Field(alias="X-Amz-Credential", default=None) + x_amz_date: typing.Optional[str] = pydantic.Field(alias="X-Amz-Date", default=None) x_amz_security_token: typing.Optional[str] = pydantic.Field( alias="X-Amz-Security-Token", + default=None, description="(optional) Temporary security token obtained when authenticated through AWS STS", ) - x_amz_signature: typing.Optional[str] = pydantic.Field(alias="X-Amz-Signature") - success_action_status: typing.Optional[str] - content_type: typing.Optional[str] = pydantic.Field(alias="content-type") - cache_control: typing.Optional[str] = pydantic.Field(alias="Cache-Control") + x_amz_signature: typing.Optional[str] = pydantic.Field(alias="X-Amz-Signature", default=None) + success_action_status: typing.Optional[str] = None + content_type: typing.Optional[str] = pydantic.Field(alias="content-type", default=None) + cache_control: typing.Optional[str] = pydantic.Field(alias="Cache-Control", default=None) def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/asset_variant.py b/src/webflow/types/asset_variant.py index 8fc6a3a..00af16a 100644 --- a/src/webflow/types/asset_variant.py +++ b/src/webflow/types/asset_variant.py @@ -12,14 +12,16 @@ class AssetVariant(pydantic.BaseModel): - hosted_url: typing.Optional[str] = pydantic.Field(alias="hostedUrl") - original_file_name: typing.Optional[str] = pydantic.Field(alias="originalFileName") - display_name: typing.Optional[str] = pydantic.Field(alias="displayName") - format: typing.Optional[str] - width: typing.Optional[int] = pydantic.Field(description="Width in pixels") - height: typing.Optional[int] = pydantic.Field(description="Height in pixels") - quality: typing.Optional[int] = pydantic.Field(description="Value between 0 and 100 representing the image quality") - error: typing.Optional[str] = pydantic.Field(description="Any associated validation errors") + hosted_url: typing.Optional[str] = pydantic.Field(alias="hostedUrl", default=None) + original_file_name: typing.Optional[str] = pydantic.Field(alias="originalFileName", default=None) + display_name: typing.Optional[str] = pydantic.Field(alias="displayName", default=None) + format: typing.Optional[str] = None + width: typing.Optional[int] = pydantic.Field(default=None, description="Width in pixels") + height: typing.Optional[int] = pydantic.Field(default=None, description="Height in pixels") + quality: typing.Optional[int] = pydantic.Field( + default=None, description="Value between 0 and 100 representing the image quality" + ) + error: typing.Optional[str] = pydantic.Field(default=None, description="Any associated validation errors") def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/assets.py b/src/webflow/types/assets.py index 9177f90..2b28808 100644 --- a/src/webflow/types/assets.py +++ b/src/webflow/types/assets.py @@ -13,7 +13,7 @@ class Assets(pydantic.BaseModel): - assets: typing.Optional[typing.List[Asset]] + assets: typing.Optional[typing.List[Asset]] = None def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/authorization.py b/src/webflow/types/authorization.py index b2898ec..c896ac6 100644 --- a/src/webflow/types/authorization.py +++ b/src/webflow/types/authorization.py @@ -14,8 +14,10 @@ class Authorization(pydantic.BaseModel): - authorization: typing.Optional[AuthorizationAuthorization] = pydantic.Field(description="The Authorization object") - application: typing.Optional[Application] + authorization: typing.Optional[AuthorizationAuthorization] = pydantic.Field( + default=None, description="The Authorization object" + ) + application: typing.Optional[Application] = None def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/authorization_authorization.py b/src/webflow/types/authorization_authorization.py index d96ec6e..cb2780e 100644 --- a/src/webflow/types/authorization_authorization.py +++ b/src/webflow/types/authorization_authorization.py @@ -17,23 +17,25 @@ class AuthorizationAuthorization(pydantic.BaseModel): The Authorization object """ - id: typing.Optional[str] = pydantic.Field(description="The unique id of the Authorization instance") + id: typing.Optional[str] = pydantic.Field(default=None, description="The unique id of the Authorization instance") created_on: typing.Optional[dt.datetime] = pydantic.Field( - alias="createdOn", description="The date the Authorization was created" + alias="createdOn", default=None, description="The date the Authorization was created" ) last_used: typing.Optional[dt.datetime] = pydantic.Field( - alias="lastUsed", description="The date the Authorization was last used" + alias="lastUsed", default=None, description="The date the Authorization was last used" ) grant_type: typing.Optional[str] = pydantic.Field( - alias="grantType", description="The grant type of the Authorization" + alias="grantType", default=None, description="The grant type of the Authorization" ) rate_limit: typing.Optional[int] = pydantic.Field( - alias="rateLimit", description="The default rate limit for the Authorization (requests/min)" + alias="rateLimit", default=None, description="The default rate limit for the Authorization (requests/min)" ) scope: typing.Optional[str] = pydantic.Field( - description="Comma separted list of OAuth scopes corresponding to the Authorization" + default=None, description="Comma separted list of OAuth scopes corresponding to the Authorization" + ) + authorized_to: typing.Optional[AuthorizationAuthorizationAuthorizedTo] = pydantic.Field( + alias="authorizedTo", default=None ) - authorized_to: typing.Optional[AuthorizationAuthorizationAuthorizedTo] = pydantic.Field(alias="authorizedTo") def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/authorization_authorization_authorized_to.py b/src/webflow/types/authorization_authorization_authorized_to.py index bf0df43..e80f490 100644 --- a/src/webflow/types/authorization_authorization_authorized_to.py +++ b/src/webflow/types/authorization_authorization_authorized_to.py @@ -13,13 +13,13 @@ class AuthorizationAuthorizationAuthorizedTo(pydantic.BaseModel): site_ids: typing.Optional[typing.List[typing.Any]] = pydantic.Field( - alias="siteIds", description="Array of Sites this app is authorized to" + alias="siteIds", default=None, description="Array of Sites this app is authorized to" ) workspace_ids: typing.Optional[typing.List[typing.Any]] = pydantic.Field( - alias="workspaceIds", description="Array of Workspaces this app is authorized to" + alias="workspaceIds", default=None, description="Array of Workspaces this app is authorized to" ) user_ids: typing.Optional[typing.List[typing.Any]] = pydantic.Field( - alias="userIds", description="Array of Users this app is authorized to" + alias="userIds", default=None, description="Array of Users this app is authorized to" ) def json(self, **kwargs: typing.Any) -> str: diff --git a/src/webflow/types/authorized_user.py b/src/webflow/types/authorized_user.py index 7f64eae..8f754d3 100644 --- a/src/webflow/types/authorized_user.py +++ b/src/webflow/types/authorized_user.py @@ -12,10 +12,12 @@ class AuthorizedUser(pydantic.BaseModel): - id: typing.Optional[str] = pydantic.Field(description="The unique id of the user") - email: typing.Optional[str] = pydantic.Field(description="The user's email address") - first_name: typing.Optional[str] = pydantic.Field(alias="firstName", description="The user's first name") - last_name: typing.Optional[str] = pydantic.Field(alias="lastName", description="The user's last name") + id: typing.Optional[str] = pydantic.Field(default=None, description="The unique id of the user") + email: typing.Optional[str] = pydantic.Field(default=None, description="The user's email address") + first_name: typing.Optional[str] = pydantic.Field( + alias="firstName", default=None, description="The user's first name" + ) + last_name: typing.Optional[str] = pydantic.Field(alias="lastName", default=None, description="The user's last name") def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/collection.py b/src/webflow/types/collection.py index 7afc3b5..6887a61 100644 --- a/src/webflow/types/collection.py +++ b/src/webflow/types/collection.py @@ -17,17 +17,20 @@ class Collection(pydantic.BaseModel): """ id: str = pydantic.Field(description="Unique identifier for a Collection") - display_name: typing.Optional[str] = pydantic.Field(alias="displayName", description="Name given to the Collection") + display_name: typing.Optional[str] = pydantic.Field( + alias="displayName", default=None, description="Name given to the Collection" + ) singular_name: typing.Optional[str] = pydantic.Field( alias="singularName", + default=None, description="The name of one Item in Collection (e.g. ”Blog Post” if the Collection is called “Blog Posts”)", ) - slug: typing.Optional[str] = pydantic.Field(description="Slug of Collection in Site URL structure") + slug: typing.Optional[str] = pydantic.Field(default=None, description="Slug of Collection in Site URL structure") created_on: typing.Optional[dt.datetime] = pydantic.Field( - alias="createdOn", description="The date the collection was created" + alias="createdOn", default=None, description="The date the collection was created" ) last_updated: typing.Optional[dt.datetime] = pydantic.Field( - alias="lastUpdated", description="The date the collection was last updated" + alias="lastUpdated", default=None, description="The date the collection was last updated" ) fields: typing.Dict[str, typing.Any] = pydantic.Field(description="The list of fields in the Collection") diff --git a/src/webflow/types/collection_item.py b/src/webflow/types/collection_item.py index e2e4c07..82a0629 100644 --- a/src/webflow/types/collection_item.py +++ b/src/webflow/types/collection_item.py @@ -18,20 +18,25 @@ class CollectionItem(pydantic.BaseModel): """ id: str = pydantic.Field(description="Unique identifier for the Item") + cms_locale_id: typing.Optional[str] = pydantic.Field( + alias="cmsLocaleId", default=None, description="Identifier for the locale of the CMS item" + ) last_published: typing.Optional[str] = pydantic.Field( - alias="lastPublished", description="The date the item was last published" + alias="lastPublished", default=None, description="The date the item was last published" ) last_updated: typing.Optional[str] = pydantic.Field( - alias="lastUpdated", description="The date the item was last updated" + alias="lastUpdated", default=None, description="The date the item was last updated" + ) + created_on: typing.Optional[str] = pydantic.Field( + alias="createdOn", default=None, description="The date the item was created" ) - created_on: typing.Optional[str] = pydantic.Field(alias="createdOn", description="The date the item was created") is_archived: typing.Optional[bool] = pydantic.Field( - alias="isArchived", description="Boolean determining if the Item is set to archived" + alias="isArchived", default=None, description="Boolean determining if the Item is set to archived" ) is_draft: typing.Optional[bool] = pydantic.Field( - alias="isDraft", description="Boolean determining if the Item is set to draft" + alias="isDraft", default=None, description="Boolean determining if the Item is set to draft" ) - field_data: typing.Optional[CollectionItemFieldData] = pydantic.Field(alias="fieldData") + field_data: typing.Optional[CollectionItemFieldData] = pydantic.Field(alias="fieldData", default=None) def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/collection_item_field_data.py b/src/webflow/types/collection_item_field_data.py index 8f62997..ba2c2fc 100644 --- a/src/webflow/types/collection_item_field_data.py +++ b/src/webflow/types/collection_item_field_data.py @@ -12,9 +12,10 @@ class CollectionItemFieldData(pydantic.BaseModel): - name: typing.Optional[str] = pydantic.Field(description="Name of the Item") + name: typing.Optional[str] = pydantic.Field(default=None, description="Name of the Item") slug: typing.Optional[str] = pydantic.Field( - description="URL structure of the Item in your site. Note: Updates to an item slug will break all links referencing the old slug." + default=None, + description="URL structure of the Item in your site. Note: Updates to an item slug will break all links referencing the old slug.", ) def json(self, **kwargs: typing.Any) -> str: diff --git a/src/webflow/types/collection_item_list.py b/src/webflow/types/collection_item_list.py index 8428e9b..11f519c 100644 --- a/src/webflow/types/collection_item_list.py +++ b/src/webflow/types/collection_item_list.py @@ -19,9 +19,9 @@ class CollectionItemList(pydantic.BaseModel): """ items: typing.Optional[typing.List[CollectionItem]] = pydantic.Field( - description="List of Items within the collection" + default=None, description="List of Items within the collection" ) - pagination: typing.Optional[CollectionItemListPagination] + pagination: typing.Optional[CollectionItemListPagination] = None def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/collection_item_list_pagination.py b/src/webflow/types/collection_item_list_pagination.py index bc91999..ffb4c77 100644 --- a/src/webflow/types/collection_item_list_pagination.py +++ b/src/webflow/types/collection_item_list_pagination.py @@ -12,9 +12,9 @@ class CollectionItemListPagination(pydantic.BaseModel): - limit: typing.Optional[float] = pydantic.Field(description="The limit specified in the request") - offset: typing.Optional[float] = pydantic.Field(description="The offset specified for pagination") - total: typing.Optional[float] = pydantic.Field(description="Total number of items in the collection") + limit: typing.Optional[float] = pydantic.Field(default=None, description="The limit specified in the request") + offset: typing.Optional[float] = pydantic.Field(default=None, description="The offset specified for pagination") + total: typing.Optional[float] = pydantic.Field(default=None, description="Total number of items in the collection") def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/collection_item_removed.py b/src/webflow/types/collection_item_removed.py index a28b357..4056f46 100644 --- a/src/webflow/types/collection_item_removed.py +++ b/src/webflow/types/collection_item_removed.py @@ -12,9 +12,9 @@ class CollectionItemRemoved(pydantic.BaseModel): - deleted: typing.Optional[float] = pydantic.Field(description="The number of items deleted") + deleted: typing.Optional[float] = pydantic.Field(default=None, description="The number of items deleted") item_id: typing.Optional[str] = pydantic.Field( - alias="itemId", description="The id of the collection item that was deleted" + alias="itemId", default=None, description="The id of the collection item that was deleted" ) def json(self, **kwargs: typing.Any) -> str: diff --git a/src/webflow/types/collection_list.py b/src/webflow/types/collection_list.py index 24aaf20..683b028 100644 --- a/src/webflow/types/collection_list.py +++ b/src/webflow/types/collection_list.py @@ -14,7 +14,7 @@ class CollectionList(pydantic.BaseModel): collections: typing.Optional[typing.List[CollectionListArrayItem]] = pydantic.Field( - description="An array of Collections" + default=None, description="An array of Collections" ) def json(self, **kwargs: typing.Any) -> str: diff --git a/src/webflow/types/collection_list_array_item.py b/src/webflow/types/collection_list_array_item.py index 9288336..2669222 100644 --- a/src/webflow/types/collection_list_array_item.py +++ b/src/webflow/types/collection_list_array_item.py @@ -17,17 +17,20 @@ class CollectionListArrayItem(pydantic.BaseModel): """ id: str = pydantic.Field(description="Unique identifier for a Collection") - display_name: typing.Optional[str] = pydantic.Field(alias="displayName", description="Name given to the Collection") + display_name: typing.Optional[str] = pydantic.Field( + alias="displayName", default=None, description="Name given to the Collection" + ) singular_name: typing.Optional[str] = pydantic.Field( alias="singularName", + default=None, description="The name of one Item in Collection (e.g. ”Blog Post” if the Collection is called “Blog Posts”)", ) - slug: typing.Optional[str] = pydantic.Field(description="Slug of Collection in Site URL structure") + slug: typing.Optional[str] = pydantic.Field(default=None, description="Slug of Collection in Site URL structure") created_on: typing.Optional[dt.datetime] = pydantic.Field( - alias="createdOn", description="The date the collection was created" + alias="createdOn", default=None, description="The date the collection was created" ) last_updated: typing.Optional[dt.datetime] = pydantic.Field( - alias="lastUpdated", description="The date the collection was last updated" + alias="lastUpdated", default=None, description="The date the collection was last updated" ) def json(self, **kwargs: typing.Any) -> str: diff --git a/src/webflow/types/custom_code_block.py b/src/webflow/types/custom_code_block.py index f150de5..90f9ea2 100644 --- a/src/webflow/types/custom_code_block.py +++ b/src/webflow/types/custom_code_block.py @@ -19,18 +19,20 @@ class CustomCodeBlock(pydantic.BaseModel): """ site_id: typing.Optional[str] = pydantic.Field( - alias="siteId", description="The Site id where the custom code was applied" + alias="siteId", default=None, description="The Site id where the custom code was applied" + ) + page_id: typing.Optional[str] = pydantic.Field( + alias="pageId", default=None, description="The Page id (if applied at Page-level)" ) - page_id: typing.Optional[str] = pydantic.Field(alias="pageId", description="The Page id (if applied at Page-level)") type: typing.Optional[CustomCodeBlockType] = pydantic.Field( - description="Whether the Custom Code script is applied at the Site-level or Page-level" + default=None, description="Whether the Custom Code script is applied at the Site-level or Page-level" ) - scripts: typing.Optional[typing.List[ScriptApply]] + scripts: typing.Optional[typing.List[ScriptApply]] = None created_on: typing.Optional[dt.datetime] = pydantic.Field( - alias="createdOn", description="The date the Block was created" + alias="createdOn", default=None, description="The date the Block was created" ) last_updated: typing.Optional[dt.datetime] = pydantic.Field( - alias="lastUpdated", description="The date the Block was most recently updated" + alias="lastUpdated", default=None, description="The date the Block was most recently updated" ) def json(self, **kwargs: typing.Any) -> str: diff --git a/src/webflow/types/custom_code_response.py b/src/webflow/types/custom_code_response.py index abf57e8..2765ca9 100644 --- a/src/webflow/types/custom_code_response.py +++ b/src/webflow/types/custom_code_response.py @@ -17,29 +17,32 @@ class CustomCodeResponse(pydantic.BaseModel): """ id: typing.Optional[str] = pydantic.Field( - description="Human readable id, derived from the user-specified display name" + default=None, description="Human readable id, derived from the user-specified display name" ) created_on: typing.Optional[str] = pydantic.Field( - alias="createdOn", description="Timestamp when the script version was created" + alias="createdOn", default=None, description="Timestamp when the script version was created" ) last_updated: typing.Optional[str] = pydantic.Field( - alias="lastUpdated", description="Timestamp when the script version was last updated" + alias="lastUpdated", default=None, description="Timestamp when the script version was last updated" ) hosted_location: typing.Optional[str] = pydantic.Field( - alias="hostedLocation", description="URI for an externally hosted script location" + alias="hostedLocation", default=None, description="URI for an externally hosted script location" ) integrity_hash: typing.Optional[str] = pydantic.Field( alias="integrityHash", + default=None, description="Sub-Resource Integrity Hash. Only required for externally hosted scripts (passed via hostedLocation)", ) can_copy: typing.Optional[bool] = pydantic.Field( - alias="canCopy", description="Define whether the script can be copied on site duplication and transfer" + alias="canCopy", + default=None, + description="Define whether the script can be copied on site duplication and transfer", ) version: typing.Optional[str] = pydantic.Field( - description="A Semantic Version (SemVer) string, denoting the version of the script" + default=None, description="A Semantic Version (SemVer) string, denoting the version of the script" ) display_name: typing.Optional[str] = pydantic.Field( - alias="displayName", description="User-facing name for the script" + alias="displayName", default=None, description="User-facing name for the script" ) def json(self, **kwargs: typing.Any) -> str: diff --git a/src/webflow/types/dom.py b/src/webflow/types/dom.py new file mode 100644 index 0000000..c6e1d9a --- /dev/null +++ b/src/webflow/types/dom.py @@ -0,0 +1,37 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +from ..core.datetime_utils import serialize_datetime +from .node import Node +from .pagination import Pagination + +try: + import pydantic.v1 as pydantic # type: ignore +except ImportError: + import pydantic # type: ignore + + +class Dom(pydantic.BaseModel): + """ + The DOM (Document Object Model) schema represents the content structure of a web page. It captures various content nodes, such as text and images, along with their associated attributes. Each node has a unique identifier and can be of different types like text or image. The schema also provides pagination details for scenarios where the content nodes are too many to be fetched in a single request. + """ + + page_id: typing.Optional[str] = pydantic.Field(alias="pageId", default=None, description="Page ID") + nodes: typing.Optional[typing.List[Node]] = None + pagination: typing.Optional[Pagination] = None + + def json(self, **kwargs: typing.Any) -> str: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().json(**kwargs_with_defaults) + + def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().dict(**kwargs_with_defaults) + + class Config: + frozen = True + smart_union = True + allow_population_by_field_name = True + json_encoders = {dt.datetime: serialize_datetime} diff --git a/src/webflow/types/domain.py b/src/webflow/types/domain.py index f3121da..1b69fa5 100644 --- a/src/webflow/types/domain.py +++ b/src/webflow/types/domain.py @@ -13,7 +13,7 @@ class Domain(pydantic.BaseModel): id: str = pydantic.Field(description="Unique identifier for the Domain") - url: typing.Optional[str] = pydantic.Field(description="The registered Domain name") + url: typing.Optional[str] = pydantic.Field(default=None, description="The registered Domain name") def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/duplicate_user_email.py b/src/webflow/types/duplicate_user_email.py index b64f5c7..0591e68 100644 --- a/src/webflow/types/duplicate_user_email.py +++ b/src/webflow/types/duplicate_user_email.py @@ -3,8 +3,6 @@ import datetime as dt import typing -import typing_extensions - from ..core.datetime_utils import serialize_datetime from .error_details_item import ErrorDetailsItem @@ -15,12 +13,14 @@ class DuplicateUserEmail(pydantic.BaseModel): - code: typing.Optional[typing_extensions.Literal["duplicate_user_email"]] - message: typing.Optional[str] = pydantic.Field(description="Error message") + code: typing.Optional[typing.Literal["duplicate_user_email"]] = None + message: typing.Optional[str] = pydantic.Field(default=None, description="Error message") external_reference: typing.Optional[str] = pydantic.Field( - alias="externalReference", description="Link to more information" + alias="externalReference", default=None, description="Link to more information" + ) + details: typing.Optional[typing.List[ErrorDetailsItem]] = pydantic.Field( + default=None, description="Array of errors" ) - details: typing.Optional[typing.List[ErrorDetailsItem]] = pydantic.Field(description="Array of errors") def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/ecommerce_settings.py b/src/webflow/types/ecommerce_settings.py index 0d52a0c..6b6b110 100644 --- a/src/webflow/types/ecommerce_settings.py +++ b/src/webflow/types/ecommerce_settings.py @@ -16,12 +16,14 @@ class EcommerceSettings(pydantic.BaseModel): Ecommerce settings for a Webflow Site """ - site_id: typing.Optional[str] = pydantic.Field(alias="siteId", description="The identifier of the Site") + site_id: typing.Optional[str] = pydantic.Field( + alias="siteId", default=None, description="The identifier of the Site" + ) created_on: typing.Optional[dt.datetime] = pydantic.Field( - alias="createdOn", description="Date that the Site was created on" + alias="createdOn", default=None, description="Date that the Site was created on" ) default_currency: typing.Optional[str] = pydantic.Field( - alias="defaultCurrency", description="The three-letter ISO currency code for the Site" + alias="defaultCurrency", default=None, description="The three-letter ISO currency code for the Site" ) def json(self, **kwargs: typing.Any) -> str: diff --git a/src/webflow/types/error.py b/src/webflow/types/error.py index 69906bb..c8574ab 100644 --- a/src/webflow/types/error.py +++ b/src/webflow/types/error.py @@ -13,12 +13,14 @@ class Error(pydantic.BaseModel): - code: typing.Optional[str] = pydantic.Field(description="Error code") - message: typing.Optional[str] = pydantic.Field(description="Error message") + code: typing.Optional[str] = pydantic.Field(default=None, description="Error code") + message: typing.Optional[str] = pydantic.Field(default=None, description="Error message") external_reference: typing.Optional[str] = pydantic.Field( - alias="externalReference", description="Link to more information" + alias="externalReference", default=None, description="Link to more information" + ) + details: typing.Optional[typing.List[ErrorDetailsItem]] = pydantic.Field( + default=None, description="Array of errors" ) - details: typing.Optional[typing.List[ErrorDetailsItem]] = pydantic.Field(description="Array of errors") def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/field.py b/src/webflow/types/field.py index 357a126..a2f8117 100644 --- a/src/webflow/types/field.py +++ b/src/webflow/types/field.py @@ -22,15 +22,16 @@ class Field(pydantic.BaseModel): alias="isRequired", description="define whether a field is required in a collection" ) is_editable: typing.Optional[bool] = pydantic.Field( - alias="isEditable", description="Define whether the field is editable" + alias="isEditable", default=None, description="Define whether the field is editable" ) type: FieldType = pydantic.Field(description="Choose these appropriate field type for your collection data") slug: typing.Optional[str] = pydantic.Field( - description='Slug of Field in Site URL structure. Slugs should be all lowercase with no spaces. Any spaces will be converted to "-."' + default=None, + description='Slug of Field in Site URL structure. Slugs should be all lowercase with no spaces. Any spaces will be converted to "-."', ) display_name: str = pydantic.Field(alias="displayName", description="The name of a field") help_text: typing.Optional[str] = pydantic.Field( - alias="helpText", description="Additional text to help anyone filling out this field" + alias="helpText", default=None, description="Additional text to help anyone filling out this field" ) def json(self, **kwargs: typing.Any) -> str: diff --git a/src/webflow/types/form.py b/src/webflow/types/form.py index b702930..82a2f69 100644 --- a/src/webflow/types/form.py +++ b/src/webflow/types/form.py @@ -14,33 +14,33 @@ class Form(pydantic.BaseModel): - id: typing.Optional[str] = pydantic.Field(description="The unique id for the Form") + id: typing.Optional[str] = pydantic.Field(default=None, description="The unique id for the Form") display_name: typing.Optional[str] = pydantic.Field( - alias="displayName", description="The Form name displayed on the site" + alias="displayName", default=None, description="The Form name displayed on the site" ) site_id: typing.Optional[str] = pydantic.Field( - alias="siteId", description="The unique id of the Site the Form belongs to" + alias="siteId", default=None, description="The unique id of the Site the Form belongs to" ) site_domain_id: typing.Optional[str] = pydantic.Field( - alias="siteDomainId", description="The unique id corresponding to the site's Domain name" + alias="siteDomainId", default=None, description="The unique id corresponding to the site's Domain name" ) page_id: typing.Optional[str] = pydantic.Field( - alias="pageId", description="The unique id for the Page on which the Form is placed" + alias="pageId", default=None, description="The unique id for the Page on which the Form is placed" ) page_name: typing.Optional[str] = pydantic.Field( - alias="pageName", description="The user-visible name of the Page where the Form is placed" + alias="pageName", default=None, description="The user-visible name of the Page where the Form is placed" ) workspace_id: typing.Optional[str] = pydantic.Field( - alias="workspaceId", description="The unique id of the Workspace the Site belongs to" + alias="workspaceId", default=None, description="The unique id of the Workspace the Site belongs to" ) created_on: typing.Optional[dt.datetime] = pydantic.Field( - alias="createdOn", description="Date that the Form was created on" + alias="createdOn", default=None, description="Date that the Form was created on" ) last_updated: typing.Optional[dt.datetime] = pydantic.Field( - alias="lastUpdated", description="Date that the Form was last updated on" + alias="lastUpdated", default=None, description="Date that the Form was last updated on" ) - fields: typing.Optional[typing.List[FormField]] - response_settings: typing.Optional[FormResponseSettings] = pydantic.Field(alias="responseSettings") + fields: typing.Optional[typing.List[FormField]] = None + response_settings: typing.Optional[FormResponseSettings] = pydantic.Field(alias="responseSettings", default=None) def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/form_field_value.py b/src/webflow/types/form_field_value.py index d17ab1b..dafb390 100644 --- a/src/webflow/types/form_field_value.py +++ b/src/webflow/types/form_field_value.py @@ -14,12 +14,12 @@ class FormFieldValue(pydantic.BaseModel): display_name: typing.Optional[str] = pydantic.Field( - alias="displayName", description="The field name displayed on the site" + alias="displayName", default=None, description="The field name displayed on the site" ) - type: typing.Optional[FormFieldValueType] = pydantic.Field(description="The field type") - placeholder: typing.Optional[str] = pydantic.Field(description="The placeholder text for the field") + type: typing.Optional[FormFieldValueType] = pydantic.Field(default=None, description="The field type") + placeholder: typing.Optional[str] = pydantic.Field(default=None, description="The placeholder text for the field") user_visible: typing.Optional[bool] = pydantic.Field( - alias="userVisible", description="Whether the field is visible to the user" + alias="userVisible", default=None, description="Whether the field is visible to the user" ) def json(self, **kwargs: typing.Any) -> str: diff --git a/src/webflow/types/form_list.py b/src/webflow/types/form_list.py index 8f96dce..c3f50c5 100644 --- a/src/webflow/types/form_list.py +++ b/src/webflow/types/form_list.py @@ -14,8 +14,8 @@ class FormList(pydantic.BaseModel): - forms: typing.Optional[typing.List[Form]] - pagination: typing.Optional[Pagination] + forms: typing.Optional[typing.List[Form]] = None + pagination: typing.Optional[Pagination] = None def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/form_response_settings.py b/src/webflow/types/form_response_settings.py index 64353f1..06c1264 100644 --- a/src/webflow/types/form_response_settings.py +++ b/src/webflow/types/form_response_settings.py @@ -13,16 +13,18 @@ class FormResponseSettings(pydantic.BaseModel): send_email_confirmation: typing.Optional[bool] = pydantic.Field( - alias="sendEmailConfirmation", description="Whether to send an email confirmation to the user" + alias="sendEmailConfirmation", default=None, description="Whether to send an email confirmation to the user" ) redirect_url: typing.Optional[str] = pydantic.Field( - alias="redirectUrl", description="The url or path to redirect the user to after form submission" + alias="redirectUrl", default=None, description="The url or path to redirect the user to after form submission" ) redirect_method: typing.Optional[str] = pydantic.Field( - alias="redirectMethod", description="The HTTP request method to use for the redirectUrl (eg. POST or GET)" + alias="redirectMethod", + default=None, + description="The HTTP request method to use for the redirectUrl (eg. POST or GET)", ) redirect_action: typing.Optional[str] = pydantic.Field( - alias="redirectAction", description="The action to take after form submission" + alias="redirectAction", default=None, description="The action to take after form submission" ) def json(self, **kwargs: typing.Any) -> str: diff --git a/src/webflow/types/form_submission.py b/src/webflow/types/form_submission.py index 157a5fa..c32d501 100644 --- a/src/webflow/types/form_submission.py +++ b/src/webflow/types/form_submission.py @@ -12,21 +12,21 @@ class FormSubmission(pydantic.BaseModel): - id: typing.Optional[str] = pydantic.Field(description="The unique id of the Form submission") + id: typing.Optional[str] = pydantic.Field(default=None, description="The unique id of the Form submission") display_name: typing.Optional[str] = pydantic.Field( - alias="displayName", description="The Form name displayed on the site" + alias="displayName", default=None, description="The Form name displayed on the site" ) site_id: typing.Optional[str] = pydantic.Field( - alias="siteId", description="The unique id of the Site the Form belongs to" + alias="siteId", default=None, description="The unique id of the Site the Form belongs to" ) workspace_id: typing.Optional[str] = pydantic.Field( - alias="workspaceId", description="The unique id of the Workspace the Site belongs to" + alias="workspaceId", default=None, description="The unique id of the Workspace the Site belongs to" ) date_submitted: typing.Optional[dt.datetime] = pydantic.Field( - alias="dateSubmitted", description="Date that the Form was submitted on" + alias="dateSubmitted", default=None, description="Date that the Form was submitted on" ) form_response: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field( - alias="formResponse", description="The data submitted in the Form" + alias="formResponse", default=None, description="The data submitted in the Form" ) def json(self, **kwargs: typing.Any) -> str: diff --git a/src/webflow/types/form_submission_list.py b/src/webflow/types/form_submission_list.py index 6658e51..78beebd 100644 --- a/src/webflow/types/form_submission_list.py +++ b/src/webflow/types/form_submission_list.py @@ -14,8 +14,8 @@ class FormSubmissionList(pydantic.BaseModel): - submissions: typing.Optional[typing.List[FormSubmission]] - pagination: typing.Optional[Pagination] + submissions: typing.Optional[typing.List[FormSubmission]] = None + pagination: typing.Optional[Pagination] = None def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/form_submission_trigger.py b/src/webflow/types/form_submission_trigger.py index 1caa143..c04dc77 100644 --- a/src/webflow/types/form_submission_trigger.py +++ b/src/webflow/types/form_submission_trigger.py @@ -14,10 +14,10 @@ class FormSubmissionTrigger(pydantic.BaseModel): trigger_type: typing.Optional[str] = pydantic.Field( - alias="triggerType", description="The type of event that triggered the request" + alias="triggerType", default=None, description="The type of event that triggered the request" ) payload: typing.Optional[FormSubmissionTriggerPayload] = pydantic.Field( - description="The payload of data sent from Webflow" + default=None, description="The payload of data sent from Webflow" ) def json(self, **kwargs: typing.Any) -> str: diff --git a/src/webflow/types/form_submission_trigger_payload.py b/src/webflow/types/form_submission_trigger_payload.py index 56e6a17..ced3f9d 100644 --- a/src/webflow/types/form_submission_trigger_payload.py +++ b/src/webflow/types/form_submission_trigger_payload.py @@ -16,15 +16,19 @@ class FormSubmissionTriggerPayload(pydantic.BaseModel): The payload of data sent from Webflow """ - name: typing.Optional[str] = pydantic.Field(description="The name of the form") + name: typing.Optional[str] = pydantic.Field(default=None, description="The name of the form") site_id: typing.Optional[str] = pydantic.Field( - alias="siteId", description="The id of the site that the form was submitted from" + alias="siteId", default=None, description="The id of the site that the form was submitted from" + ) + data: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field( + default=None, description="The data submitted in the form" ) - data: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(description="The data submitted in the form") submitted_at: typing.Optional[str] = pydantic.Field( - alias="submittedAt", description="The timestamp the form was submitted" + alias="submittedAt", default=None, description="The timestamp the form was submitted" + ) + form_id: typing.Optional[str] = pydantic.Field( + alias="formId", default=None, description="The id of the form submission" ) - form_id: typing.Optional[str] = pydantic.Field(alias="formId", description="The id of the form submission") def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/image_node.py b/src/webflow/types/image_node.py new file mode 100644 index 0000000..019874c --- /dev/null +++ b/src/webflow/types/image_node.py @@ -0,0 +1,34 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +from ..core.datetime_utils import serialize_datetime + +try: + import pydantic.v1 as pydantic # type: ignore +except ImportError: + import pydantic # type: ignore + + +class ImageNode(pydantic.BaseModel): + """ + Represents an image within the DOM. It contains details about the image, such as its alternative text (alt) for accessibility and an asset identifier for fetching the actual image resource. Additional attributes can be associated with the image for styling or other purposes. + """ + + alt: typing.Optional[str] = None + asset_id: typing.Optional[str] = pydantic.Field(alias="assetId", default=None) + + def json(self, **kwargs: typing.Any) -> str: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().json(**kwargs_with_defaults) + + def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().dict(**kwargs_with_defaults) + + class Config: + frozen = True + smart_union = True + allow_population_by_field_name = True + json_encoders = {dt.datetime: serialize_datetime} diff --git a/src/webflow/types/invalid_scopes.py b/src/webflow/types/invalid_scopes.py new file mode 100644 index 0000000..7fac370 --- /dev/null +++ b/src/webflow/types/invalid_scopes.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +from ..core.datetime_utils import serialize_datetime + +try: + import pydantic.v1 as pydantic # type: ignore +except ImportError: + import pydantic # type: ignore + + +class InvalidScopes(pydantic.BaseModel): + status: typing.Optional[int] = None + message: typing.Optional[str] = None + public_error_code: typing.Optional[str] = pydantic.Field(alias="publicErrorCode", default=None) + external_reference: typing.Optional[str] = pydantic.Field(alias="externalReference", default=None) + details: typing.Optional[typing.List[str]] = None + + def json(self, **kwargs: typing.Any) -> str: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().json(**kwargs_with_defaults) + + def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().dict(**kwargs_with_defaults) + + class Config: + frozen = True + smart_union = True + allow_population_by_field_name = True + json_encoders = {dt.datetime: serialize_datetime} diff --git a/src/webflow/types/inventory_item.py b/src/webflow/types/inventory_item.py index a563e48..d1f66e9 100644 --- a/src/webflow/types/inventory_item.py +++ b/src/webflow/types/inventory_item.py @@ -17,12 +17,12 @@ class InventoryItem(pydantic.BaseModel): The availabile inventory for an item """ - id: typing.Optional[str] = pydantic.Field(description="Unique identifier for a SKU item") + id: typing.Optional[str] = pydantic.Field(default=None, description="Unique identifier for a SKU item") quantity: typing.Optional[float] = pydantic.Field( - description="Total quantity of items remaining in inventory (if inventoryType is finite)" + default=None, description="Total quantity of items remaining in inventory (if inventoryType is finite)" ) inventory_type: typing.Optional[InventoryItemInventoryType] = pydantic.Field( - alias="inventoryType", description="infinite or finite" + alias="inventoryType", default=None, description="infinite or finite" ) def json(self, **kwargs: typing.Any) -> str: diff --git a/src/webflow/types/list_custom_code_blocks.py b/src/webflow/types/list_custom_code_blocks.py index 4a7266d..20ea276 100644 --- a/src/webflow/types/list_custom_code_blocks.py +++ b/src/webflow/types/list_custom_code_blocks.py @@ -18,8 +18,8 @@ class ListCustomCodeBlocks(pydantic.BaseModel): Custom Code Blocks corresponding to where scripts were applied """ - blocks: typing.Optional[typing.List[CustomCodeBlock]] - pagination: typing.Optional[Pagination] + blocks: typing.Optional[typing.List[CustomCodeBlock]] = None + pagination: typing.Optional[Pagination] = None def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/missing_scopes.py b/src/webflow/types/missing_scopes.py index fc32d21..74e0a7f 100644 --- a/src/webflow/types/missing_scopes.py +++ b/src/webflow/types/missing_scopes.py @@ -3,8 +3,6 @@ import datetime as dt import typing -import typing_extensions - from ..core.datetime_utils import serialize_datetime from .error_details_item import ErrorDetailsItem @@ -15,13 +13,15 @@ class MissingScopes(pydantic.BaseModel): - code: typing.Optional[typing_extensions.Literal["missing_scopes"]] - type: typing.Optional[str] - message: typing.Optional[str] = pydantic.Field(description="Error message") + code: typing.Optional[typing.Literal["missing_scopes"]] = None + type: typing.Optional[str] = None + message: typing.Optional[str] = pydantic.Field(default=None, description="Error message") external_reference: typing.Optional[str] = pydantic.Field( - alias="externalReference", description="Link to more information" + alias="externalReference", default=None, description="Link to more information" + ) + details: typing.Optional[typing.List[ErrorDetailsItem]] = pydantic.Field( + default=None, description="Array of errors" ) - details: typing.Optional[typing.List[ErrorDetailsItem]] = pydantic.Field(description="Array of errors") def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/node.py b/src/webflow/types/node.py new file mode 100644 index 0000000..d15cf06 --- /dev/null +++ b/src/webflow/types/node.py @@ -0,0 +1,39 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +from ..core.datetime_utils import serialize_datetime +from .image_node import ImageNode +from .node_type import NodeType +from .text_node import TextNode + +try: + import pydantic.v1 as pydantic # type: ignore +except ImportError: + import pydantic # type: ignore + + +class Node(pydantic.BaseModel): + """ + A generic representation of a content element within the Document Object Model (DOM). Each node has a unique identifier and a specific type that determines its content structure and attributes. + """ + + id: typing.Optional[str] = pydantic.Field(default=None, description="Node UUID") + type: typing.Optional[NodeType] = None + text: typing.Optional[TextNode] = None + image: typing.Optional[ImageNode] = None + attributes: typing.Optional[typing.Dict[str, str]] = None + + def json(self, **kwargs: typing.Any) -> str: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().json(**kwargs_with_defaults) + + def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().dict(**kwargs_with_defaults) + + class Config: + frozen = True + smart_union = True + json_encoders = {dt.datetime: serialize_datetime} diff --git a/src/webflow/types/node_type.py b/src/webflow/types/node_type.py new file mode 100644 index 0000000..943719c --- /dev/null +++ b/src/webflow/types/node_type.py @@ -0,0 +1,17 @@ +# This file was auto-generated by Fern from our API Definition. + +import enum +import typing + +T_Result = typing.TypeVar("T_Result") + + +class NodeType(str, enum.Enum): + TEXT = "text" + IMAGE = "image" + + def visit(self, text: typing.Callable[[], T_Result], image: typing.Callable[[], T_Result]) -> T_Result: + if self is NodeType.TEXT: + return text() + if self is NodeType.IMAGE: + return image() diff --git a/src/webflow/types/not_enterprise_plan_site.py b/src/webflow/types/not_enterprise_plan_site.py new file mode 100644 index 0000000..9c2c607 --- /dev/null +++ b/src/webflow/types/not_enterprise_plan_site.py @@ -0,0 +1,38 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +from ..core.datetime_utils import serialize_datetime +from .error_details_item import ErrorDetailsItem + +try: + import pydantic.v1 as pydantic # type: ignore +except ImportError: + import pydantic # type: ignore + + +class NotEnterprisePlanSite(pydantic.BaseModel): + code: typing.Optional[typing.Literal["missing_scopes"]] = None + type: typing.Optional[str] = None + message: typing.Optional[str] = pydantic.Field(default=None, description="Error message") + external_reference: typing.Optional[str] = pydantic.Field( + alias="externalReference", default=None, description="Link to more information" + ) + details: typing.Optional[typing.List[ErrorDetailsItem]] = pydantic.Field( + default=None, description="Array of errors" + ) + + def json(self, **kwargs: typing.Any) -> str: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().json(**kwargs_with_defaults) + + def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().dict(**kwargs_with_defaults) + + class Config: + frozen = True + smart_union = True + allow_population_by_field_name = True + json_encoders = {dt.datetime: serialize_datetime} diff --git a/src/webflow/types/oauth_scope.py b/src/webflow/types/oauth_scope.py index 4299b79..ed41a48 100644 --- a/src/webflow/types/oauth_scope.py +++ b/src/webflow/types/oauth_scope.py @@ -62,6 +62,11 @@ class OauthScope(str, enum.Enum): edit ecommerce data """ + SITE_ACTIVITY_READ = "site_activity:read" + """ + read site activity logs + """ + def visit( self, authorized_user_read: typing.Callable[[], T_Result], @@ -75,6 +80,7 @@ def visit( users_write: typing.Callable[[], T_Result], ecommerce_read: typing.Callable[[], T_Result], ecommerce_write: typing.Callable[[], T_Result], + site_activity_read: typing.Callable[[], T_Result], ) -> T_Result: if self is OauthScope.AUTHORIZED_USER_READ: return authorized_user_read() @@ -98,3 +104,5 @@ def visit( return ecommerce_read() if self is OauthScope.ECOMMERCE_WRITE: return ecommerce_write() + if self is OauthScope.SITE_ACTIVITY_READ: + return site_activity_read() diff --git a/src/webflow/types/order.py b/src/webflow/types/order.py index 8ad20be..9f7cdd6 100644 --- a/src/webflow/types/order.py +++ b/src/webflow/types/order.py @@ -26,99 +26,118 @@ class Order(pydantic.BaseModel): order_id: typing.Optional[str] = pydantic.Field( alias="orderId", + default=None, description="The order id. Will usually be 6 hex characters, but can also be 9 hex characters if the site has a very large number of Orders. Randomly assigned.", ) - status: typing.Optional[OrderStatus] = pydantic.Field(description="The status of the Order") + status: typing.Optional[OrderStatus] = pydantic.Field(default=None, description="The status of the Order") comment: typing.Optional[str] = pydantic.Field( - description="A comment string for this Order editable by API user (not used by Webflow)." + default=None, description="A comment string for this Order editable by API user (not used by Webflow)." ) order_comment: typing.Optional[str] = pydantic.Field( - alias="orderComment", description="A comment that the customer left when making their Order" + alias="orderComment", default=None, description="A comment that the customer left when making their Order" ) accepted_on: typing.Optional[dt.datetime] = pydantic.Field( - alias="acceptedOn", description="The ISO8601 timestamp that an Order was placed." + alias="acceptedOn", default=None, description="The ISO8601 timestamp that an Order was placed." ) fulfilled_on: typing.Optional[dt.datetime] = pydantic.Field( alias="fulfilledOn", + default=None, description="If an Order was marked as 'fulfilled', then this is the ISO8601 timestamp when that happened.", ) refunded_on: typing.Optional[dt.datetime] = pydantic.Field( - alias="refundedOn", description="If an Order was refunded, this is the ISO8601 of when that happened." + alias="refundedOn", + default=None, + description="If an Order was refunded, this is the ISO8601 of when that happened.", ) disputed_on: typing.Optional[dt.datetime] = pydantic.Field( alias="disputedOn", + default=None, description="If an Order was disputed by the customer, then this key will be set with the ISO8601 timestamp that Stripe notifies Webflow. Null if not disputed.", ) dispute_updated_on: typing.Optional[dt.datetime] = pydantic.Field( alias="disputeUpdatedOn", + default=None, description="If an Order was disputed by the customer, then this key will be set with the ISO8601 timestamp of the last time that we got an update. Null if not disputed.", ) dispute_last_status: typing.Optional[OrderDisputeLastStatus] = pydantic.Field( alias="disputeLastStatus", + default=None, description="If an order was disputed by the customer, then this key will be set with the [dispute's status](https://stripe.com/docs/api#dispute_object-status).", ) customer_paid: typing.Optional[OrderPrice] = pydantic.Field( - alias="customerPaid", description="The total paid by the customer" + alias="customerPaid", default=None, description="The total paid by the customer" ) net_amount: typing.Optional[OrderPrice] = pydantic.Field( - alias="netAmount", description="The net amount after application fees" + alias="netAmount", default=None, description="The net amount after application fees" ) application_fee: typing.Optional[OrderPrice] = pydantic.Field( - alias="applicationFee", description="The application fee assessed by the platform" + alias="applicationFee", default=None, description="The application fee assessed by the platform" ) all_addresses: typing.Optional[typing.List[OrderAddress]] = pydantic.Field( - alias="allAddresses", description="All addresses provided by the customer during the ordering flow." + alias="allAddresses", + default=None, + description="All addresses provided by the customer during the ordering flow.", ) shipping_address: typing.Optional[OrderAddress] = pydantic.Field( - alias="shippingAddress", description="The shipping address" + alias="shippingAddress", default=None, description="The shipping address" ) billing_address: typing.Optional[OrderAddress] = pydantic.Field( - alias="billingAddress", description="The billing address" + alias="billingAddress", default=None, description="The billing address" ) shipping_provider: typing.Optional[str] = pydantic.Field( alias="shippingProvider", + default=None, description="A string editable by the API user to note the shipping provider used (not used by Webflow).", ) shipping_tracking: typing.Optional[str] = pydantic.Field( alias="shippingTracking", + default=None, description="A string editable by the API user to note the shipping tracking number for the order (not used by Webflow).", ) - shipping_tracking_url: typing.Optional[str] = pydantic.Field(alias="shippingTrackingURL") + shipping_tracking_url: typing.Optional[str] = pydantic.Field(alias="shippingTrackingURL", default=None) customer_info: typing.Optional[OrderCustomerInfo] = pydantic.Field( - alias="customerInfo", description="An object with the keys `fullName` and `email`." + alias="customerInfo", default=None, description="An object with the keys `fullName` and `email`." ) purchased_items: typing.Optional[typing.List[OrderPurchasedItem]] = pydantic.Field( - alias="purchasedItems", description="An array of all things that the Customer purchased." + alias="purchasedItems", default=None, description="An array of all things that the Customer purchased." ) purchased_items_count: typing.Optional[float] = pydantic.Field( - alias="purchasedItemsCount", description="The sum of all 'count' fields in 'purchasedItems'." + alias="purchasedItemsCount", default=None, description="The sum of all 'count' fields in 'purchasedItems'." ) - stripe_details: typing.Optional[StripeDetails] = pydantic.Field(alias="stripeDetails") - stripe_card: typing.Optional[StripeCard] = pydantic.Field(alias="stripeCard") - paypal_details: typing.Optional[PaypalDetails] = pydantic.Field(alias="paypalDetails") + stripe_details: typing.Optional[StripeDetails] = pydantic.Field(alias="stripeDetails", default=None) + stripe_card: typing.Optional[StripeCard] = pydantic.Field(alias="stripeCard", default=None) + paypal_details: typing.Optional[PaypalDetails] = pydantic.Field(alias="paypalDetails", default=None) custom_data: typing.Optional[typing.List[typing.Dict[str, typing.Any]]] = pydantic.Field( alias="customData", + default=None, description="An array of additional inputs for custom order data gathering. Each object in the array represents an input with a name, and a textInput, textArea, or checkbox value.", ) - metadata: typing.Optional[OrderMetadata] + metadata: typing.Optional[OrderMetadata] = None is_customer_deleted: typing.Optional[bool] = pydantic.Field( alias="isCustomerDeleted", + default=None, description="A boolean indicating whether the customer has been deleted from the site.", ) is_shipping_required: typing.Optional[bool] = pydantic.Field( alias="isShippingRequired", + default=None, description="A boolean indicating whether the order contains one or more purchased items that require shipping.", ) has_downloads: typing.Optional[bool] = pydantic.Field( alias="hasDownloads", + default=None, description="A boolean indicating whether the order contains one or more purchased items that are downloadable.", ) payment_processor: typing.Optional[str] = pydantic.Field( - alias="paymentProcessor", description="A string indicating the payment processor used for this order." + alias="paymentProcessor", + default=None, + description="A string indicating the payment processor used for this order.", + ) + totals: typing.Optional[OrderTotals] = pydantic.Field( + default=None, description="An object describing various pricing totals" ) - totals: typing.Optional[OrderTotals] = pydantic.Field(description="An object describing various pricing totals") download_files: typing.Optional[typing.List[OrderDownloadFilesItem]] = pydantic.Field( - alias="downloadFiles", description="An array of downloadable file objects." + alias="downloadFiles", default=None, description="An array of downloadable file objects." ) def json(self, **kwargs: typing.Any) -> str: diff --git a/src/webflow/types/order_address.py b/src/webflow/types/order_address.py index fa0561a..a22a3de 100644 --- a/src/webflow/types/order_address.py +++ b/src/webflow/types/order_address.py @@ -19,18 +19,24 @@ class OrderAddress(pydantic.BaseModel): """ type: typing.Optional[OrderAddressType] = pydantic.Field( - description="The type of the order address (billing or shipping)" + default=None, description="The type of the order address (billing or shipping)" ) japan_type: typing.Optional[OrderAddressJapanType] = pydantic.Field( - alias="japanType", description="Japan-only address format" + alias="japanType", default=None, description="Japan-only address format" + ) + addressee: typing.Optional[str] = pydantic.Field(default=None, description="Display name on the address") + line_1: typing.Optional[str] = pydantic.Field( + alias="line1", default=None, description="The first line of the address" + ) + line_2: typing.Optional[str] = pydantic.Field( + alias="line2", default=None, description="The second line of the address" + ) + city: typing.Optional[str] = pydantic.Field(default=None, description="The city of the address.") + state: typing.Optional[str] = pydantic.Field(default=None, description="The state or province of the address") + country: typing.Optional[str] = pydantic.Field(default=None, description="The country of the address") + postal_code: typing.Optional[str] = pydantic.Field( + alias="postalCode", default=None, description="The postal code of the address" ) - addressee: typing.Optional[str] = pydantic.Field(description="Display name on the address") - line_1: typing.Optional[str] = pydantic.Field(alias="line1", description="The first line of the address") - line_2: typing.Optional[str] = pydantic.Field(alias="line2", description="The second line of the address") - city: typing.Optional[str] = pydantic.Field(description="The city of the address.") - state: typing.Optional[str] = pydantic.Field(description="The state or province of the address") - country: typing.Optional[str] = pydantic.Field(description="The country of the address") - postal_code: typing.Optional[str] = pydantic.Field(alias="postalCode", description="The postal code of the address") def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/order_customer_info.py b/src/webflow/types/order_customer_info.py index 1603ec9..e0486d2 100644 --- a/src/webflow/types/order_customer_info.py +++ b/src/webflow/types/order_customer_info.py @@ -16,8 +16,10 @@ class OrderCustomerInfo(pydantic.BaseModel): An object with the keys `fullName` and `email`. """ - full_name: typing.Optional[str] = pydantic.Field(alias="fullName", description="The full name of the Customer") - email: typing.Optional[str] = pydantic.Field(description="The Customer's email address") + full_name: typing.Optional[str] = pydantic.Field( + alias="fullName", default=None, description="The full name of the Customer" + ) + email: typing.Optional[str] = pydantic.Field(default=None, description="The Customer's email address") def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/order_download_files_item.py b/src/webflow/types/order_download_files_item.py index d6f46ec..15a3210 100644 --- a/src/webflow/types/order_download_files_item.py +++ b/src/webflow/types/order_download_files_item.py @@ -12,9 +12,15 @@ class OrderDownloadFilesItem(pydantic.BaseModel): - id: typing.Optional[str] = pydantic.Field(description="The unique identifier for the downloadable file") - name: typing.Optional[str] = pydantic.Field(description="The user-facing name for the downloadable file") - url: typing.Optional[str] = pydantic.Field(description="The hosted location for the downloadable file") + id: typing.Optional[str] = pydantic.Field( + default=None, description="The unique identifier for the downloadable file" + ) + name: typing.Optional[str] = pydantic.Field( + default=None, description="The user-facing name for the downloadable file" + ) + url: typing.Optional[str] = pydantic.Field( + default=None, description="The hosted location for the downloadable file" + ) def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/order_list.py b/src/webflow/types/order_list.py index a3e9c00..2ad1b84 100644 --- a/src/webflow/types/order_list.py +++ b/src/webflow/types/order_list.py @@ -18,8 +18,8 @@ class OrderList(pydantic.BaseModel): Results from order list """ - items: typing.Optional[typing.List[Order]] = pydantic.Field(description="List of orders") - pagination: typing.Optional[Pagination] + items: typing.Optional[typing.List[Order]] = pydantic.Field(default=None, description="List of orders") + pagination: typing.Optional[Pagination] = None def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/order_metadata.py b/src/webflow/types/order_metadata.py index 089f63f..d37fc38 100644 --- a/src/webflow/types/order_metadata.py +++ b/src/webflow/types/order_metadata.py @@ -12,7 +12,7 @@ class OrderMetadata(pydantic.BaseModel): - is_buy_now: typing.Optional[bool] = pydantic.Field(alias="isBuyNow") + is_buy_now: typing.Optional[bool] = pydantic.Field(alias="isBuyNow", default=None) def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/order_price.py b/src/webflow/types/order_price.py index 097ed30..36012d1 100644 --- a/src/webflow/types/order_price.py +++ b/src/webflow/types/order_price.py @@ -12,9 +12,13 @@ class OrderPrice(pydantic.BaseModel): - unit: typing.Optional[str] = pydantic.Field(description="The three-letter ISO currency code") - value: typing.Optional[str] = pydantic.Field(description="The numeric value in the base unit of the currency") - string: typing.Optional[str] = pydantic.Field(description="The user-facing string representation of the amount") + unit: typing.Optional[str] = pydantic.Field(default=None, description="The three-letter ISO currency code") + value: typing.Optional[str] = pydantic.Field( + default=None, description="The numeric value in the base unit of the currency" + ) + string: typing.Optional[str] = pydantic.Field( + default=None, description="The user-facing string representation of the amount" + ) def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/order_purchased_item.py b/src/webflow/types/order_purchased_item.py index a7e9f24..f2250aa 100644 --- a/src/webflow/types/order_purchased_item.py +++ b/src/webflow/types/order_purchased_item.py @@ -18,37 +18,43 @@ class OrderPurchasedItem(pydantic.BaseModel): An Item that was purchased """ - count: typing.Optional[float] = pydantic.Field(description="Number of Item purchased.") - row_total: typing.Optional[OrderPrice] = pydantic.Field(alias="rowTotal", description="The total for the row") + count: typing.Optional[float] = pydantic.Field(default=None, description="Number of Item purchased.") + row_total: typing.Optional[OrderPrice] = pydantic.Field( + alias="rowTotal", default=None, description="The total for the row" + ) product_id: typing.Optional[str] = pydantic.Field( - alias="productId", description="The unique identifier for the Product" + alias="productId", default=None, description="The unique identifier for the Product" ) product_name: typing.Optional[str] = pydantic.Field( - alias="productName", description="User-facing name of the Product" + alias="productName", default=None, description="User-facing name of the Product" + ) + product_slug: typing.Optional[str] = pydantic.Field( + alias="productSlug", default=None, description="Slug for the Product" ) - product_slug: typing.Optional[str] = pydantic.Field(alias="productSlug", description="Slug for the Product") variant_id: typing.Optional[str] = pydantic.Field( - alias="variantId", description="Identifier for the Product Variant (SKU)" + alias="variantId", default=None, description="Identifier for the Product Variant (SKU)" ) variant_name: typing.Optional[str] = pydantic.Field( - alias="variantName", description="User-facing name of the Product Variant (SKU)" + alias="variantName", default=None, description="User-facing name of the Product Variant (SKU)" ) variant_slug: typing.Optional[str] = pydantic.Field( - alias="variantSlug", description="Slug for the Product Variant (SKU)" + alias="variantSlug", default=None, description="Slug for the Product Variant (SKU)" ) - variant_image: typing.Optional[OrderPurchasedItemVariantImage] = pydantic.Field(alias="variantImage") + variant_image: typing.Optional[OrderPurchasedItemVariantImage] = pydantic.Field(alias="variantImage", default=None) variant_price: typing.Optional[OrderPrice] = pydantic.Field( - alias="variantPrice", description="The price corresponding to the variant" + alias="variantPrice", default=None, description="The price corresponding to the variant" ) weight: typing.Optional[float] = pydantic.Field( - description="The physical weight of the variant if provided, or null" + default=None, description="The physical weight of the variant if provided, or null" + ) + width: typing.Optional[float] = pydantic.Field( + default=None, description="The physical width of the variant if provided, or null" ) - width: typing.Optional[float] = pydantic.Field(description="The physical width of the variant if provided, or null") height: typing.Optional[float] = pydantic.Field( - description="The physical height of the variant if provided, or null" + default=None, description="The physical height of the variant if provided, or null" ) length: typing.Optional[float] = pydantic.Field( - description="The physical length of the variant if provided, or null" + default=None, description="The physical length of the variant if provided, or null" ) def json(self, **kwargs: typing.Any) -> str: diff --git a/src/webflow/types/order_purchased_item_variant_image.py b/src/webflow/types/order_purchased_item_variant_image.py index 32d721c..0b31d99 100644 --- a/src/webflow/types/order_purchased_item_variant_image.py +++ b/src/webflow/types/order_purchased_item_variant_image.py @@ -13,8 +13,8 @@ class OrderPurchasedItemVariantImage(pydantic.BaseModel): - url: typing.Optional[str] = pydantic.Field(description="The hosted location for the Variant's image") - file: typing.Optional[OrderPurchasedItemVariantImageFile] + url: typing.Optional[str] = pydantic.Field(default=None, description="The hosted location for the Variant's image") + file: typing.Optional[OrderPurchasedItemVariantImageFile] = None def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/order_purchased_item_variant_image_file.py b/src/webflow/types/order_purchased_item_variant_image_file.py index cd79481..9d73a2d 100644 --- a/src/webflow/types/order_purchased_item_variant_image_file.py +++ b/src/webflow/types/order_purchased_item_variant_image_file.py @@ -13,18 +13,20 @@ class OrderPurchasedItemVariantImageFile(pydantic.BaseModel): - size: typing.Optional[float] = pydantic.Field(description="The image size in bytes") + size: typing.Optional[float] = pydantic.Field(default=None, description="The image size in bytes") original_file_name: typing.Optional[str] = pydantic.Field( - alias="originalFileName", description="the original name of the image" + alias="originalFileName", default=None, description="the original name of the image" ) created_on: typing.Optional[dt.datetime] = pydantic.Field( - alias="createdOn", description="The creation timestamp of the image" + alias="createdOn", default=None, description="The creation timestamp of the image" ) - content_type: typing.Optional[str] = pydantic.Field(alias="contentType", description="The MIME type of the image") - width: typing.Optional[int] = pydantic.Field(description="The image width in pixels") - height: typing.Optional[int] = pydantic.Field(description="The image height in pixels") + content_type: typing.Optional[str] = pydantic.Field( + alias="contentType", default=None, description="The MIME type of the image" + ) + width: typing.Optional[int] = pydantic.Field(default=None, description="The image width in pixels") + height: typing.Optional[int] = pydantic.Field(default=None, description="The image height in pixels") variants: typing.Optional[typing.List[OrderPurchasedItemVariantImageFileVariantsItem]] = pydantic.Field( - description="Variants of the supplied image" + default=None, description="Variants of the supplied image" ) def json(self, **kwargs: typing.Any) -> str: diff --git a/src/webflow/types/order_purchased_item_variant_image_file_variants_item.py b/src/webflow/types/order_purchased_item_variant_image_file_variants_item.py index 52387b8..fc37a0d 100644 --- a/src/webflow/types/order_purchased_item_variant_image_file_variants_item.py +++ b/src/webflow/types/order_purchased_item_variant_image_file_variants_item.py @@ -12,11 +12,11 @@ class OrderPurchasedItemVariantImageFileVariantsItem(pydantic.BaseModel): - url: typing.Optional[str] = pydantic.Field(description="The hosted location for the Variant's image") - original_file_name: typing.Optional[str] = pydantic.Field(alias="originalFileName") - size: typing.Optional[float] = pydantic.Field(description="The image size in bytes") - width: typing.Optional[int] = pydantic.Field(description="The image width in pixels") - height: typing.Optional[int] = pydantic.Field(description="The image height in pixels") + url: typing.Optional[str] = pydantic.Field(default=None, description="The hosted location for the Variant's image") + original_file_name: typing.Optional[str] = pydantic.Field(alias="originalFileName", default=None) + size: typing.Optional[float] = pydantic.Field(default=None, description="The image size in bytes") + width: typing.Optional[int] = pydantic.Field(default=None, description="The image width in pixels") + height: typing.Optional[int] = pydantic.Field(default=None, description="The image height in pixels") def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/order_totals.py b/src/webflow/types/order_totals.py index 8c19a5a..ef88075 100644 --- a/src/webflow/types/order_totals.py +++ b/src/webflow/types/order_totals.py @@ -18,11 +18,11 @@ class OrderTotals(pydantic.BaseModel): An object describing various pricing totals """ - subtotal: typing.Optional[OrderPrice] = pydantic.Field(description="The subtotal price") + subtotal: typing.Optional[OrderPrice] = pydantic.Field(default=None, description="The subtotal price") extras: typing.Optional[typing.List[OrderTotalsExtrasItem]] = pydantic.Field( - description="An array of extra items, includes discounts, shipping, and taxes." + default=None, description="An array of extra items, includes discounts, shipping, and taxes." ) - total: typing.Optional[OrderPrice] = pydantic.Field(description="The total price") + total: typing.Optional[OrderPrice] = pydantic.Field(default=None, description="The total price") def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/order_totals_extras_item.py b/src/webflow/types/order_totals_extras_item.py index b771246..e2a70e0 100644 --- a/src/webflow/types/order_totals_extras_item.py +++ b/src/webflow/types/order_totals_extras_item.py @@ -18,14 +18,16 @@ class OrderTotalsExtrasItem(pydantic.BaseModel): Extra order items, includes discounts, shipping, and taxes. """ - type: typing.Optional[OrderTotalsExtrasItemType] = pydantic.Field(description="The type of extra item this is.") + type: typing.Optional[OrderTotalsExtrasItemType] = pydantic.Field( + default=None, description="The type of extra item this is." + ) name: typing.Optional[str] = pydantic.Field( - description="A human-readable (but English) name for this extra charge." + default=None, description="A human-readable (but English) name for this extra charge." ) description: typing.Optional[str] = pydantic.Field( - description="A human-readable (but English) description of this extra charge." + default=None, description="A human-readable (but English) description of this extra charge." ) - price: typing.Optional[OrderPrice] = pydantic.Field(description="The price for the item") + price: typing.Optional[OrderPrice] = pydantic.Field(default=None, description="The price for the item") def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/page.py b/src/webflow/types/page.py index 00a4735..f67e4b2 100644 --- a/src/webflow/types/page.py +++ b/src/webflow/types/page.py @@ -18,34 +18,41 @@ class Page(pydantic.BaseModel): The Page object """ - id: typing.Optional[str] = pydantic.Field(description="Unique identifier for the Page") - site_id: typing.Optional[str] = pydantic.Field(alias="siteId", description="Unique identifier for the Site") - title: typing.Optional[str] = pydantic.Field(description="Title of the Page") - slug: typing.Optional[str] = pydantic.Field(description="slug of the Page (derived from title)") - parent_id: typing.Optional[str] = pydantic.Field(alias="parentId", description="Identifier of the parent folder") + id: typing.Optional[str] = pydantic.Field(default=None, description="Unique identifier for the Page") + site_id: typing.Optional[str] = pydantic.Field( + alias="siteId", default=None, description="Unique identifier for the Site" + ) + title: typing.Optional[str] = pydantic.Field(default=None, description="Title of the Page") + slug: typing.Optional[str] = pydantic.Field(default=None, description="slug of the Page (derived from title)") + parent_id: typing.Optional[str] = pydantic.Field( + alias="parentId", default=None, description="Identifier of the parent folder" + ) collection_id: typing.Optional[str] = pydantic.Field( alias="collectionId", + default=None, description="Unique identifier for a linked Collection, value will be null if the Page is not part of a Collection.", ) created_on: typing.Optional[dt.datetime] = pydantic.Field( - alias="createdOn", description="The date the Page was created" + alias="createdOn", default=None, description="The date the Page was created" ) last_updated: typing.Optional[dt.datetime] = pydantic.Field( - alias="lastUpdated", description="The date the Page was most recently updated" + alias="lastUpdated", default=None, description="The date the Page was most recently updated" ) - archived: typing.Optional[bool] = pydantic.Field(description="Whether the Page has been archived") - draft: typing.Optional[bool] = pydantic.Field(description="Whether the Page is a draft") + archived: typing.Optional[bool] = pydantic.Field(default=None, description="Whether the Page has been archived") + draft: typing.Optional[bool] = pydantic.Field(default=None, description="Whether the Page is a draft") can_branch: typing.Optional[bool] = pydantic.Field( alias="canBranch", + default=None, description="Indicates whether the Page supports [Page Branching](https://university.webflow.com/lesson/page-branching)", ) is_members_only: typing.Optional[bool] = pydantic.Field( alias="isMembersOnly", + default=None, description="Indicates whether the Page is restricted by [Memberships Controls](https://university.webflow.com/lesson/webflow-memberships-overview#how-to-manage-page-restrictions)", ) - seo: typing.Optional[PageSeo] = pydantic.Field(description="SEO-related fields for the Page") + seo: typing.Optional[PageSeo] = pydantic.Field(default=None, description="SEO-related fields for the Page") open_graph: typing.Optional[PageOpenGraph] = pydantic.Field( - alias="openGraph", description="Open Graph fields for the Page" + alias="openGraph", default=None, description="Open Graph fields for the Page" ) def json(self, **kwargs: typing.Any) -> str: diff --git a/src/webflow/types/page_created_webhook.py b/src/webflow/types/page_created_webhook.py index 267f6d6..ce1dcfa 100644 --- a/src/webflow/types/page_created_webhook.py +++ b/src/webflow/types/page_created_webhook.py @@ -16,10 +16,10 @@ class PageCreatedWebhook(pydantic.BaseModel): The Webhook payload for when a Page is created """ - site_id: typing.Optional[str] = pydantic.Field(alias="siteId") - page_id: typing.Optional[str] = pydantic.Field(alias="pageId") - page_title: typing.Optional[str] = pydantic.Field(alias="pageTitle") - created_at: typing.Optional[dt.datetime] = pydantic.Field(alias="createdAt") + site_id: typing.Optional[str] = pydantic.Field(alias="siteId", default=None) + page_id: typing.Optional[str] = pydantic.Field(alias="pageId", default=None) + page_title: typing.Optional[str] = pydantic.Field(alias="pageTitle", default=None) + created_at: typing.Optional[dt.datetime] = pydantic.Field(alias="createdAt", default=None) def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/page_deleted_webhook.py b/src/webflow/types/page_deleted_webhook.py index 0125d65..d97c9a5 100644 --- a/src/webflow/types/page_deleted_webhook.py +++ b/src/webflow/types/page_deleted_webhook.py @@ -16,10 +16,10 @@ class PageDeletedWebhook(pydantic.BaseModel): The Webhook payload for when a Page is deleted """ - site_id: typing.Optional[str] = pydantic.Field(alias="siteId") - page_id: typing.Optional[str] = pydantic.Field(alias="pageId") - page_title: typing.Optional[str] = pydantic.Field(alias="pageTitle") - deleted_at: typing.Optional[dt.datetime] = pydantic.Field(alias="deletedAt") + site_id: typing.Optional[str] = pydantic.Field(alias="siteId", default=None) + page_id: typing.Optional[str] = pydantic.Field(alias="pageId", default=None) + page_title: typing.Optional[str] = pydantic.Field(alias="pageTitle", default=None) + deleted_at: typing.Optional[dt.datetime] = pydantic.Field(alias="deletedAt", default=None) def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/page_list.py b/src/webflow/types/page_list.py index 9d93365..3ba1a63 100644 --- a/src/webflow/types/page_list.py +++ b/src/webflow/types/page_list.py @@ -18,8 +18,8 @@ class PageList(pydantic.BaseModel): The Page object """ - pages: typing.Optional[typing.List[Page]] - pagination: typing.Optional[Pagination] + pages: typing.Optional[typing.List[Page]] = None + pagination: typing.Optional[Pagination] = None def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/page_metadata_updated_webhook.py b/src/webflow/types/page_metadata_updated_webhook.py index b2bf0ff..e8e99bb 100644 --- a/src/webflow/types/page_metadata_updated_webhook.py +++ b/src/webflow/types/page_metadata_updated_webhook.py @@ -16,10 +16,10 @@ class PageMetadataUpdatedWebhook(pydantic.BaseModel): The Webhook payload for when a Page's metadata is updated """ - site_id: typing.Optional[str] = pydantic.Field(alias="siteId") - page_id: typing.Optional[str] = pydantic.Field(alias="pageId") - page_title: typing.Optional[str] = pydantic.Field(alias="pageTitle") - last_updated: typing.Optional[dt.datetime] = pydantic.Field(alias="lastUpdated") + site_id: typing.Optional[str] = pydantic.Field(alias="siteId", default=None) + page_id: typing.Optional[str] = pydantic.Field(alias="pageId", default=None) + page_title: typing.Optional[str] = pydantic.Field(alias="pageTitle", default=None) + last_updated: typing.Optional[dt.datetime] = pydantic.Field(alias="lastUpdated", default=None) def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/page_open_graph.py b/src/webflow/types/page_open_graph.py index 2be127b..2c7f5fb 100644 --- a/src/webflow/types/page_open_graph.py +++ b/src/webflow/types/page_open_graph.py @@ -16,13 +16,18 @@ class PageOpenGraph(pydantic.BaseModel): Open Graph fields for the Page """ - title: typing.Optional[str] = pydantic.Field(description="The title supplied to Open Graph annotations") + title: typing.Optional[str] = pydantic.Field( + default=None, description="The title supplied to Open Graph annotations" + ) title_copied: typing.Optional[bool] = pydantic.Field( - alias="titleCopied", description="Indicates the Open Graph title was copied from the SEO title" + alias="titleCopied", default=None, description="Indicates the Open Graph title was copied from the SEO title" + ) + description: typing.Optional[str] = pydantic.Field( + default=None, description="The description supplied to Open Graph annotations" ) - description: typing.Optional[str] = pydantic.Field(description="The description supplied to Open Graph annotations") description_copied: typing.Optional[bool] = pydantic.Field( alias="descriptionCopied", + default=None, description="Indicates the Open Graph description was copied from the SEO description", ) diff --git a/src/webflow/types/page_seo.py b/src/webflow/types/page_seo.py index 76ed235..091d1e9 100644 --- a/src/webflow/types/page_seo.py +++ b/src/webflow/types/page_seo.py @@ -16,9 +16,11 @@ class PageSeo(pydantic.BaseModel): SEO-related fields for the Page """ - title: typing.Optional[str] = pydantic.Field(description="The Page title shown in search engine results") + title: typing.Optional[str] = pydantic.Field( + default=None, description="The Page title shown in search engine results" + ) description: typing.Optional[str] = pydantic.Field( - description="The Page description shown in search engine results" + default=None, description="The Page description shown in search engine results" ) def json(self, **kwargs: typing.Any) -> str: diff --git a/src/webflow/types/page_seo_graph_data.py b/src/webflow/types/page_seo_graph_data.py index 3af35d1..b57bbc6 100644 --- a/src/webflow/types/page_seo_graph_data.py +++ b/src/webflow/types/page_seo_graph_data.py @@ -18,8 +18,8 @@ class PageSeoGraphData(pydantic.BaseModel): The SEO and/or OpenGraph information to include in the page's details """ - seo: typing.Optional[PageSeoGraphDataSeo] - open_graph: typing.Optional[PageSeoGraphDataOpenGraph] = pydantic.Field(alias="openGraph") + seo: typing.Optional[PageSeoGraphDataSeo] = None + open_graph: typing.Optional[PageSeoGraphDataOpenGraph] = pydantic.Field(alias="openGraph", default=None) def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/page_seo_graph_data_open_graph.py b/src/webflow/types/page_seo_graph_data_open_graph.py index de4a071..0064bc5 100644 --- a/src/webflow/types/page_seo_graph_data_open_graph.py +++ b/src/webflow/types/page_seo_graph_data_open_graph.py @@ -12,8 +12,8 @@ class PageSeoGraphDataOpenGraph(pydantic.BaseModel): - title: typing.Optional[str] - description: typing.Optional[str] + title: typing.Optional[str] = None + description: typing.Optional[str] = None def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/page_seo_graph_data_seo.py b/src/webflow/types/page_seo_graph_data_seo.py index 6c95d2b..d7c9dc4 100644 --- a/src/webflow/types/page_seo_graph_data_seo.py +++ b/src/webflow/types/page_seo_graph_data_seo.py @@ -12,8 +12,8 @@ class PageSeoGraphDataSeo(pydantic.BaseModel): - title: typing.Optional[str] - description: typing.Optional[str] + title: typing.Optional[str] = None + description: typing.Optional[str] = None def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/pagination.py b/src/webflow/types/pagination.py index 63b09db..b8bb3b6 100644 --- a/src/webflow/types/pagination.py +++ b/src/webflow/types/pagination.py @@ -16,9 +16,9 @@ class Pagination(pydantic.BaseModel): Pagination object """ - limit: typing.Optional[float] = pydantic.Field(description="The limit used for pagination") - offset: typing.Optional[float] = pydantic.Field(description="The offset used for pagination") - total: typing.Optional[float] = pydantic.Field(description="The total number of records") + limit: typing.Optional[float] = pydantic.Field(default=None, description="The limit used for pagination") + offset: typing.Optional[float] = pydantic.Field(default=None, description="The offset used for pagination") + total: typing.Optional[float] = pydantic.Field(default=None, description="The total number of records") def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/paypal_details.py b/src/webflow/types/paypal_details.py index 055f96e..80afce3 100644 --- a/src/webflow/types/paypal_details.py +++ b/src/webflow/types/paypal_details.py @@ -12,14 +12,24 @@ class PaypalDetails(pydantic.BaseModel): - order_id: typing.Optional[str] = pydantic.Field(alias="orderId", description="PayPal order identifier") - payer_id: typing.Optional[str] = pydantic.Field(alias="payerId", description="PayPal payer identifier") - capture_id: typing.Optional[str] = pydantic.Field(alias="captureId", description="PayPal capture identifier") - refund_id: typing.Optional[str] = pydantic.Field(alias="refundId", description="PayPal refund identifier") + order_id: typing.Optional[str] = pydantic.Field( + alias="orderId", default=None, description="PayPal order identifier" + ) + payer_id: typing.Optional[str] = pydantic.Field( + alias="payerId", default=None, description="PayPal payer identifier" + ) + capture_id: typing.Optional[str] = pydantic.Field( + alias="captureId", default=None, description="PayPal capture identifier" + ) + refund_id: typing.Optional[str] = pydantic.Field( + alias="refundId", default=None, description="PayPal refund identifier" + ) refund_reason: typing.Optional[str] = pydantic.Field( - alias="refundReason", description="PayPal-issued reason for the refund" + alias="refundReason", default=None, description="PayPal-issued reason for the refund" + ) + dispute_id: typing.Optional[str] = pydantic.Field( + alias="disputeId", default=None, description="PayPal dispute identifier" ) - dispute_id: typing.Optional[str] = pydantic.Field(alias="disputeId", description="PayPal dispute identifier") def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/product.py b/src/webflow/types/product.py index 7a6d3d1..81e7372 100644 --- a/src/webflow/types/product.py +++ b/src/webflow/types/product.py @@ -17,23 +17,23 @@ class Product(pydantic.BaseModel): The Product object """ - id: typing.Optional[str] = pydantic.Field(description="Unique identifier for the Product") + id: typing.Optional[str] = pydantic.Field(default=None, description="Unique identifier for the Product") last_published: typing.Optional[dt.datetime] = pydantic.Field( - alias="lastPublished", description="The date the Product was last published" + alias="lastPublished", default=None, description="The date the Product was last published" ) last_updated: typing.Optional[dt.datetime] = pydantic.Field( - alias="lastUpdated", description="The date the Product was last updated" + alias="lastUpdated", default=None, description="The date the Product was last updated" ) created_on: typing.Optional[dt.datetime] = pydantic.Field( - alias="createdOn", description="The date the Product was created" + alias="createdOn", default=None, description="The date the Product was created" ) is_archived: typing.Optional[bool] = pydantic.Field( - alias="isArchived", description="Boolean determining if the Product is set to archived" + alias="isArchived", default=None, description="Boolean determining if the Product is set to archived" ) is_draft: typing.Optional[bool] = pydantic.Field( - alias="isDraft", description="Boolean determining if the Product is set to draft" + alias="isDraft", default=None, description="Boolean determining if the Product is set to draft" ) - field_data: typing.Optional[ProductFieldData] = pydantic.Field(alias="fieldData") + field_data: typing.Optional[ProductFieldData] = pydantic.Field(alias="fieldData", default=None) def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/product_and_sk_us.py b/src/webflow/types/product_and_sk_us.py index 435f0ca..64ee6b5 100644 --- a/src/webflow/types/product_and_sk_us.py +++ b/src/webflow/types/product_and_sk_us.py @@ -18,8 +18,8 @@ class ProductAndSkUs(pydantic.BaseModel): A product and its SKUs. """ - product: typing.Optional[Product] - skus: typing.Optional[typing.List[Sku]] + product: typing.Optional[Product] = None + skus: typing.Optional[typing.List[Sku]] = pydantic.Field(default=None, description="A list of SKU Objects") def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/product_and_sk_us_list.py b/src/webflow/types/product_and_sk_us_list.py index f059785..0c2eae5 100644 --- a/src/webflow/types/product_and_sk_us_list.py +++ b/src/webflow/types/product_and_sk_us_list.py @@ -19,9 +19,10 @@ class ProductAndSkUsList(pydantic.BaseModel): """ items: typing.Optional[typing.List[ProductAndSkUs]] = pydantic.Field( - description="List of Item objects within the Collection. Contains product and skus keys for each Item" + default=None, + description="List of Item objects within the Collection. Contains product and skus keys for each Item", ) - pagination: typing.Optional[Pagination] + pagination: typing.Optional[Pagination] = None def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/product_field_data.py b/src/webflow/types/product_field_data.py index 744dfbf..756c629 100644 --- a/src/webflow/types/product_field_data.py +++ b/src/webflow/types/product_field_data.py @@ -4,6 +4,8 @@ import typing from ..core.datetime_utils import serialize_datetime +from .product_field_data_ec_product_type import ProductFieldDataEcProductType +from .product_field_data_tax_category import ProductFieldDataTaxCategory from .sku_property_list import SkuPropertyList try: @@ -13,10 +15,31 @@ class ProductFieldData(pydantic.BaseModel): - name: typing.Optional[str] = pydantic.Field(description="Name of the Product") - slug: typing.Optional[str] = pydantic.Field(description="URL structure of the Product in your site.") + name: str = pydantic.Field(description="Name of the Product") + slug: str = pydantic.Field(description="URL structure of the Product in your site.") + description: typing.Optional[str] = pydantic.Field(default=None, description="A description of your product") + shippable: typing.Optional[bool] = pydantic.Field( + default=None, description="Boolean determining if the Product is shippable" + ) sku_properties: typing.Optional[typing.List[SkuPropertyList]] = pydantic.Field( - alias="sku-properties", description="Variant/Options types to include in SKUs" + alias="sku-properties", default=None, description="Variant types to include in SKUs" + ) + categories: typing.Optional[typing.List[str]] = pydantic.Field( + default=None, description="The categories your product belongs to." + ) + tax_category: typing.Optional[ProductFieldDataTaxCategory] = pydantic.Field( + alias="tax-category", default=None, description="Product tax class" + ) + default_sku: typing.Optional[str] = pydantic.Field( + alias="default-sku", default=None, description="The default SKU associated with this product." + ) + ec_product_type: typing.Optional[ProductFieldDataEcProductType] = pydantic.Field( + alias="ec-product-type", + default=None, + description='Product types. Enums reflect the following values in order: Physical, Digital, Service, Advanced"', + ) + additional_properties: typing.Optional[str] = pydantic.Field( + alias="additionalProperties", default=None, description="Custom fields for your product." ) def json(self, **kwargs: typing.Any) -> str: diff --git a/src/webflow/types/product_field_data_ec_product_type.py b/src/webflow/types/product_field_data_ec_product_type.py new file mode 100644 index 0000000..f496e5a --- /dev/null +++ b/src/webflow/types/product_field_data_ec_product_type.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +import enum +import typing + +T_Result = typing.TypeVar("T_Result") + + +class ProductFieldDataEcProductType(str, enum.Enum): + """ + Product types. Enums reflect the following values in order: Physical, Digital, Service, Advanced" + """ + + FF_42_FEE_0113744_F_693_A_764_E_3431_A_9_CC_2 = "ff42fee0113744f693a764e3431a9cc2" + F_22027_DB_68002190_AEF_89_A_4_A_2_B_7_AC_8_A_1 = "f22027db68002190aef89a4a2b7ac8a1" + C_599_E_43_B_1_A_1_C_34_D_5_A_323_AEDF_75_D_3_ADF_6 = "c599e43b1a1c34d5a323aedf75d3adf6" + B_6_CCC_1830_DB_4_B_1_BABEB_06_A_9_AC_5_F_6_DD_76 = "b6ccc1830db4b1babeb06a9ac5f6dd76" + + def visit( + self, + ff_42_fee_0113744_f_693_a_764_e_3431_a_9_cc_2: typing.Callable[[], T_Result], + f_22027_db_68002190_aef_89_a_4_a_2_b_7_ac_8_a_1: typing.Callable[[], T_Result], + c_599_e_43_b_1_a_1_c_34_d_5_a_323_aedf_75_d_3_adf_6: typing.Callable[[], T_Result], + b_6_ccc_1830_db_4_b_1_babeb_06_a_9_ac_5_f_6_dd_76: typing.Callable[[], T_Result], + ) -> T_Result: + if self is ProductFieldDataEcProductType.FF_42_FEE_0113744_F_693_A_764_E_3431_A_9_CC_2: + return ff_42_fee_0113744_f_693_a_764_e_3431_a_9_cc_2() + if self is ProductFieldDataEcProductType.F_22027_DB_68002190_AEF_89_A_4_A_2_B_7_AC_8_A_1: + return f_22027_db_68002190_aef_89_a_4_a_2_b_7_ac_8_a_1() + if self is ProductFieldDataEcProductType.C_599_E_43_B_1_A_1_C_34_D_5_A_323_AEDF_75_D_3_ADF_6: + return c_599_e_43_b_1_a_1_c_34_d_5_a_323_aedf_75_d_3_adf_6() + if self is ProductFieldDataEcProductType.B_6_CCC_1830_DB_4_B_1_BABEB_06_A_9_AC_5_F_6_DD_76: + return b_6_ccc_1830_db_4_b_1_babeb_06_a_9_ac_5_f_6_dd_76() diff --git a/src/webflow/types/product_field_data_tax_category.py b/src/webflow/types/product_field_data_tax_category.py new file mode 100644 index 0000000..bb27b51 --- /dev/null +++ b/src/webflow/types/product_field_data_tax_category.py @@ -0,0 +1,133 @@ +# This file was auto-generated by Fern from our API Definition. + +import enum +import typing + +T_Result = typing.TypeVar("T_Result") + + +class ProductFieldDataTaxCategory(str, enum.Enum): + """ + Product tax class + """ + + STANDARD_TAXABLE = "standard-taxable" + STANDARD_EXEMPT = "standard-exempt" + BOOKS_RELIGIOUS = "books-religious" + BOOKS_TEXTBOOK = "books-textbook" + CLOTHING = "clothing" + CLOTHING_SWIMWEAR = "clothing-swimwear" + DIGITAL_GOODS = "digital-goods" + DIGITAL_SERVICE = "digital-service" + DRUGS_NON_PRESCRIPTION = "drugs-non-prescription" + DRUGS_PRESCRIPTION = "drugs-prescription" + FOOD_BOTTLED_WATER = "food-bottled-water" + FOOD_CANDY = "food-candy" + FOOD_GROCERIES = "food-groceries" + FOOD_PREPARED = "food-prepared" + FOOD_SODA = "food-soda" + FOOD_SUPPLEMENTS = "food-supplements" + MAGAZINE_INDIVIDUAL = "magazine-individual" + MAGAZINE_SUBSCRIPTION = "magazine-subscription" + SERVICE_ADMISSION = "service-admission" + SERVICE_ADVERTISING = "service-advertising" + SERVICE_DRY_CLEANING = "service-dry-cleaning" + SERVICE_HAIRDRESSING = "service-hairdressing" + SERVICE_INSTALLATION = "service-installation" + SERVICE_MISCELLANEOUS = "service-miscellaneous" + SERVICE_PARKING = "service-parking" + SERVICE_PRINTING = "service-printing" + SERVICE_PROFESSIONAL = "service-professional" + SERVICE_REPAIR = "service-repair" + SERVICE_TRAINING = "service-training" + + def visit( + self, + standard_taxable: typing.Callable[[], T_Result], + standard_exempt: typing.Callable[[], T_Result], + books_religious: typing.Callable[[], T_Result], + books_textbook: typing.Callable[[], T_Result], + clothing: typing.Callable[[], T_Result], + clothing_swimwear: typing.Callable[[], T_Result], + digital_goods: typing.Callable[[], T_Result], + digital_service: typing.Callable[[], T_Result], + drugs_non_prescription: typing.Callable[[], T_Result], + drugs_prescription: typing.Callable[[], T_Result], + food_bottled_water: typing.Callable[[], T_Result], + food_candy: typing.Callable[[], T_Result], + food_groceries: typing.Callable[[], T_Result], + food_prepared: typing.Callable[[], T_Result], + food_soda: typing.Callable[[], T_Result], + food_supplements: typing.Callable[[], T_Result], + magazine_individual: typing.Callable[[], T_Result], + magazine_subscription: typing.Callable[[], T_Result], + service_admission: typing.Callable[[], T_Result], + service_advertising: typing.Callable[[], T_Result], + service_dry_cleaning: typing.Callable[[], T_Result], + service_hairdressing: typing.Callable[[], T_Result], + service_installation: typing.Callable[[], T_Result], + service_miscellaneous: typing.Callable[[], T_Result], + service_parking: typing.Callable[[], T_Result], + service_printing: typing.Callable[[], T_Result], + service_professional: typing.Callable[[], T_Result], + service_repair: typing.Callable[[], T_Result], + service_training: typing.Callable[[], T_Result], + ) -> T_Result: + if self is ProductFieldDataTaxCategory.STANDARD_TAXABLE: + return standard_taxable() + if self is ProductFieldDataTaxCategory.STANDARD_EXEMPT: + return standard_exempt() + if self is ProductFieldDataTaxCategory.BOOKS_RELIGIOUS: + return books_religious() + if self is ProductFieldDataTaxCategory.BOOKS_TEXTBOOK: + return books_textbook() + if self is ProductFieldDataTaxCategory.CLOTHING: + return clothing() + if self is ProductFieldDataTaxCategory.CLOTHING_SWIMWEAR: + return clothing_swimwear() + if self is ProductFieldDataTaxCategory.DIGITAL_GOODS: + return digital_goods() + if self is ProductFieldDataTaxCategory.DIGITAL_SERVICE: + return digital_service() + if self is ProductFieldDataTaxCategory.DRUGS_NON_PRESCRIPTION: + return drugs_non_prescription() + if self is ProductFieldDataTaxCategory.DRUGS_PRESCRIPTION: + return drugs_prescription() + if self is ProductFieldDataTaxCategory.FOOD_BOTTLED_WATER: + return food_bottled_water() + if self is ProductFieldDataTaxCategory.FOOD_CANDY: + return food_candy() + if self is ProductFieldDataTaxCategory.FOOD_GROCERIES: + return food_groceries() + if self is ProductFieldDataTaxCategory.FOOD_PREPARED: + return food_prepared() + if self is ProductFieldDataTaxCategory.FOOD_SODA: + return food_soda() + if self is ProductFieldDataTaxCategory.FOOD_SUPPLEMENTS: + return food_supplements() + if self is ProductFieldDataTaxCategory.MAGAZINE_INDIVIDUAL: + return magazine_individual() + if self is ProductFieldDataTaxCategory.MAGAZINE_SUBSCRIPTION: + return magazine_subscription() + if self is ProductFieldDataTaxCategory.SERVICE_ADMISSION: + return service_admission() + if self is ProductFieldDataTaxCategory.SERVICE_ADVERTISING: + return service_advertising() + if self is ProductFieldDataTaxCategory.SERVICE_DRY_CLEANING: + return service_dry_cleaning() + if self is ProductFieldDataTaxCategory.SERVICE_HAIRDRESSING: + return service_hairdressing() + if self is ProductFieldDataTaxCategory.SERVICE_INSTALLATION: + return service_installation() + if self is ProductFieldDataTaxCategory.SERVICE_MISCELLANEOUS: + return service_miscellaneous() + if self is ProductFieldDataTaxCategory.SERVICE_PARKING: + return service_parking() + if self is ProductFieldDataTaxCategory.SERVICE_PRINTING: + return service_printing() + if self is ProductFieldDataTaxCategory.SERVICE_PROFESSIONAL: + return service_professional() + if self is ProductFieldDataTaxCategory.SERVICE_REPAIR: + return service_repair() + if self is ProductFieldDataTaxCategory.SERVICE_TRAINING: + return service_training() diff --git a/src/webflow/types/publish_status.py b/src/webflow/types/publish_status.py index c416bfb..dbee8d9 100644 --- a/src/webflow/types/publish_status.py +++ b/src/webflow/types/publish_status.py @@ -8,7 +8,7 @@ class PublishStatus(str, enum.Enum): """ - Publish target + Indicate whether your Product should be set as "staging" or "live" """ STAGING = "staging" diff --git a/src/webflow/types/published_items.py b/src/webflow/types/published_items.py index 747338a..e0ad961 100644 --- a/src/webflow/types/published_items.py +++ b/src/webflow/types/published_items.py @@ -17,9 +17,9 @@ class PublishedItems(pydantic.BaseModel): """ published_item_ids: typing.Optional[typing.List[str]] = pydantic.Field( - alias="publishedItemIds", description="Array of published item ids" + alias="publishedItemIds", default=None, description="Array of published item ids" ) - errors: typing.Optional[typing.List[str]] = pydantic.Field(description="Array of errors") + errors: typing.Optional[typing.List[str]] = pydantic.Field(default=None, description="Array of errors") def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/registered_script_list.py b/src/webflow/types/registered_script_list.py index 69e8c11..96bcbaa 100644 --- a/src/webflow/types/registered_script_list.py +++ b/src/webflow/types/registered_script_list.py @@ -13,7 +13,9 @@ class RegisteredScriptList(pydantic.BaseModel): - registered_scripts: typing.Optional[typing.List[CustomCodeResponse]] = pydantic.Field(alias="registeredScripts") + registered_scripts: typing.Optional[typing.List[CustomCodeResponse]] = pydantic.Field( + alias="registeredScripts", default=None + ) def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/removed_items.py b/src/webflow/types/removed_items.py index 26c5d94..889df1d 100644 --- a/src/webflow/types/removed_items.py +++ b/src/webflow/types/removed_items.py @@ -17,9 +17,9 @@ class RemovedItems(pydantic.BaseModel): """ deleted_item_ids: typing.Optional[typing.List[str]] = pydantic.Field( - alias="deletedItemIds", description="Array of deleted item ids" + alias="deletedItemIds", default=None, description="Array of deleted item ids" ) - errors: typing.Optional[typing.List[str]] = pydantic.Field(description="Array of errors") + errors: typing.Optional[typing.List[str]] = pydantic.Field(default=None, description="Array of errors") def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/script_apply.py b/src/webflow/types/script_apply.py index 628e6f9..2868113 100644 --- a/src/webflow/types/script_apply.py +++ b/src/webflow/types/script_apply.py @@ -19,7 +19,7 @@ class ScriptApply(pydantic.BaseModel): ) version: str = pydantic.Field(description="Semantic Version String for the registered script _e.g. 0.0.1_") attributes: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field( - description="Developer-specified key/value pairs to be applied as attributes to the script" + default=None, description="Developer-specified key/value pairs to be applied as attributes to the script" ) def json(self, **kwargs: typing.Any) -> str: diff --git a/src/webflow/types/script_apply_list.py b/src/webflow/types/script_apply_list.py index 6f66099..23e7579 100644 --- a/src/webflow/types/script_apply_list.py +++ b/src/webflow/types/script_apply_list.py @@ -13,12 +13,12 @@ class ScriptApplyList(pydantic.BaseModel): - scripts: typing.Optional[typing.List[ScriptApply]] + scripts: typing.Optional[typing.List[ScriptApply]] = None last_updated: typing.Optional[str] = pydantic.Field( - alias="lastUpdated", description="Date when the Site's scripts were last updated" + alias="lastUpdated", default=None, description="Date when the Site's scripts were last updated" ) created_on: typing.Optional[str] = pydantic.Field( - alias="createdOn", description="Date when the Site's scripts were created" + alias="createdOn", default=None, description="Date when the Site's scripts were created" ) def json(self, **kwargs: typing.Any) -> str: diff --git a/src/webflow/types/site.py b/src/webflow/types/site.py index d25372a..c1bba38 100644 --- a/src/webflow/types/site.py +++ b/src/webflow/types/site.py @@ -15,26 +15,30 @@ class Site(pydantic.BaseModel): id: str = pydantic.Field(description="Unique identifier for the Site") workspace_id: typing.Optional[str] = pydantic.Field( - alias="workspaceId", description="Unique identifier for the Workspace" + alias="workspaceId", default=None, description="Unique identifier for the Workspace" ) created_on: typing.Optional[dt.datetime] = pydantic.Field( - alias="createdOn", description="Date the Site was created" + alias="createdOn", default=None, description="Date the Site was created" + ) + display_name: typing.Optional[str] = pydantic.Field( + alias="displayName", default=None, description="Name given to Site" + ) + short_name: typing.Optional[str] = pydantic.Field( + alias="shortName", default=None, description="Slugified version of name" ) - display_name: typing.Optional[str] = pydantic.Field(alias="displayName", description="Name given to Site") - short_name: typing.Optional[str] = pydantic.Field(alias="shortName", description="Slugified version of name") last_published: typing.Optional[dt.datetime] = pydantic.Field( - alias="lastPublished", description="Date the Site was last published" + alias="lastPublished", default=None, description="Date the Site was last published" ) last_updated: typing.Optional[dt.datetime] = pydantic.Field( - alias="lastUpdated", description="Date the Site was last updated" + alias="lastUpdated", default=None, description="Date the Site was last updated" ) preview_url: typing.Optional[str] = pydantic.Field( - alias="previewUrl", description="URL of a generated image for the given Site" + alias="previewUrl", default=None, description="URL of a generated image for the given Site" ) time_zone: typing.Optional[str] = pydantic.Field( - alias="timeZone", description="Site timezone set under Site Settings" + alias="timeZone", default=None, description="Site timezone set under Site Settings" ) - custom_domains: typing.Optional[typing.List[Domain]] = pydantic.Field(alias="customDomains") + custom_domains: typing.Optional[typing.List[Domain]] = pydantic.Field(alias="customDomains", default=None) def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/site_activity_log_item.py b/src/webflow/types/site_activity_log_item.py index f993073..f04b804 100644 --- a/src/webflow/types/site_activity_log_item.py +++ b/src/webflow/types/site_activity_log_item.py @@ -5,6 +5,7 @@ from ..core.datetime_utils import serialize_datetime from .site_activity_log_item_resource_operation import SiteActivityLogItemResourceOperation +from .site_activity_log_item_user import SiteActivityLogItemUser try: import pydantic.v1 as pydantic # type: ignore @@ -13,19 +14,19 @@ class SiteActivityLogItem(pydantic.BaseModel): - id: typing.Optional[str] - created_on: typing.Optional[dt.datetime] = pydantic.Field(alias="createdOn") - last_updated: typing.Optional[dt.datetime] = pydantic.Field(alias="lastUpdated") - event: typing.Optional[str] + id: typing.Optional[str] = None + created_on: typing.Optional[dt.datetime] = pydantic.Field(alias="createdOn", default=None) + last_updated: typing.Optional[dt.datetime] = pydantic.Field(alias="lastUpdated", default=None) + event: typing.Optional[str] = None resource_operation: typing.Optional[SiteActivityLogItemResourceOperation] = pydantic.Field( - alias="resourceOperation" + alias="resourceOperation", default=None ) - user: typing.Optional[str] - resource_id: typing.Optional[str] = pydantic.Field(alias="resourceId") - resource_name: typing.Optional[str] = pydantic.Field(alias="resourceName") - new_value: typing.Optional[str] = pydantic.Field(alias="newValue") - previous_value: typing.Optional[str] = pydantic.Field(alias="previousValue") - payload: typing.Optional[typing.Dict[str, typing.Any]] + user: typing.Optional[SiteActivityLogItemUser] = None + resource_id: typing.Optional[str] = pydantic.Field(alias="resourceId", default=None) + resource_name: typing.Optional[str] = pydantic.Field(alias="resourceName", default=None) + new_value: typing.Optional[str] = pydantic.Field(alias="newValue", default=None) + previous_value: typing.Optional[str] = pydantic.Field(alias="previousValue", default=None) + payload: typing.Optional[typing.Dict[str, typing.Any]] = None def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/site_activity_log_item_user.py b/src/webflow/types/site_activity_log_item_user.py new file mode 100644 index 0000000..66bcfbb --- /dev/null +++ b/src/webflow/types/site_activity_log_item_user.py @@ -0,0 +1,30 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +from ..core.datetime_utils import serialize_datetime + +try: + import pydantic.v1 as pydantic # type: ignore +except ImportError: + import pydantic # type: ignore + + +class SiteActivityLogItemUser(pydantic.BaseModel): + id: typing.Optional[str] = None + display_name: typing.Optional[str] = pydantic.Field(alias="displayName", default=None) + + def json(self, **kwargs: typing.Any) -> str: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().json(**kwargs_with_defaults) + + def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().dict(**kwargs_with_defaults) + + class Config: + frozen = True + smart_union = True + allow_population_by_field_name = True + json_encoders = {dt.datetime: serialize_datetime} diff --git a/src/webflow/types/site_activity_log_response.py b/src/webflow/types/site_activity_log_response.py index 3bba088..06a04ab 100644 --- a/src/webflow/types/site_activity_log_response.py +++ b/src/webflow/types/site_activity_log_response.py @@ -14,8 +14,8 @@ class SiteActivityLogResponse(pydantic.BaseModel): - items: typing.Optional[typing.List[SiteActivityLogItem]] - pagination: typing.Optional[Pagination] + items: typing.Optional[typing.List[SiteActivityLogItem]] = None + pagination: typing.Optional[Pagination] = None def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/site_publish.py b/src/webflow/types/site_publish.py index af2fc92..81936e2 100644 --- a/src/webflow/types/site_publish.py +++ b/src/webflow/types/site_publish.py @@ -13,7 +13,9 @@ class SitePublish(pydantic.BaseModel): - payload: typing.Optional[SitePublishPayload] = pydantic.Field(description="The payload of data sent from Webflow") + payload: typing.Optional[SitePublishPayload] = pydantic.Field( + default=None, description="The payload of data sent from Webflow" + ) def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/site_publish_payload.py b/src/webflow/types/site_publish_payload.py index 366a3a5..35da24d 100644 --- a/src/webflow/types/site_publish_payload.py +++ b/src/webflow/types/site_publish_payload.py @@ -16,13 +16,15 @@ class SitePublishPayload(pydantic.BaseModel): The payload of data sent from Webflow """ - site: typing.Optional[str] = pydantic.Field(description="The site id that was published") + site: typing.Optional[str] = pydantic.Field(default=None, description="The site id that was published") publish_time: typing.Optional[dt.datetime] = pydantic.Field( - alias="publishTime", description="The timestamp of the publish event" + alias="publishTime", default=None, description="The timestamp of the publish event" + ) + domains: typing.Optional[typing.List[str]] = pydantic.Field( + default=None, description="The domains that were published" ) - domains: typing.Optional[typing.List[str]] = pydantic.Field(description="The domains that were published") published_by: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field( - alias="publishedBy", description="The name and id of the user who published the site" + alias="publishedBy", default=None, description="The name and id of the user who published the site" ) def json(self, **kwargs: typing.Any) -> str: diff --git a/src/webflow/types/sites.py b/src/webflow/types/sites.py index 4273e7f..e292bce 100644 --- a/src/webflow/types/sites.py +++ b/src/webflow/types/sites.py @@ -13,7 +13,7 @@ class Sites(pydantic.BaseModel): - sites: typing.Optional[typing.List[Site]] + sites: typing.Optional[typing.List[Site]] = None def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/sku.py b/src/webflow/types/sku.py index 31c193e..a97ee15 100644 --- a/src/webflow/types/sku.py +++ b/src/webflow/types/sku.py @@ -17,17 +17,19 @@ class Sku(pydantic.BaseModel): The SKU object """ - id: typing.Optional[str] = pydantic.Field(description="Unique identifier for the Product") + id: typing.Optional[str] = pydantic.Field(default=None, description="Unique identifier for the Product") last_published: typing.Optional[dt.datetime] = pydantic.Field( - alias="lastPublished", description="The date the Product was last published" + alias="lastPublished", default=None, description="The date the Product was last published" ) last_updated: typing.Optional[dt.datetime] = pydantic.Field( - alias="lastUpdated", description="The date the Product was last updated" + alias="lastUpdated", default=None, description="The date the Product was last updated" ) created_on: typing.Optional[dt.datetime] = pydantic.Field( - alias="createdOn", description="The date the Product was created" + alias="createdOn", default=None, description="The date the Product was created" + ) + field_data: typing.Optional[SkuFieldData] = pydantic.Field( + alias="fieldData", default=None, description="Standard and Custom fields for a SKU" ) - field_data: typing.Optional[SkuFieldData] = pydantic.Field(alias="fieldData") def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/sku_field_data.py b/src/webflow/types/sku_field_data.py index 27ca178..7143bc3 100644 --- a/src/webflow/types/sku_field_data.py +++ b/src/webflow/types/sku_field_data.py @@ -4,6 +4,9 @@ import typing from ..core.datetime_utils import serialize_datetime +from .sku_field_data_compare_at_price import SkuFieldDataCompareAtPrice +from .sku_field_data_ec_sku_billing_method import SkuFieldDataEcSkuBillingMethod +from .sku_field_data_ec_sku_subscription_plan import SkuFieldDataEcSkuSubscriptionPlan from .sku_field_data_price import SkuFieldDataPrice from .sku_value_list import SkuValueList @@ -14,10 +17,31 @@ class SkuFieldData(pydantic.BaseModel): - name: typing.Optional[str] = pydantic.Field(description="Name of the Product") - slug: typing.Optional[str] = pydantic.Field(description="URL structure of the Product in your site.") - price: typing.Optional[SkuFieldDataPrice] = pydantic.Field(description="price of SKU") - sku_values: typing.Optional[SkuValueList] = pydantic.Field(alias="sku-values") + """ + Standard and Custom fields for a SKU + """ + + sku_values: typing.Optional[SkuValueList] = pydantic.Field(alias="sku-values", default=None) + name: str = pydantic.Field(description="Name of the Product") + slug: str = pydantic.Field(description="URL structure of the Product in your site.") + price: SkuFieldDataPrice = pydantic.Field(description="price of SKU") + compare_at_price: typing.Optional[SkuFieldDataCompareAtPrice] = pydantic.Field( + alias="compare-at-price", default=None, description="comparison price of SKU" + ) + ec_sku_billing_method: typing.Optional[SkuFieldDataEcSkuBillingMethod] = pydantic.Field( + alias="ec-sku-billing-method", default=None + ) + ec_sku_subscription_plan: typing.Optional[SkuFieldDataEcSkuSubscriptionPlan] = pydantic.Field( + alias="ec-sku-subscription-plan", default=None + ) + track_inventory: typing.Optional[bool] = pydantic.Field( + alias="track-inventory", + default=None, + description="A boolean indicating whether inventory for this product should be tracked.", + ) + quantity: typing.Optional[float] = pydantic.Field( + default=None, description="Quantity of SKU that will be tracked as items are ordered." + ) def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/sku_field_data_compare_at_price.py b/src/webflow/types/sku_field_data_compare_at_price.py new file mode 100644 index 0000000..6b85f7a --- /dev/null +++ b/src/webflow/types/sku_field_data_compare_at_price.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +from ..core.datetime_utils import serialize_datetime + +try: + import pydantic.v1 as pydantic # type: ignore +except ImportError: + import pydantic # type: ignore + + +class SkuFieldDataCompareAtPrice(pydantic.BaseModel): + """ + comparison price of SKU + """ + + value: typing.Optional[float] = pydantic.Field(default=None, description="Price of SKU") + unit: typing.Optional[str] = pydantic.Field(default=None, description="Currency of Item") + + def json(self, **kwargs: typing.Any) -> str: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().json(**kwargs_with_defaults) + + def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().dict(**kwargs_with_defaults) + + class Config: + frozen = True + smart_union = True + json_encoders = {dt.datetime: serialize_datetime} diff --git a/src/webflow/types/sku_field_data_ec_sku_billing_method.py b/src/webflow/types/sku_field_data_ec_sku_billing_method.py new file mode 100644 index 0000000..044f305 --- /dev/null +++ b/src/webflow/types/sku_field_data_ec_sku_billing_method.py @@ -0,0 +1,17 @@ +# This file was auto-generated by Fern from our API Definition. + +import enum +import typing + +T_Result = typing.TypeVar("T_Result") + + +class SkuFieldDataEcSkuBillingMethod(str, enum.Enum): + ONE_TIME = "one-time" + SUBSCRIPTION = "subscription" + + def visit(self, one_time: typing.Callable[[], T_Result], subscription: typing.Callable[[], T_Result]) -> T_Result: + if self is SkuFieldDataEcSkuBillingMethod.ONE_TIME: + return one_time() + if self is SkuFieldDataEcSkuBillingMethod.SUBSCRIPTION: + return subscription() diff --git a/src/webflow/types/sku_field_data_ec_sku_subscription_plan.py b/src/webflow/types/sku_field_data_ec_sku_subscription_plan.py new file mode 100644 index 0000000..e69bcb4 --- /dev/null +++ b/src/webflow/types/sku_field_data_ec_sku_subscription_plan.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +from ..core.datetime_utils import serialize_datetime +from .sku_field_data_ec_sku_subscription_plan_interval import SkuFieldDataEcSkuSubscriptionPlanInterval + +try: + import pydantic.v1 as pydantic # type: ignore +except ImportError: + import pydantic # type: ignore + + +class SkuFieldDataEcSkuSubscriptionPlan(pydantic.BaseModel): + interval: typing.Optional[SkuFieldDataEcSkuSubscriptionPlanInterval] = pydantic.Field( + default=None, description="Interval of subscription renewal" + ) + frequency: typing.Optional[float] = pydantic.Field(default=None, description="Frequncy of billing within interval") + trial: typing.Optional[float] = pydantic.Field(default=None, description="Number of days of a trial") + + def json(self, **kwargs: typing.Any) -> str: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().json(**kwargs_with_defaults) + + def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().dict(**kwargs_with_defaults) + + class Config: + frozen = True + smart_union = True + json_encoders = {dt.datetime: serialize_datetime} diff --git a/src/webflow/types/sku_field_data_ec_sku_subscription_plan_interval.py b/src/webflow/types/sku_field_data_ec_sku_subscription_plan_interval.py new file mode 100644 index 0000000..ffa978f --- /dev/null +++ b/src/webflow/types/sku_field_data_ec_sku_subscription_plan_interval.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +import enum +import typing + +T_Result = typing.TypeVar("T_Result") + + +class SkuFieldDataEcSkuSubscriptionPlanInterval(str, enum.Enum): + """ + Interval of subscription renewal + """ + + DAY = "day" + WEEK = "week" + MONTH = "month" + YEAR = "year" + + def visit( + self, + day: typing.Callable[[], T_Result], + week: typing.Callable[[], T_Result], + month: typing.Callable[[], T_Result], + year: typing.Callable[[], T_Result], + ) -> T_Result: + if self is SkuFieldDataEcSkuSubscriptionPlanInterval.DAY: + return day() + if self is SkuFieldDataEcSkuSubscriptionPlanInterval.WEEK: + return week() + if self is SkuFieldDataEcSkuSubscriptionPlanInterval.MONTH: + return month() + if self is SkuFieldDataEcSkuSubscriptionPlanInterval.YEAR: + return year() diff --git a/src/webflow/types/sku_field_data_price.py b/src/webflow/types/sku_field_data_price.py index 85621a3..a588035 100644 --- a/src/webflow/types/sku_field_data_price.py +++ b/src/webflow/types/sku_field_data_price.py @@ -16,8 +16,8 @@ class SkuFieldDataPrice(pydantic.BaseModel): price of SKU """ - value: typing.Optional[float] = pydantic.Field(description="Price of SKU") - unit: typing.Optional[str] = pydantic.Field(description="Currency of Item") + value: typing.Optional[float] = pydantic.Field(default=None, description="Price of SKU") + unit: typing.Optional[str] = pydantic.Field(default=None, description="Currency of Item") def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/sku_property_list.py b/src/webflow/types/sku_property_list.py index 014dd05..68acf4a 100644 --- a/src/webflow/types/sku_property_list.py +++ b/src/webflow/types/sku_property_list.py @@ -17,12 +17,10 @@ class SkuPropertyList(pydantic.BaseModel): A variant/option type for a SKU """ - id: typing.Optional[str] = pydantic.Field( - description="Unique identifier for a collection of Product options/Variants" - ) - name: typing.Optional[str] = pydantic.Field(description="Name of the collection of Product options/Variants") - enum: typing.Optional[typing.List[SkuPropertyListEnumItem]] = pydantic.Field( - description="The individual Product variants/Options that are contained within the collection" + id: str = pydantic.Field(description="Unique identifier for a collection of Product Variants") + name: str = pydantic.Field(description="Name of the collection of Product Variants") + enum: typing.List[SkuPropertyListEnumItem] = pydantic.Field( + description="The individual Product variants that are contained within the collection" ) def json(self, **kwargs: typing.Any) -> str: diff --git a/src/webflow/types/sku_property_list_enum_item.py b/src/webflow/types/sku_property_list_enum_item.py index 1810ab3..e995e4a 100644 --- a/src/webflow/types/sku_property_list_enum_item.py +++ b/src/webflow/types/sku_property_list_enum_item.py @@ -16,11 +16,9 @@ class SkuPropertyListEnumItem(pydantic.BaseModel): Enumerated Product variants/Options for the SKU """ - id: typing.Optional[str] = pydantic.Field(description="Unique identifier for a Product variant/Option") - name: typing.Optional[str] = pydantic.Field(description="Name of the Product variant/Option") - slug: typing.Optional[str] = pydantic.Field( - description="Slug for the Product variant/Option in the Site URL structure" - ) + id: str = pydantic.Field(description="Unique identifier for a Product variant/Option") + name: str = pydantic.Field(description="Name of the Product variant/Option") + slug: str = pydantic.Field(description="Slug for the Product variant/Option in the Site URL structure") def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/stripe_card.py b/src/webflow/types/stripe_card.py index 55a3b65..deb17d0 100644 --- a/src/webflow/types/stripe_card.py +++ b/src/webflow/types/stripe_card.py @@ -19,11 +19,17 @@ class StripeCard(pydantic.BaseModel): """ last_4: typing.Optional[str] = pydantic.Field( - alias="last4", description="The last 4 digits on the card as a string" + alias="last4", default=None, description="The last 4 digits on the card as a string" + ) + brand: typing.Optional[StripeCardBrand] = pydantic.Field( + default=None, description="The card's brand (ie. credit card network)" + ) + owner_name: typing.Optional[str] = pydantic.Field( + alias="ownerName", default=None, description="The name on the card." + ) + expires: typing.Optional[StripeCardExpires] = pydantic.Field( + default=None, description="The card's expiration date." ) - brand: typing.Optional[StripeCardBrand] = pydantic.Field(description="The card's brand (ie. credit card network)") - owner_name: typing.Optional[str] = pydantic.Field(alias="ownerName", description="The name on the card.") - expires: typing.Optional[StripeCardExpires] = pydantic.Field(description="The card's expiration date.") def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/stripe_card_expires.py b/src/webflow/types/stripe_card_expires.py index de7c446..793f717 100644 --- a/src/webflow/types/stripe_card_expires.py +++ b/src/webflow/types/stripe_card_expires.py @@ -16,8 +16,8 @@ class StripeCardExpires(pydantic.BaseModel): The card's expiration date. """ - year: typing.Optional[float] = pydantic.Field(description="Year that the card expires") - month: typing.Optional[float] = pydantic.Field(description="Month that the card expires") + year: typing.Optional[float] = pydantic.Field(default=None, description="Year that the card expires") + month: typing.Optional[float] = pydantic.Field(default=None, description="Month that the card expires") def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/stripe_details.py b/src/webflow/types/stripe_details.py index d50b8bc..e71a90d 100644 --- a/src/webflow/types/stripe_details.py +++ b/src/webflow/types/stripe_details.py @@ -17,28 +17,28 @@ class StripeDetails(pydantic.BaseModel): """ subscription_id: typing.Optional[str] = pydantic.Field( - alias="subscriptionId", description="Stripe-generated identifier for the Subscription" + alias="subscriptionId", default=None, description="Stripe-generated identifier for the Subscription" ) payment_method: typing.Optional[str] = pydantic.Field( - alias="paymentMethod", description="Stripe-generated identifier for the PaymentMethod used" + alias="paymentMethod", default=None, description="Stripe-generated identifier for the PaymentMethod used" ) payment_intent_id: typing.Optional[str] = pydantic.Field( - alias="paymentIntentId", description="Stripe-generated identifier for the PaymentIntent, or null" + alias="paymentIntentId", default=None, description="Stripe-generated identifier for the PaymentIntent, or null" ) customer_id: typing.Optional[str] = pydantic.Field( - alias="customerId", description="Stripe-generated customer identifier, or null" + alias="customerId", default=None, description="Stripe-generated customer identifier, or null" ) charge_id: typing.Optional[str] = pydantic.Field( - alias="chargeId", description="Stripe-generated charge identifier, or null" + alias="chargeId", default=None, description="Stripe-generated charge identifier, or null" ) dispute_id: typing.Optional[str] = pydantic.Field( - alias="disputeId", description="Stripe-generated dispute identifier, or null" + alias="disputeId", default=None, description="Stripe-generated dispute identifier, or null" ) refund_id: typing.Optional[str] = pydantic.Field( - alias="refundId", description="Stripe-generated refund identifier, or null" + alias="refundId", default=None, description="Stripe-generated refund identifier, or null" ) refund_reason: typing.Optional[str] = pydantic.Field( - alias="refundReason", description="Stripe-generated refund reason, or null" + alias="refundReason", default=None, description="Stripe-generated refund reason, or null" ) def json(self, **kwargs: typing.Any) -> str: diff --git a/src/webflow/types/text_node.py b/src/webflow/types/text_node.py new file mode 100644 index 0000000..e0b9aac --- /dev/null +++ b/src/webflow/types/text_node.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +from ..core.datetime_utils import serialize_datetime + +try: + import pydantic.v1 as pydantic # type: ignore +except ImportError: + import pydantic # type: ignore + + +class TextNode(pydantic.BaseModel): + """ + Represents textual content within the DOM. It contains both the raw text and its HTML representation, allowing for flexibility in rendering and processing. Additional attributes can be associated with the text for styling or other purposes. + """ + + html: typing.Optional[str] = None + text: typing.Optional[str] = None + + def json(self, **kwargs: typing.Any) -> str: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().json(**kwargs_with_defaults) + + def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]: + kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} + return super().dict(**kwargs_with_defaults) + + class Config: + frozen = True + smart_union = True + json_encoders = {dt.datetime: serialize_datetime} diff --git a/src/webflow/types/user.py b/src/webflow/types/user.py index d3584d7..ec54559 100644 --- a/src/webflow/types/user.py +++ b/src/webflow/types/user.py @@ -19,27 +19,27 @@ class User(pydantic.BaseModel): The fields that define the schema for a given Item are based on the Collection that Item belongs to. Beyond the user defined fields, there are a handful of additional fields that are automatically created for all items """ - id: typing.Optional[str] = pydantic.Field(description="Unique identifier for the User") + id: typing.Optional[str] = pydantic.Field(default=None, description="Unique identifier for the User") is_email_verified: typing.Optional[bool] = pydantic.Field( - alias="isEmailVerified", description="Shows whether the user has verified their email address" + alias="isEmailVerified", default=None, description="Shows whether the user has verified their email address" ) last_updated: typing.Optional[dt.datetime] = pydantic.Field( - alias="lastUpdated", description="The timestamp the user was updated" + alias="lastUpdated", default=None, description="The timestamp the user was updated" ) invited_on: typing.Optional[dt.datetime] = pydantic.Field( - alias="invitedOn", description="The timestamp the user was invited" + alias="invitedOn", default=None, description="The timestamp the user was invited" ) created_on: typing.Optional[dt.datetime] = pydantic.Field( - alias="createdOn", description="The timestamp the user was created" + alias="createdOn", default=None, description="The timestamp the user was created" ) last_login: typing.Optional[dt.datetime] = pydantic.Field( - alias="lastLogin", description="The timestamp the user was logged in" + alias="lastLogin", default=None, description="The timestamp the user was logged in" ) - status: typing.Optional[UserStatus] = pydantic.Field(description="The status of the user") + status: typing.Optional[UserStatus] = pydantic.Field(default=None, description="The status of the user") access_groups: typing.Optional[typing.List[UserAccessGroupsItem]] = pydantic.Field( - alias="accessGroups", description="Access groups the user belongs to" + alias="accessGroups", default=None, description="Access groups the user belongs to" ) - data: typing.Optional[UserData] + data: typing.Optional[UserData] = None def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/user_access_groups_item.py b/src/webflow/types/user_access_groups_item.py index de10a91..7eeb0f7 100644 --- a/src/webflow/types/user_access_groups_item.py +++ b/src/webflow/types/user_access_groups_item.py @@ -17,14 +17,15 @@ class UserAccessGroupsItem(pydantic.BaseModel): Access group slugs and types """ - slug: typing.Optional[str] = pydantic.Field(description="Access group identifier for APIs") + slug: typing.Optional[str] = pydantic.Field(default=None, description="Access group identifier for APIs") type: typing.Optional[UserAccessGroupsItemType] = pydantic.Field( + default=None, description=( "The type of access group based on how it was assigned to the user.\n" "\n" "- `admin` - Assigned to the user via API or in the designer\n" "- `ecommerce` - Assigned to the user via an ecommerce purchase\n" - ) + ), ) def json(self, **kwargs: typing.Any) -> str: diff --git a/src/webflow/types/user_data.py b/src/webflow/types/user_data.py index 4021796..d28d82e 100644 --- a/src/webflow/types/user_data.py +++ b/src/webflow/types/user_data.py @@ -17,7 +17,7 @@ class UserData(pydantic.BaseModel): An object containing the User's basic info and custom fields """ - data: typing.Optional[UserDataData] + data: typing.Optional[UserDataData] = None def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/user_data_data.py b/src/webflow/types/user_data_data.py index 8177134..b58ade7 100644 --- a/src/webflow/types/user_data_data.py +++ b/src/webflow/types/user_data_data.py @@ -12,17 +12,20 @@ class UserDataData(pydantic.BaseModel): - name: typing.Optional[str] = pydantic.Field(description="The name of the user") - email: typing.Optional[str] = pydantic.Field(description="The email address of the user") + name: typing.Optional[str] = pydantic.Field(default=None, description="The name of the user") + email: typing.Optional[str] = pydantic.Field(default=None, description="The email address of the user") accept_privacy: typing.Optional[bool] = pydantic.Field( - alias="accept-privacy", description="Boolean indicating if the user has accepted the privacy policy" + alias="accept-privacy", + default=None, + description="Boolean indicating if the user has accepted the privacy policy", ) accept_communications: typing.Optional[bool] = pydantic.Field( alias="accept-communications", + default=None, description="Boolean indicating if the user has accepted to receive communications", ) additional_properties: typing.Optional[str] = pydantic.Field( - alias="additionalProperties", description="Custom user attributes" + alias="additionalProperties", default=None, description="Custom user attributes" ) def json(self, **kwargs: typing.Any) -> str: diff --git a/src/webflow/types/user_limit_reached.py b/src/webflow/types/user_limit_reached.py index c3b4f63..90f4189 100644 --- a/src/webflow/types/user_limit_reached.py +++ b/src/webflow/types/user_limit_reached.py @@ -3,8 +3,6 @@ import datetime as dt import typing -import typing_extensions - from ..core.datetime_utils import serialize_datetime from .error_details_item import ErrorDetailsItem @@ -15,12 +13,14 @@ class UserLimitReached(pydantic.BaseModel): - code: typing.Optional[typing_extensions.Literal["user_limit_reached"]] - message: typing.Optional[str] = pydantic.Field(description="Error message") + code: typing.Optional[typing.Literal["user_limit_reached"]] = None + message: typing.Optional[str] = pydantic.Field(default=None, description="Error message") external_reference: typing.Optional[str] = pydantic.Field( - alias="externalReference", description="Link to more information" + alias="externalReference", default=None, description="Link to more information" + ) + details: typing.Optional[typing.List[ErrorDetailsItem]] = pydantic.Field( + default=None, description="Array of errors" ) - details: typing.Optional[typing.List[ErrorDetailsItem]] = pydantic.Field(description="Array of errors") def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/user_list.py b/src/webflow/types/user_list.py index 4f002bb..5c2b5a2 100644 --- a/src/webflow/types/user_list.py +++ b/src/webflow/types/user_list.py @@ -17,11 +17,11 @@ class UserList(pydantic.BaseModel): The list users results """ - count: typing.Optional[float] = pydantic.Field(description="Number of users returned") - limit: typing.Optional[float] = pydantic.Field(description="The limit specified in the request") - offset: typing.Optional[float] = pydantic.Field(description="The offset specified for pagination") - total: typing.Optional[float] = pydantic.Field(description="Total number of users in the collection") - users: typing.Optional[typing.List[User]] = pydantic.Field(description="List of Users for a Site") + count: typing.Optional[float] = pydantic.Field(default=None, description="Number of users returned") + limit: typing.Optional[float] = pydantic.Field(default=None, description="The limit specified in the request") + offset: typing.Optional[float] = pydantic.Field(default=None, description="The offset specified for pagination") + total: typing.Optional[float] = pydantic.Field(default=None, description="Total number of users in the collection") + users: typing.Optional[typing.List[User]] = pydantic.Field(default=None, description="List of Users for a Site") def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/user_webhook_payload.py b/src/webflow/types/user_webhook_payload.py index 436ed51..f2735f0 100644 --- a/src/webflow/types/user_webhook_payload.py +++ b/src/webflow/types/user_webhook_payload.py @@ -15,9 +15,9 @@ class UserWebhookPayload(pydantic.BaseModel): trigger_type: typing.Optional[UserWebhookPayloadTriggerType] = pydantic.Field( - alias="triggerType", description="The type of event that triggered the request" + alias="triggerType", default=None, description="The type of event that triggered the request" ) - payload: typing.Optional[User] + payload: typing.Optional[User] = None def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/users_not_enabled.py b/src/webflow/types/users_not_enabled.py index 7053e95..b2717e4 100644 --- a/src/webflow/types/users_not_enabled.py +++ b/src/webflow/types/users_not_enabled.py @@ -3,8 +3,6 @@ import datetime as dt import typing -import typing_extensions - from ..core.datetime_utils import serialize_datetime from .error_details_item import ErrorDetailsItem @@ -15,12 +13,14 @@ class UsersNotEnabled(pydantic.BaseModel): - code: typing.Optional[typing_extensions.Literal["users_not_enabled"]] - message: typing.Optional[str] = pydantic.Field(description="Error message") + code: typing.Optional[typing.Literal["users_not_enabled"]] = None + message: typing.Optional[str] = pydantic.Field(default=None, description="Error message") external_reference: typing.Optional[str] = pydantic.Field( - alias="externalReference", description="Link to more information" + alias="externalReference", default=None, description="Link to more information" + ) + details: typing.Optional[typing.List[ErrorDetailsItem]] = pydantic.Field( + default=None, description="Array of errors" ) - details: typing.Optional[typing.List[ErrorDetailsItem]] = pydantic.Field(description="Array of errors") def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/webhook.py b/src/webflow/types/webhook.py index 754ba47..29dff3c 100644 --- a/src/webflow/types/webhook.py +++ b/src/webflow/types/webhook.py @@ -13,24 +13,29 @@ class Webhook(pydantic.BaseModel): - id: typing.Optional[str] = pydantic.Field(description="Unique identifier for the Webhook registration") + id: typing.Optional[str] = pydantic.Field( + default=None, description="Unique identifier for the Webhook registration" + ) workspace_id: typing.Optional[str] = pydantic.Field( - alias="workspaceId", description="Unique identifier for the Workspace the Webhook is registered in" + alias="workspaceId", + default=None, + description="Unique identifier for the Workspace the Webhook is registered in", ) site_id: typing.Optional[str] = pydantic.Field( - alias="siteId", description="Unique identifier for the Site the Webhook is registered in" + alias="siteId", default=None, description="Unique identifier for the Site the Webhook is registered in" ) - trigger_type: typing.Optional[TriggerType] = pydantic.Field(alias="triggerType") + trigger_type: typing.Optional[TriggerType] = pydantic.Field(alias="triggerType", default=None) filter: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field( - description="Filter for selecting which events you want Webhooks to be sent for. Only supported for form_submission trigger types." + default=None, + description="Filter for selecting which events you want Webhooks to be sent for. Only supported for form_submission trigger types.", ) last_triggered: typing.Optional[dt.datetime] = pydantic.Field( - alias="lastTriggered", description="Date the Webhook instance was last triggered" + alias="lastTriggered", default=None, description="Date the Webhook instance was last triggered" ) created_on: typing.Optional[dt.datetime] = pydantic.Field( - alias="createdOn", description="Date the Webhook registration was created" + alias="createdOn", default=None, description="Date the Webhook registration was created" ) - url: typing.Optional[str] = pydantic.Field(description="URL to send the Webhook payload to") + url: typing.Optional[str] = pydantic.Field(default=None, description="URL to send the Webhook payload to") def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs} diff --git a/src/webflow/types/webhook_list.py b/src/webflow/types/webhook_list.py index 363abca..62f5dd2 100644 --- a/src/webflow/types/webhook_list.py +++ b/src/webflow/types/webhook_list.py @@ -14,8 +14,8 @@ class WebhookList(pydantic.BaseModel): - pagination: typing.Optional[Pagination] - webhooks: typing.Optional[typing.List[Webhook]] + pagination: typing.Optional[Pagination] = None + webhooks: typing.Optional[typing.List[Webhook]] = None def json(self, **kwargs: typing.Any) -> str: kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs}