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="