Merge pull request #1122 from useautumn/dev

This commit is contained in:
amianthus
2026-03-28 14:11:37 +00:00
committed by GitHub
100 changed files with 1822 additions and 1570 deletions

View File

@@ -154,6 +154,9 @@ When grouping is specified, `values` contains the total sum while `grouped_value
</Expandable>
</DynamicParamField>
<DynamicParamField body="filter_by.{key}" type="string">
Filter events by property values, e.g. \{"model": "gpt-4", "region": "us"\}. Maximum 5 filters.
</DynamicParamField>
<DynamicParamField body="max_groups" type="integer">
Maximum number of distinct group values to return per time bin when using group_by. Remaining values are bundled into an 'Other' bucket. Defaults to 9
</DynamicParamField>

View File

@@ -12376,6 +12376,14 @@ paths:
- end
description: Custom time range to aggregate events for. If provided, range must
not be provided
filter_by:
type: object
propertyNames:
type: string
additionalProperties:
type: string
description: 'Filter events by property values, e.g. {"model": "gpt-4",
"region": "us"}. Maximum 5 filters.'
max_groups:
type: integer
minimum: 1

View File

@@ -248,7 +248,7 @@
"@eslint/js": "^9.26.0",
"eslint": "^9.26.0",
"globals": "^15.14.0",
"tshy": "^2.0.0",
"tshy": "^3.3.2",
"typescript": "~5.8.3",
"typescript-eslint": "^8.26.0",
},
@@ -3268,7 +3268,7 @@
"for-each": ["for-each@0.3.5", "", { "dependencies": { "is-callable": "^1.2.7" } }, "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg=="],
"foreground-child": ["foreground-child@3.3.1", "", { "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" } }, "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw=="],
"foreground-child": ["foreground-child@4.0.3", "", { "dependencies": { "signal-exit": "^4.0.1" } }, "sha512-yeXZaNbCBGaT9giTpLPBdtedzjwhlJBUoL/R4BVQU5mn0TQXOHwVIl1Q2DMuBIdNno4ktA1abZ7dQFVxD6uHxw=="],
"form-data": ["form-data@4.0.5", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" } }, "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w=="],
@@ -3766,6 +3766,8 @@
"jsonc-parser": ["jsonc-parser@2.2.1", "", {}, "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w=="],
"jsonc-simple-parser": ["jsonc-simple-parser@3.0.0", "", { "dependencies": { "reghex": "^3.0.2" } }, "sha512-0qi9Kuj4JPar4/3b9wZteuPZrTeFzXsQyOZj7hksnReCZN3Vr17Doz7w/i3E9XH7vRkVTHhHES+r1h97I+hfww=="],
"jsonfile": ["jsonfile@6.2.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg=="],
"jsonpath-plus": ["jsonpath-plus@10.4.0", "", { "dependencies": { "@jsep-plugin/assignment": "^1.3.0", "@jsep-plugin/regex": "^1.0.4", "jsep": "^1.4.0" }, "bin": { "jsonpath": "bin/jsonpath-cli.js", "jsonpath-plus": "bin/jsonpath-cli.js" } }, "sha512-T92WWatJXmhBbKsgH/0hl+jxjdXrifi5IKeMY02DWggRxX0UElcbVzPlmgLTbvsPeW1PasQ6xE2Q75stkhGbsA=="],
@@ -4610,6 +4612,8 @@
"regexpp": ["regexpp@3.2.0", "", {}, "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg=="],
"reghex": ["reghex@3.0.2", "", {}, "sha512-Zb9DJ5u6GhgqRSBnxV2QSnLqEwcKxHWFA1N2yUa4ZUAO1P8jlWKYtWZ6/ooV6yylspGXJX0O/uNzEv0xrCtwaA=="],
"rehype-harden": ["rehype-harden@1.1.8", "", { "dependencies": { "unist-util-visit": "^5.0.0" } }, "sha512-Qn7vR1xrf6fZCrkm9TDWi/AB4ylrHy+jqsNm1EHOAmbARYA6gsnVJBq/sdBh6kmT4NEZxH5vgIjrscefJAOXcw=="],
"rehype-katex": ["rehype-katex@7.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/katex": "^0.16.0", "hast-util-from-html-isomorphic": "^2.0.0", "hast-util-to-text": "^4.0.0", "katex": "^0.16.0", "unist-util-visit-parents": "^6.0.0", "vfile": "^6.0.0" } }, "sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA=="],
@@ -4676,7 +4680,7 @@
"resolve-from": ["resolve-from@5.0.0", "", {}, "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="],
"resolve-import": ["resolve-import@1.4.6", "", { "dependencies": { "glob": "^10.3.3", "walk-up-path": "^3.0.1" } }, "sha512-CIw9e64QcKcCFUj9+KxUCJPy8hYofv6eVfo3U9wdhCm2E4IjvFnZ6G4/yIC4yP3f11+h6uU5b3LdS7O64LgqrA=="],
"resolve-import": ["resolve-import@2.4.0", "", { "dependencies": { "glob": "^13.0.0", "walk-up-path": "^4.0.0" } }, "sha512-gLWKdA5tiv5j/D7ipR47u3ovbVfzFPrctTdw2Ulnpmr6PPVVSvPKGNWu09jXVNlOSLLAeD6CA13bjIelpWttSw=="],
"resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="],
@@ -4700,7 +4704,7 @@
"rfdc": ["rfdc@1.4.1", "", {}, "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="],
"rimraf": ["rimraf@5.0.10", "", { "dependencies": { "glob": "^10.3.7" }, "bin": { "rimraf": "dist/esm/bin.mjs" } }, "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ=="],
"rimraf": ["rimraf@6.1.3", "", { "dependencies": { "glob": "^13.0.3", "package-json-from-dist": "^1.0.1" }, "bin": { "rimraf": "dist/esm/bin.mjs" } }, "sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA=="],
"robust-predicates": ["robust-predicates@3.0.3", "", {}, "sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA=="],
@@ -4950,7 +4954,7 @@
"swr": ["swr@2.4.1", "", { "dependencies": { "dequal": "^2.0.3", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { "react": "^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-2CC6CiKQtEwaEeNiqWTAw9PGykW8SR5zZX8MZk6TeAvEAnVS7Visz8WzphqgtQ8v2xz/4Q5K+j+SeMaKXeeQIA=="],
"sync-content": ["sync-content@1.0.2", "", { "dependencies": { "glob": "^10.2.6", "mkdirp": "^3.0.1", "path-scurry": "^1.9.2", "rimraf": "^5.0.1" }, "bin": { "sync-content": "dist/mjs/bin.mjs" } }, "sha512-znd3rYiiSxU3WteWyS9a6FXkTA/Wjk8WQsOyzHbineeL837dLn3DA4MRhsIX3qGcxDMH6+uuFV4axztssk7wEQ=="],
"sync-content": ["sync-content@2.0.4", "", { "dependencies": { "glob": "^13.0.1", "mkdirp": "^3.0.1", "path-scurry": "^2.0.0", "rimraf": "^6.0.0" }, "bin": { "sync-content": "dist/esm/bin.mjs" } }, "sha512-w3ioiBmbaogob33WdLnuwFk+8tpePI58CTWKqtdAgEqc2hfGuSwP02gPETqNX/3PLS5skv5a1wQR0gbaa2W0XQ=="],
"system-architecture": ["system-architecture@0.1.0", "", {}, "sha512-ulAk51I9UVUyJgxlv9M6lFot2WP3e7t8Kz9+IS6D4rVba1tR9kON+Ey69f+1R4Q8cd45Lod6a4IcJIxnzGc/zA=="],
@@ -5106,7 +5110,7 @@
"tsconfig-paths": ["tsconfig-paths@4.2.0", "", { "dependencies": { "json5": "^2.2.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } }, "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg=="],
"tshy": ["tshy@2.0.1", "", { "dependencies": { "chalk": "^5.3.0", "chokidar": "^3.6.0", "foreground-child": "^3.1.1", "minimatch": "^9.0.4", "mkdirp": "^3.0.1", "polite-json": "^5.0.0", "resolve-import": "^1.4.5", "rimraf": "^5.0.1", "sync-content": "^1.0.2", "typescript": "5", "walk-up-path": "^3.0.1" }, "bin": { "tshy": "dist/esm/index.js" } }, "sha512-U5fC+3pMaGfmULhPTVpxKMd62AcX13yfsFrjhAP/daTLG6LFRLIuxqYOmkejJ4MT/s5bEa29+1Jy/9mXkMiMfA=="],
"tshy": ["tshy@3.3.2", "", { "dependencies": { "@typescript/native-preview": "^7.0.0-dev.20260218.1", "chalk": "^5.6.2", "chokidar": "^4.0.3", "foreground-child": "^4.0.0", "jsonc-simple-parser": "^3.0.0", "minimatch": "^10.0.3", "mkdirp": "^3.0.1", "polite-json": "^5.0.0", "resolve-import": "^2.4.0", "rimraf": "^6.1.2", "sync-content": "^2.0.3", "typescript": "^5.9.3", "walk-up-path": "^4.0.0" }, "bin": { "tshy": "dist/esm/bin-min.mjs" } }, "sha512-vOIXkqMtBWNjKUR/c99+6N50LhWdnKG1xE3+5wf8IPdzxx2lcIFPvbGgFdBBgoTMbdNb8mz06MUm7hY+TFnJcw=="],
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
@@ -5272,7 +5276,7 @@
"walk-sync": ["walk-sync@0.2.7", "", { "dependencies": { "ensure-posix-path": "^1.0.0", "matcher-collection": "^1.0.0" } }, "sha512-OH8GdRMowEFr0XSHQeX5fGweO6zSVHo7bG/0yJQx6LAj9Oukz0C8heI3/FYectT66gY0IPGe89kOvU410/UNpg=="],
"walk-up-path": ["walk-up-path@3.0.1", "", {}, "sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA=="],
"walk-up-path": ["walk-up-path@4.0.0", "", {}, "sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A=="],
"watchpack": ["watchpack@2.5.1", "", { "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" } }, "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg=="],
@@ -6486,6 +6490,8 @@
"get-uri/data-uri-to-buffer": ["data-uri-to-buffer@6.0.2", "", {}, "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw=="],
"glob/foreground-child": ["foreground-child@3.3.1", "", { "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" } }, "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw=="],
"globby/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
"hosted-git-info/lru-cache": ["lru-cache@7.18.3", "", {}, "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA=="],
@@ -6718,6 +6724,10 @@
"requirejs-config-file/stringify-object": ["stringify-object@3.3.0", "", { "dependencies": { "get-own-enumerable-property-symbols": "^3.0.0", "is-obj": "^1.0.1", "is-regexp": "^1.0.0" } }, "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw=="],
"resolve-import/glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="],
"rimraf/glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="],
"router/path-to-regexp": ["path-to-regexp@8.3.0", "", {}, "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA=="],
"run-jxa/execa": ["execa@5.1.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", "human-signals": "^2.1.0", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^4.0.1", "onetime": "^5.1.2", "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" } }, "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg=="],
@@ -6784,6 +6794,10 @@
"supports-hyperlinks/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
"sync-content/glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="],
"sync-content/path-scurry": ["path-scurry@2.0.2", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg=="],
"tar/chownr": ["chownr@2.0.0", "", {}, "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="],
"tar/minipass": ["minipass@5.0.0", "", {}, "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ=="],
@@ -6808,7 +6822,9 @@
"tsc-alias/commander": ["commander@9.5.0", "", {}, "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ=="],
"tshy/chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="],
"tshy/@typescript/native-preview": ["@typescript/native-preview@7.0.0-dev.20260326.1", "", { "optionalDependencies": { "@typescript/native-preview-darwin-arm64": "7.0.0-dev.20260326.1", "@typescript/native-preview-darwin-x64": "7.0.0-dev.20260326.1", "@typescript/native-preview-linux-arm": "7.0.0-dev.20260326.1", "@typescript/native-preview-linux-arm64": "7.0.0-dev.20260326.1", "@typescript/native-preview-linux-x64": "7.0.0-dev.20260326.1", "@typescript/native-preview-win32-arm64": "7.0.0-dev.20260326.1", "@typescript/native-preview-win32-x64": "7.0.0-dev.20260326.1" }, "bin": { "tsgo": "bin/tsgo.js" } }, "sha512-oq2UShxAa+CS4aalhQjntuxuzTv/ud54So3lqfYcJDiQabmpGk/95rGvW5PXi28JIBlZ6AbUL6gEj0gRvIDJcQ=="],
"tshy/minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="],
"tsutils/tslib": ["tslib@1.14.1", "", {}, "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="],
@@ -7986,6 +8002,8 @@
"fs-minipass/minipass/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="],
"glob/foreground-child/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="],
"ink-confirm-input/ink-text-input/chalk": ["chalk@3.0.0", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg=="],
"ink-confirm-input/ink-text-input/ink": ["ink@6.8.0", "", { "dependencies": { "@alcalzone/ansi-tokenize": "^0.2.4", "ansi-escapes": "^7.3.0", "ansi-styles": "^6.2.1", "auto-bind": "^5.0.1", "chalk": "^5.6.0", "cli-boxes": "^3.0.0", "cli-cursor": "^4.0.0", "cli-truncate": "^5.1.1", "code-excerpt": "^4.0.0", "es-toolkit": "^1.39.10", "indent-string": "^5.0.0", "is-in-ci": "^2.0.0", "patch-console": "^2.0.0", "react-reconciler": "^0.33.0", "scheduler": "^0.27.0", "signal-exit": "^3.0.7", "slice-ansi": "^8.0.0", "stack-utils": "^2.0.6", "string-width": "^8.1.1", "terminal-size": "^4.0.1", "type-fest": "^5.4.1", "widest-line": "^6.0.0", "wrap-ansi": "^9.0.0", "ws": "^8.18.0", "yoga-layout": "~3.2.1" }, "peerDependencies": { "@types/react": ">=19.0.0", "react": ">=19.0.0", "react-devtools-core": ">=6.1.2" }, "optionalPeers": ["@types/react", "react-devtools-core"] }, "sha512-sbl1RdLOgkO9isK42WCZlJCFN9hb++sX9dsklOvfd1YQ3bQ2AiFu12Q6tFlr0HvEUvzraJntQCCpfEoUe9DSzA=="],
@@ -8156,6 +8174,8 @@
"puppeteer/puppeteer-core/chromium-bidi": ["chromium-bidi@0.6.2", "", { "dependencies": { "mitt": "3.0.1", "urlpattern-polyfill": "10.0.0", "zod": "3.23.8" }, "peerDependencies": { "devtools-protocol": "*" } }, "sha512-4WVBa6ijmUTVr9cZD4eicQD8Mdy/HCX3bzEIYYpmk0glqYLoWH+LqQEvV9RpDRzoQSbY1KJHloYXbDMXMbDPhg=="],
"react-email/glob/foreground-child": ["foreground-child@3.3.1", "", { "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" } }, "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw=="],
"react-email/glob/jackspeak": ["jackspeak@4.2.3", "", { "dependencies": { "@isaacs/cliui": "^9.0.0" } }, "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg=="],
"react-email/glob/minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="],
@@ -8184,6 +8204,14 @@
"requirejs-config-file/stringify-object/is-regexp": ["is-regexp@1.0.0", "", {}, "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA=="],
"resolve-import/glob/minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="],
"resolve-import/glob/path-scurry": ["path-scurry@2.0.2", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg=="],
"rimraf/glob/minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="],
"rimraf/glob/path-scurry": ["path-scurry@2.0.2", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg=="],
"run-jxa/execa/get-stream": ["get-stream@6.0.1", "", {}, "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg=="],
"run-jxa/execa/human-signals": ["human-signals@2.1.0", "", {}, "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw=="],
@@ -8256,15 +8284,29 @@
"string-width-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
"sync-content/glob/minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="],
"ts-to-zod/@clack/prompts/@clack/core": ["@clack/core@1.0.0-alpha.4", "", { "dependencies": { "picocolors": "^1.0.0", "sisteransi": "^1.0.5" } }, "sha512-VCtU+vjyKPMSakVrB9q1bOnXN7QW/w4+YQDQCOF59GrzydW+169i0fVx/qzRRXJgt8KGj/pZZ/JxXroFZIDByg=="],
"tsc-alias/chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
"tsc-alias/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="],
"tshy/chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
"tshy/@typescript/native-preview/@typescript/native-preview-darwin-arm64": ["@typescript/native-preview-darwin-arm64@7.0.0-dev.20260326.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-eEMQnArhP/9cLOR3kkShEmT2y1dUs/kHLpwOdEHFmkXwJ477V7P0eZEtabsF5xefU9GwF+cMw4cw60ANVGPgeA=="],
"tshy/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="],
"tshy/@typescript/native-preview/@typescript/native-preview-darwin-x64": ["@typescript/native-preview-darwin-x64@7.0.0-dev.20260326.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-lUjpUTe95X4pmxIJb354UY/+1/+0Zh3z0J9ekNSWhhWgZpqQQi5rS1C5BfSJbg2aH8OXYVaEFWzxddXc8qeILg=="],
"tshy/@typescript/native-preview/@typescript/native-preview-linux-arm": ["@typescript/native-preview-linux-arm@7.0.0-dev.20260326.1", "", { "os": "linux", "cpu": "arm" }, "sha512-w6jrOrAw9kDoFDToECXMEkYByxjK67FNXM96SzpoX0JRB0BwkdvVclKsYeZtiP9naaW0u7lzZdfh/h0Hw6euYw=="],
"tshy/@typescript/native-preview/@typescript/native-preview-linux-arm64": ["@typescript/native-preview-linux-arm64@7.0.0-dev.20260326.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-rhqnrDAeC1FhXuXDPQlcMULIvdlzerCc0cXJ16i18waLpZ1nr5ntvzhzzRx7+DvugemTGf2ximX6r/N9HRt+Ow=="],
"tshy/@typescript/native-preview/@typescript/native-preview-linux-x64": ["@typescript/native-preview-linux-x64@7.0.0-dev.20260326.1", "", { "os": "linux", "cpu": "x64" }, "sha512-F8aWt0EH8YBE3Xo2KwIcDwA0iiNq9CdV+z5/+tca70CU5HcfGJlY/c6u6UIM9ZYa1IFcykq0HMHv2FE1NAXdcw=="],
"tshy/@typescript/native-preview/@typescript/native-preview-win32-arm64": ["@typescript/native-preview-win32-arm64@7.0.0-dev.20260326.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-OQt93BgZbvkqHVYXH56gjQv2ZOchT4FvLwkwS6jei8t5zB2P4EXmnXA/WxMWwjpYNl4HGfEF/yRkPTfhmbODig=="],
"tshy/@typescript/native-preview/@typescript/native-preview-win32-x64": ["@typescript/native-preview-win32-x64@7.0.0-dev.20260326.1", "", { "os": "win32", "cpu": "x64" }, "sha512-hfK3cA8+TtFICHwIo898QHd5VjbixEpdL5QcPkq3GtxuRQl7ZJvQj5Fb64fejIpxI3QicwIKgJW1jJDFCPSGsw=="],
"tshy/minimatch/brace-expansion": ["brace-expansion@5.0.5", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ=="],
"type-is/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
@@ -8938,6 +8980,8 @@
"puppeteer/puppeteer-core/chromium-bidi/zod": ["zod@3.23.8", "", {}, "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g=="],
"react-email/glob/foreground-child/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="],
"react-email/glob/jackspeak/@isaacs/cliui": ["@isaacs/cliui@9.0.0", "", {}, "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg=="],
"react-email/glob/minimatch/brace-expansion": ["brace-expansion@5.0.5", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ=="],
@@ -8948,6 +8992,10 @@
"read-pkg-up/find-up/locate-path/p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="],
"resolve-import/glob/minimatch/brace-expansion": ["brace-expansion@5.0.5", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ=="],
"rimraf/glob/minimatch/brace-expansion": ["brace-expansion@5.0.5", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ=="],
"sdk-test/next/postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
"shadcn/cosmiconfig/js-yaml/argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
@@ -8956,9 +9004,11 @@
"shadcn/ora/log-symbols/is-unicode-supported": ["is-unicode-supported@1.3.0", "", {}, "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ=="],
"sync-content/glob/minimatch/brace-expansion": ["brace-expansion@5.0.5", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ=="],
"tsc-alias/chokidar/readdirp/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="],
"tshy/chokidar/readdirp/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="],
"tshy/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="],
"unplugin/chokidar/readdirp/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="],
@@ -9196,10 +9246,16 @@
"read-pkg-up/find-up/locate-path/p-locate/p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="],
"resolve-import/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="],
"rimraf/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="],
"shadcn/ora/cli-cursor/restore-cursor/onetime": ["onetime@7.0.0", "", { "dependencies": { "mimic-function": "^5.0.0" } }, "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ=="],
"shadcn/ora/cli-cursor/restore-cursor/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="],
"sync-content/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="],
"xo/eslint/file-entry-cache/flat-cache/rimraf": ["rimraf@3.0.2", "", { "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" } }, "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA=="],
"xo/find-up/locate-path/p-locate/p-limit": ["p-limit@4.0.0", "", { "dependencies": { "yocto-queue": "^1.0.0" } }, "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ=="],

File diff suppressed because it is too large Load Diff

View File

@@ -459,7 +459,8 @@ disable=raw-checker-failed,
consider-using-with,
wildcard-import,
unused-wildcard-import,
too-many-return-statements
too-many-return-statements,
redefined-builtin
# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option

View File

@@ -5,8 +5,8 @@ import importlib.metadata
__title__: str = "autumn-sdk"
__version__: str = "0.4.18"
__openapi_doc_version__: str = "2.2.0"
__gen_version__: str = "2.824.1"
__user_agent__: str = "speakeasy-sdk/python 0.4.18 2.824.1 2.2.0 autumn-sdk"
__gen_version__: str = "2.869.25"
__user_agent__: str = "speakeasy-sdk/python 0.4.18 2.869.25 2.2.0 autumn-sdk"
try:
if __package__ is not None:

View File

@@ -225,7 +225,7 @@ class BaseSDK:
data=serialized_request_body.data,
files=serialized_request_body.files,
headers=headers,
timeout=timeout,
timeout=timeout if timeout is not None else httpx.USE_CLIENT_DEFAULT,
)
def do_request(
@@ -245,6 +245,8 @@ class BaseSDK:
http_res = None
try:
req = hooks.before_request(BeforeRequestContext(hook_ctx), request)
if "timeout" in request.extensions and "timeout" not in req.extensions:
req.extensions["timeout"] = request.extensions["timeout"]
logger.debug(
"Request:\nMethod: %s\nURL: %s\nHeaders: %s\nBody: %s",
req.method,
@@ -322,6 +324,8 @@ class BaseSDK:
hooks.before_request, BeforeRequestContext(hook_ctx), request
)
if "timeout" in request.extensions and "timeout" not in req.extensions:
req.extensions["timeout"] = request.extensions["timeout"]
logger.debug(
"Request:\nMethod: %s\nURL: %s\nHeaders: %s\nBody: %s",
req.method,

View File

@@ -1,10 +1,9 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from .autumnerror import AutumnError
from typing import TYPE_CHECKING
from importlib import import_module
import builtins
import sys
from typing import Any, TYPE_CHECKING
from autumn_sdk.utils.dynamic_imports import lazy_getattr, lazy_dir
if TYPE_CHECKING:
from .autumndefaulterror import AutumnDefaultError
@@ -25,39 +24,11 @@ _dynamic_imports: dict[str, str] = {
}
def dynamic_import(modname, retries=3):
for attempt in range(retries):
try:
return import_module(modname, __package__)
except KeyError:
# Clear any half-initialized module and retry
sys.modules.pop(modname, None)
if attempt == retries - 1:
break
raise KeyError(f"Failed to import module '{modname}' after {retries} attempts")
def __getattr__(attr_name: str) -> object:
module_name = _dynamic_imports.get(attr_name)
if module_name is None:
raise AttributeError(
f"No {attr_name} found in _dynamic_imports for module name -> {__name__} "
)
try:
module = dynamic_import(module_name)
result = getattr(module, attr_name)
return result
except ImportError as e:
raise ImportError(
f"Failed to import {attr_name} from {module_name}: {e}"
) from e
except AttributeError as e:
raise AttributeError(
f"Failed to get {attr_name} from {module_name}: {e}"
) from e
def __getattr__(attr_name: str) -> Any:
return lazy_getattr(
attr_name, package=__package__, dynamic_imports=_dynamic_imports
)
def __dir__():
lazy_attrs = builtins.list(_dynamic_imports.keys())
return builtins.sorted(lazy_attrs)
return lazy_dir(dynamic_imports=_dynamic_imports)

View File

@@ -5,7 +5,7 @@ from autumn_sdk import errors, models, utils
from autumn_sdk._hooks import HookContext
from autumn_sdk.types import OptionalNullable, UNSET
from autumn_sdk.utils.unmarshal_json_response import unmarshal_json_response
from typing import Mapping, Optional, Union
from typing import Dict, Mapping, Optional, Union
class Events(BaseSDK):
@@ -248,6 +248,7 @@ class Events(BaseSDK):
models.AggregateEventsCustomRangeTypedDict,
]
] = None,
filter_by: Optional[Dict[str, str]] = None,
max_groups: Optional[int] = None,
retries: OptionalNullable[utils.RetryConfig] = UNSET,
server_url: Optional[str] = None,
@@ -263,6 +264,7 @@ class Events(BaseSDK):
:param range: Time range to aggregate events for. Either range or custom_range must be provided
:param bin_size: Size of the time bins to aggregate events for. Defaults to hour if range is 24h, otherwise day
:param custom_range: Custom time range to aggregate events for. If provided, range must not be provided
:param filter_by: Filter events by property values, e.g. {\"model\": \"gpt-4\", \"region\": \"us\"}. Maximum 5 filters.
:param max_groups: Maximum number of distinct group values to return per time bin when using group_by. Remaining values are bundled into an 'Other' bucket. Defaults to 9
:param retries: Override the default retry configuration for this method
:param server_url: Override the default server URL for this method
@@ -289,6 +291,7 @@ class Events(BaseSDK):
custom_range=utils.get_pydantic_model(
custom_range, Optional[models.AggregateEventsCustomRange]
),
filter_by=filter_by,
max_groups=max_groups,
)
@@ -368,6 +371,7 @@ class Events(BaseSDK):
models.AggregateEventsCustomRangeTypedDict,
]
] = None,
filter_by: Optional[Dict[str, str]] = None,
max_groups: Optional[int] = None,
retries: OptionalNullable[utils.RetryConfig] = UNSET,
server_url: Optional[str] = None,
@@ -383,6 +387,7 @@ class Events(BaseSDK):
:param range: Time range to aggregate events for. Either range or custom_range must be provided
:param bin_size: Size of the time bins to aggregate events for. Defaults to hour if range is 24h, otherwise day
:param custom_range: Custom time range to aggregate events for. If provided, range must not be provided
:param filter_by: Filter events by property values, e.g. {\"model\": \"gpt-4\", \"region\": \"us\"}. Maximum 5 filters.
:param max_groups: Maximum number of distinct group values to return per time bin when using group_by. Remaining values are bundled into an 'Other' bucket. Defaults to 9
:param retries: Override the default retry configuration for this method
:param server_url: Override the default server URL for this method
@@ -409,6 +414,7 @@ class Events(BaseSDK):
custom_range=utils.get_pydantic_model(
custom_range, Optional[models.AggregateEventsCustomRange]
),
filter_by=filter_by,
max_groups=max_groups,
)

View File

@@ -1,9 +1,8 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from typing import TYPE_CHECKING
from importlib import import_module
import builtins
import sys
from typing import Any, TYPE_CHECKING
from autumn_sdk.utils.dynamic_imports import lazy_getattr, lazy_dir
if TYPE_CHECKING:
from .aggregateeventsop import (
@@ -1278,6 +1277,7 @@ if TYPE_CHECKING:
UpdatePlanToTypedDict,
UpdatePlanType,
)
from . import internal
__all__ = [
"Action",
@@ -3671,40 +3671,17 @@ _dynamic_imports: dict[str, str] = {
"UpdatePlanType": ".updateplanop",
}
def dynamic_import(modname, retries=3):
for attempt in range(retries):
try:
return import_module(modname, __package__)
except KeyError:
# Clear any half-initialized module and retry
sys.modules.pop(modname, None)
if attempt == retries - 1:
break
raise KeyError(f"Failed to import module '{modname}' after {retries} attempts")
_sub_packages = ["internal"]
def __getattr__(attr_name: str) -> object:
module_name = _dynamic_imports.get(attr_name)
if module_name is None:
raise AttributeError(
f"No {attr_name} found in _dynamic_imports for module name -> {__name__} "
)
try:
module = dynamic_import(module_name)
result = getattr(module, attr_name)
return result
except ImportError as e:
raise ImportError(
f"Failed to import {attr_name} from {module_name}: {e}"
) from e
except AttributeError as e:
raise AttributeError(
f"Failed to get {attr_name} from {module_name}: {e}"
) from e
def __getattr__(attr_name: str) -> Any:
return lazy_getattr(
attr_name,
package=__package__,
dynamic_imports=_dynamic_imports,
sub_packages=_sub_packages,
)
def __dir__():
lazy_attrs = builtins.list(_dynamic_imports.keys())
return builtins.sorted(lazy_attrs)
return lazy_dir(dynamic_imports=_dynamic_imports, sub_packages=_sub_packages)

View File

@@ -28,7 +28,7 @@ class AggregateEventsGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -99,6 +99,8 @@ class EventsAggregateParamsTypedDict(TypedDict):
r"""Size of the time bins to aggregate events for. Defaults to hour if range is 24h, otherwise day"""
custom_range: NotRequired[AggregateEventsCustomRangeTypedDict]
r"""Custom time range to aggregate events for. If provided, range must not be provided"""
filter_by: NotRequired[Dict[str, str]]
r"""Filter events by property values, e.g. {\"model\": \"gpt-4\", \"region\": \"us\"}. Maximum 5 filters."""
max_groups: NotRequired[int]
r"""Maximum number of distinct group values to return per time bin when using group_by. Remaining values are bundled into an 'Other' bucket. Defaults to 9"""
@@ -125,6 +127,8 @@ class EventsAggregateParams(BaseModel):
custom_range: Optional[AggregateEventsCustomRange] = None
r"""Custom time range to aggregate events for. If provided, range must not be provided"""
filter_by: Optional[Dict[str, str]] = None
r"""Filter events by property values, e.g. {\"model\": \"gpt-4\", \"region\": \"us\"}. Maximum 5 filters."""
max_groups: Optional[int] = None
r"""Maximum number of distinct group values to return per time bin when using group_by. Remaining values are bundled into an 'Other' bucket. Defaults to 9"""
@@ -138,6 +142,7 @@ class EventsAggregateParams(BaseModel):
"range",
"bin_size",
"custom_range",
"filter_by",
"max_groups",
]
)
@@ -146,7 +151,7 @@ class EventsAggregateParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -182,7 +187,7 @@ class AggregateEventsList(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:

View File

@@ -35,7 +35,7 @@ class AttachGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -75,7 +75,7 @@ class AttachFeatureQuantity(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -126,7 +126,7 @@ class AttachBasePrice(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -175,7 +175,7 @@ class AttachReset(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -211,7 +211,7 @@ class AttachTier(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -307,7 +307,7 @@ class AttachPrice(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -392,7 +392,7 @@ class AttachRollover(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -454,7 +454,7 @@ class AttachPlanItem(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -502,7 +502,7 @@ class AttachFreeTrialParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -543,7 +543,7 @@ class AttachCustomize(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -591,7 +591,7 @@ class AttachInvoiceMode(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -641,7 +641,7 @@ class AttachAttachDiscount(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -698,7 +698,7 @@ class AttachCarryOverBalances(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -733,7 +733,7 @@ class AttachCarryOverUsages(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -875,7 +875,7 @@ class AttachParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -924,7 +924,7 @@ class AttachInvoice(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
m[k] = val
@@ -1004,7 +1004,7 @@ class AttachResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member

View File

@@ -67,7 +67,7 @@ class BalanceDisplay(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -140,7 +140,7 @@ class BalanceFeature(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -201,7 +201,7 @@ class BalanceReset(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -281,7 +281,7 @@ class BalancePrice(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -361,7 +361,7 @@ class Breakdown(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -461,7 +461,7 @@ class Balance(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member

View File

@@ -35,7 +35,7 @@ class BillingUpdateGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -75,7 +75,7 @@ class BillingUpdateFeatureQuantity(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -126,7 +126,7 @@ class BillingUpdateBasePrice(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -175,7 +175,7 @@ class BillingUpdateReset(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -211,7 +211,7 @@ class BillingUpdateTier(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -307,7 +307,7 @@ class BillingUpdatePrice(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -392,7 +392,7 @@ class BillingUpdateRollover(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -454,7 +454,7 @@ class BillingUpdatePlanItem(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -502,7 +502,7 @@ class BillingUpdateFreeTrialParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -543,7 +543,7 @@ class BillingUpdateCustomize(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -591,7 +591,7 @@ class BillingUpdateInvoiceMode(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -729,7 +729,7 @@ class UpdateSubscriptionParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -778,7 +778,7 @@ class BillingUpdateInvoice(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
m[k] = val
@@ -858,7 +858,7 @@ class BillingUpdateResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member

View File

@@ -37,7 +37,7 @@ class CheckGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -80,7 +80,7 @@ class CheckLock(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -150,7 +150,7 @@ class CheckParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -212,7 +212,7 @@ class FlagDisplay(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -285,7 +285,7 @@ class CheckFeature(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -332,7 +332,7 @@ class Flag(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -448,7 +448,7 @@ class ProductDisplay(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -496,7 +496,7 @@ class CheckRollover(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -558,7 +558,7 @@ class Config(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -717,7 +717,7 @@ class CheckItem(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -783,7 +783,7 @@ class CheckFreeTrial(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -855,7 +855,7 @@ class CheckProperties(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -953,7 +953,7 @@ class Product(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -1061,7 +1061,7 @@ class CheckResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member

View File

@@ -28,7 +28,7 @@ class CreateBalanceGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -77,7 +77,7 @@ class CreateBalanceReset(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -147,7 +147,7 @@ class CreateBalanceParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:

View File

@@ -38,7 +38,7 @@ class CreateEntityGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -74,7 +74,7 @@ class CreateEntitySpendLimitRequest(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -127,7 +127,7 @@ class CreateEntityUsageAlertRequestBody(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -162,7 +162,7 @@ class CreateEntityBillingControlsRequest(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -214,7 +214,7 @@ class CreateEntityParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -340,7 +340,7 @@ class CreateEntitySubscription(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -393,7 +393,7 @@ class CreateEntityPurchase(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -463,7 +463,7 @@ class CreateEntityDisplay(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -536,7 +536,7 @@ class CreateEntityFeature(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -583,7 +583,7 @@ class CreateEntityFlags(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -627,7 +627,7 @@ class CreateEntitySpendLimitResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -683,7 +683,7 @@ class CreateEntityUsageAlertResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -718,7 +718,7 @@ class CreateEntityBillingControlsResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -775,7 +775,7 @@ class CreateEntityInvoice(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -863,7 +863,7 @@ class CreateEntityResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member

View File

@@ -35,7 +35,7 @@ class CreateFeatureGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -123,7 +123,7 @@ class CreateFeatureParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -185,7 +185,7 @@ class CreateFeatureDisplayResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -258,7 +258,7 @@ class CreateFeatureResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:

View File

@@ -35,7 +35,7 @@ class CreatePlanGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -86,7 +86,7 @@ class CreatePlanPriceRequest(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -135,7 +135,7 @@ class CreatePlanResetRequest(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -171,7 +171,7 @@ class CreatePlanTier(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -267,7 +267,7 @@ class CreatePlanItemPriceRequest(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -352,7 +352,7 @@ class CreatePlanRolloverRequest(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -414,7 +414,7 @@ class CreatePlanPlanItem(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -462,7 +462,7 @@ class FreeTrialRequest(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -539,7 +539,7 @@ class CreatePlanParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -596,7 +596,7 @@ class CreatePlanPriceDisplay(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -637,7 +637,7 @@ class CreatePlanPriceResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -736,7 +736,7 @@ class CreatePlanFeature(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -792,7 +792,7 @@ class CreatePlanResetResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -885,7 +885,7 @@ class CreatePlanItemPriceResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -928,7 +928,7 @@ class CreatePlanItemDisplay(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -979,7 +979,7 @@ class CreatePlanRolloverResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -1049,7 +1049,7 @@ class CreatePlanItem(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -1171,7 +1171,7 @@ class CreatePlanCustomerEligibility(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -1270,7 +1270,7 @@ class CreatePlanResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member

View File

@@ -28,7 +28,7 @@ class CreateReferralCodeGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:

View File

@@ -69,7 +69,7 @@ class CustomerPurchaseLimit(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -115,7 +115,7 @@ class CustomerAutoTopup(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -151,7 +151,7 @@ class CustomerSpendLimit(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -207,7 +207,7 @@ class CustomerUsageAlert(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -247,7 +247,7 @@ class CustomerBillingControls(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -355,7 +355,7 @@ class Subscription(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -408,7 +408,7 @@ class Purchase(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -478,7 +478,7 @@ class CustomerDisplay(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -551,7 +551,7 @@ class CustomerFeature(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -598,7 +598,7 @@ class Flags(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -663,7 +663,7 @@ class Invoice(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -733,7 +733,7 @@ class Entity(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -772,7 +772,7 @@ class TrialsUsed(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -898,7 +898,7 @@ class Discount(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -947,7 +947,7 @@ class ReferralCustomer(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -1113,7 +1113,7 @@ class Customer(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member

View File

@@ -53,7 +53,7 @@ class CustomerDataPurchaseLimit(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -99,7 +99,7 @@ class CustomerDataAutoTopup(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -135,7 +135,7 @@ class CustomerDataSpendLimit(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -188,7 +188,7 @@ class CustomerDataUsageAlert(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -228,7 +228,7 @@ class CustomerDataBillingControls(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -311,7 +311,7 @@ class CustomerData(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member

View File

@@ -28,7 +28,7 @@ class DeleteBalanceGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -101,7 +101,7 @@ class DeleteBalanceParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:

View File

@@ -28,7 +28,7 @@ class DeleteCustomerGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -59,7 +59,7 @@ class DeleteCustomerParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:

View File

@@ -28,7 +28,7 @@ class DeleteEntityGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -59,7 +59,7 @@ class DeleteEntityParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:

View File

@@ -28,7 +28,7 @@ class DeleteFeatureGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:

View File

@@ -28,7 +28,7 @@ class DeletePlanGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -59,7 +59,7 @@ class DeletePlanParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:

View File

@@ -28,7 +28,7 @@ class FinalizeLockGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -76,7 +76,7 @@ class FinalizeBalanceParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:

View File

@@ -37,7 +37,7 @@ class GetEntityGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -68,7 +68,7 @@ class GetEntityParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -186,7 +186,7 @@ class GetEntitySubscription(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -239,7 +239,7 @@ class GetEntityPurchase(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -309,7 +309,7 @@ class GetEntityDisplay(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -382,7 +382,7 @@ class GetEntityFeature(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -429,7 +429,7 @@ class GetEntityFlags(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -473,7 +473,7 @@ class GetEntitySpendLimit(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -529,7 +529,7 @@ class GetEntityUsageAlert(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -564,7 +564,7 @@ class GetEntityBillingControls(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -621,7 +621,7 @@ class GetEntityInvoice(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -709,7 +709,7 @@ class GetEntityResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member

View File

@@ -35,7 +35,7 @@ class GetFeatureGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -107,7 +107,7 @@ class GetFeatureDisplay(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -180,7 +180,7 @@ class GetFeatureResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:

View File

@@ -34,7 +34,7 @@ class GetOrCreateCustomerGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -83,7 +83,7 @@ class GetOrCreateCustomerPurchaseLimit(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -129,7 +129,7 @@ class GetOrCreateCustomerAutoTopup(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -165,7 +165,7 @@ class GetOrCreateCustomerSpendLimit(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -218,7 +218,7 @@ class GetOrCreateCustomerUsageAlert(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -258,7 +258,7 @@ class GetOrCreateCustomerBillingControls(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -348,7 +348,7 @@ class GetOrCreateCustomerParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member

View File

@@ -35,7 +35,7 @@ class GetPlanGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -66,7 +66,7 @@ class GetPlanParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -115,7 +115,7 @@ class GetPlanPriceDisplay(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -156,7 +156,7 @@ class GetPlanPrice(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -255,7 +255,7 @@ class GetPlanFeature(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -311,7 +311,7 @@ class GetPlanReset(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -404,7 +404,7 @@ class GetPlanItemPrice(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -447,7 +447,7 @@ class GetPlanItemDisplay(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -498,7 +498,7 @@ class GetPlanRollover(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -568,7 +568,7 @@ class GetPlanItem(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -690,7 +690,7 @@ class GetPlanCustomerEligibility(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -789,7 +789,7 @@ class GetPlanResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member

View File

@@ -1,9 +1,8 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from typing import TYPE_CHECKING
from importlib import import_module
import builtins
import sys
from typing import Any, TYPE_CHECKING
from autumn_sdk.utils.dynamic_imports import lazy_getattr, lazy_dir
if TYPE_CHECKING:
from .globals import Globals, GlobalsTypedDict
@@ -16,39 +15,11 @@ _dynamic_imports: dict[str, str] = {
}
def dynamic_import(modname, retries=3):
for attempt in range(retries):
try:
return import_module(modname, __package__)
except KeyError:
# Clear any half-initialized module and retry
sys.modules.pop(modname, None)
if attempt == retries - 1:
break
raise KeyError(f"Failed to import module '{modname}' after {retries} attempts")
def __getattr__(attr_name: str) -> object:
module_name = _dynamic_imports.get(attr_name)
if module_name is None:
raise AttributeError(
f"No {attr_name} found in _dynamic_imports for module name -> {__name__} "
)
try:
module = dynamic_import(module_name)
result = getattr(module, attr_name)
return result
except ImportError as e:
raise ImportError(
f"Failed to import {attr_name} from {module_name}: {e}"
) from e
except AttributeError as e:
raise AttributeError(
f"Failed to get {attr_name} from {module_name}: {e}"
) from e
def __getattr__(attr_name: str) -> Any:
return lazy_getattr(
attr_name, package=__package__, dynamic_imports=_dynamic_imports
)
def __dir__():
lazy_attrs = builtins.list(_dynamic_imports.keys())
return builtins.sorted(lazy_attrs)
return lazy_dir(dynamic_imports=_dynamic_imports)

View File

@@ -35,7 +35,7 @@ class Globals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:

View File

@@ -37,7 +37,7 @@ class ListCustomersGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -64,7 +64,7 @@ class ListCustomersPlan(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -119,7 +119,7 @@ class ListCustomersParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -181,7 +181,7 @@ class ListCustomersPurchaseLimit(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -227,7 +227,7 @@ class ListCustomersAutoTopup(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -263,7 +263,7 @@ class ListCustomersSpendLimit(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -319,7 +319,7 @@ class ListCustomersUsageAlert(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -359,7 +359,7 @@ class ListCustomersBillingControls(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -467,7 +467,7 @@ class ListCustomersSubscription(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -520,7 +520,7 @@ class ListCustomersPurchase(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -590,7 +590,7 @@ class ListCustomersDisplay(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -663,7 +663,7 @@ class ListCustomersFeature(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -710,7 +710,7 @@ class ListCustomersFlags(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -808,7 +808,7 @@ class ListCustomersList(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
m[k] = val

View File

@@ -28,7 +28,7 @@ class ListEventsGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -73,7 +73,7 @@ class ListEventsCustomRange(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -133,7 +133,7 @@ class EventsListParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:

View File

@@ -35,7 +35,7 @@ class ListFeaturesGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -105,7 +105,7 @@ class ListFeaturesDisplay(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -174,7 +174,7 @@ class ListFeaturesList(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:

View File

@@ -35,7 +35,7 @@ class ListPlansGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -71,7 +71,7 @@ class ListPlansParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -120,7 +120,7 @@ class ListPlansPriceDisplay(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -161,7 +161,7 @@ class ListPlansPrice(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -260,7 +260,7 @@ class ListPlansFeature(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -316,7 +316,7 @@ class ListPlansReset(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -409,7 +409,7 @@ class ListPlansItemPrice(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -452,7 +452,7 @@ class ListPlansItemDisplay(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -503,7 +503,7 @@ class ListPlansRollover(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -573,7 +573,7 @@ class ListPlansItem(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -695,7 +695,7 @@ class ListPlansCustomerEligibility(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -794,7 +794,7 @@ class ListPlansList(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member

View File

@@ -36,7 +36,7 @@ class MultiAttachGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -87,7 +87,7 @@ class MultiAttachBasePrice(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -136,7 +136,7 @@ class MultiAttachReset(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -172,7 +172,7 @@ class MultiAttachTier(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -268,7 +268,7 @@ class MultiAttachPrice(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -353,7 +353,7 @@ class MultiAttachRollover(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -415,7 +415,7 @@ class MultiAttachPlanItem(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -451,7 +451,7 @@ class MultiAttachCustomize(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -499,7 +499,7 @@ class MultiAttachFeatureQuantity(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -547,7 +547,7 @@ class MultiAttachPlan(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -595,7 +595,7 @@ class MultiAttachFreeTrialParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -635,7 +635,7 @@ class MultiAttachInvoiceMode(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -670,7 +670,7 @@ class MultiAttachAttachDiscount(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -714,7 +714,7 @@ class MultiAttachSpendLimit(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -767,7 +767,7 @@ class MultiAttachUsageAlert(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -802,7 +802,7 @@ class MultiAttachBillingControls(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -838,7 +838,7 @@ class MultiAttachEntityData(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -931,7 +931,7 @@ class MultiAttachParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -988,7 +988,7 @@ class MultiAttachInvoice(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
m[k] = val
@@ -1068,7 +1068,7 @@ class MultiAttachResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member

View File

@@ -28,7 +28,7 @@ class OpenCustomerPortalGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -64,7 +64,7 @@ class OpenCustomerPortalParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:

View File

@@ -54,7 +54,7 @@ class PlanPriceDisplay(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -95,7 +95,7 @@ class PlanPrice(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -194,7 +194,7 @@ class PlanFeature(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -250,7 +250,7 @@ class PlanReset(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -343,7 +343,7 @@ class PlanItemPrice(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -386,7 +386,7 @@ class PlanItemDisplay(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -437,7 +437,7 @@ class PlanRollover(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -507,7 +507,7 @@ class Item(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -629,7 +629,7 @@ class CustomerEligibility(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -724,7 +724,7 @@ class Plan(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member

View File

@@ -36,7 +36,7 @@ class PreviewAttachGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -76,7 +76,7 @@ class PreviewAttachFeatureQuantityRequest(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -127,7 +127,7 @@ class PreviewAttachBasePrice(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -176,7 +176,7 @@ class PreviewAttachReset(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -212,7 +212,7 @@ class PreviewAttachTier(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -308,7 +308,7 @@ class PreviewAttachPrice(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -393,7 +393,7 @@ class PreviewAttachRollover(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -455,7 +455,7 @@ class PreviewAttachPlanItem(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -503,7 +503,7 @@ class PreviewAttachFreeTrialParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -544,7 +544,7 @@ class PreviewAttachCustomize(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -592,7 +592,7 @@ class PreviewAttachInvoiceMode(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -642,7 +642,7 @@ class PreviewAttachAttachDiscount(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -699,7 +699,7 @@ class PreviewAttachCarryOverBalances(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -734,7 +734,7 @@ class PreviewAttachCarryOverUsages(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -876,7 +876,7 @@ class PreviewAttachParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -909,7 +909,7 @@ class PreviewAttachDiscount(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -995,7 +995,7 @@ class PreviewAttachLineItem(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -1036,7 +1036,7 @@ class PreviewAttachNextCycleDiscount(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -1122,7 +1122,7 @@ class PreviewAttachNextCycleLineItem(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -1191,7 +1191,7 @@ class PreviewAttachUsageLineItem(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -1298,7 +1298,7 @@ class PreviewAttachIncoming(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -1371,7 +1371,7 @@ class PreviewAttachOutgoing(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -1467,7 +1467,7 @@ class PreviewAttachResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member

View File

@@ -37,7 +37,7 @@ class PreviewMultiAttachGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -88,7 +88,7 @@ class PreviewMultiAttachBasePrice(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -137,7 +137,7 @@ class PreviewMultiAttachReset(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -175,7 +175,7 @@ class PreviewMultiAttachTier(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -271,7 +271,7 @@ class PreviewMultiAttachPrice(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -356,7 +356,7 @@ class PreviewMultiAttachRollover(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -418,7 +418,7 @@ class PreviewMultiAttachPlanItem(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -454,7 +454,7 @@ class PreviewMultiAttachCustomize(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -502,7 +502,7 @@ class PreviewMultiAttachPlanFeatureQuantity(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -552,7 +552,7 @@ class PreviewMultiAttachPlan(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -600,7 +600,7 @@ class PreviewMultiAttachFreeTrialParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -640,7 +640,7 @@ class PreviewMultiAttachInvoiceMode(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -675,7 +675,7 @@ class PreviewMultiAttachAttachDiscount(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -719,7 +719,7 @@ class PreviewMultiAttachSpendLimit(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -772,7 +772,7 @@ class PreviewMultiAttachUsageAlert(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -807,7 +807,7 @@ class PreviewMultiAttachBillingControls(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -843,7 +843,7 @@ class PreviewMultiAttachEntityData(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -936,7 +936,7 @@ class PreviewMultiAttachParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -977,7 +977,7 @@ class PreviewMultiAttachDiscount(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -1063,7 +1063,7 @@ class PreviewMultiAttachLineItem(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -1104,7 +1104,7 @@ class PreviewMultiAttachNextCycleDiscount(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -1190,7 +1190,7 @@ class PreviewMultiAttachNextCycleLineItem(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -1259,7 +1259,7 @@ class PreviewMultiAttachUsageLineItem(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -1366,7 +1366,7 @@ class PreviewMultiAttachIncoming(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -1439,7 +1439,7 @@ class PreviewMultiAttachOutgoing(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -1535,7 +1535,7 @@ class PreviewMultiAttachResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member

View File

@@ -36,7 +36,7 @@ class PreviewUpdateGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -76,7 +76,7 @@ class PreviewUpdateFeatureQuantityRequest(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -127,7 +127,7 @@ class PreviewUpdateBasePrice(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -176,7 +176,7 @@ class PreviewUpdateReset(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -212,7 +212,7 @@ class PreviewUpdateTier(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -308,7 +308,7 @@ class PreviewUpdatePrice(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -393,7 +393,7 @@ class PreviewUpdateRollover(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -455,7 +455,7 @@ class PreviewUpdatePlanItem(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -503,7 +503,7 @@ class PreviewUpdateFreeTrialParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -544,7 +544,7 @@ class PreviewUpdateCustomize(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -592,7 +592,7 @@ class PreviewUpdateInvoiceMode(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -730,7 +730,7 @@ class PreviewUpdateParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -763,7 +763,7 @@ class PreviewUpdateDiscount(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -849,7 +849,7 @@ class PreviewUpdateLineItem(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -890,7 +890,7 @@ class PreviewUpdateNextCycleDiscount(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -976,7 +976,7 @@ class PreviewUpdateNextCycleLineItem(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -1045,7 +1045,7 @@ class PreviewUpdateUsageLineItem(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -1152,7 +1152,7 @@ class PreviewUpdateIncoming(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -1225,7 +1225,7 @@ class PreviewUpdateOutgoing(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -1319,7 +1319,7 @@ class PreviewUpdateResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:

View File

@@ -28,7 +28,7 @@ class RedeemReferralCodeGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:

View File

@@ -34,7 +34,7 @@ class SetupPaymentGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -74,7 +74,7 @@ class SetupPaymentFeatureQuantity(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -125,7 +125,7 @@ class SetupPaymentBasePrice(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -174,7 +174,7 @@ class SetupPaymentReset(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -210,7 +210,7 @@ class SetupPaymentTier(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -306,7 +306,7 @@ class SetupPaymentPrice(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -391,7 +391,7 @@ class SetupPaymentRollover(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -453,7 +453,7 @@ class SetupPaymentPlanItem(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -501,7 +501,7 @@ class SetupPaymentFreeTrialParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -542,7 +542,7 @@ class SetupPaymentCustomize(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -592,7 +592,7 @@ class SetupPaymentAttachDiscount(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -642,7 +642,7 @@ class SetupPaymentCarryOverBalances(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -677,7 +677,7 @@ class SetupPaymentCarryOverUsages(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -796,7 +796,7 @@ class SetupPaymentParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -836,7 +836,7 @@ class SetupPaymentResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:

View File

@@ -30,7 +30,7 @@ class TrackGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -69,7 +69,7 @@ class TrackLock(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -125,7 +125,7 @@ class TrackParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -181,7 +181,7 @@ class TrackResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member

View File

@@ -28,7 +28,7 @@ class UpdateBalanceGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -124,7 +124,7 @@ class UpdateBalanceParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:

View File

@@ -37,7 +37,7 @@ class UpdateCustomerGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -86,7 +86,7 @@ class UpdateCustomerPurchaseLimitRequest(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -132,7 +132,7 @@ class UpdateCustomerAutoTopupRequest(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -168,7 +168,7 @@ class UpdateCustomerSpendLimitRequest(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -221,7 +221,7 @@ class UpdateCustomerUsageAlertRequestBody(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -261,7 +261,7 @@ class UpdateCustomerBillingControlsRequest(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -339,7 +339,7 @@ class UpdateCustomerParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -409,7 +409,7 @@ class UpdateCustomerPurchaseLimitResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -455,7 +455,7 @@ class UpdateCustomerAutoTopupResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -491,7 +491,7 @@ class UpdateCustomerSpendLimitResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -547,7 +547,7 @@ class UpdateCustomerUsageAlertResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -587,7 +587,7 @@ class UpdateCustomerBillingControlsResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -695,7 +695,7 @@ class UpdateCustomerSubscription(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -748,7 +748,7 @@ class UpdateCustomerPurchase(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -818,7 +818,7 @@ class UpdateCustomerDisplay(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -891,7 +891,7 @@ class UpdateCustomerFeature(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -938,7 +938,7 @@ class UpdateCustomerFlags(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -1040,7 +1040,7 @@ class UpdateCustomerResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
m[k] = val

View File

@@ -37,7 +37,7 @@ class UpdateEntityGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -73,7 +73,7 @@ class UpdateEntitySpendLimitRequest(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -126,7 +126,7 @@ class UpdateEntityUsageAlertRequestBody(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -161,7 +161,7 @@ class UpdateEntityBillingControlsRequest(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -197,7 +197,7 @@ class UpdateEntityParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -315,7 +315,7 @@ class UpdateEntitySubscription(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -368,7 +368,7 @@ class UpdateEntityPurchase(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -438,7 +438,7 @@ class UpdateEntityDisplay(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -511,7 +511,7 @@ class UpdateEntityFeature(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -558,7 +558,7 @@ class UpdateEntityFlags(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -602,7 +602,7 @@ class UpdateEntitySpendLimitResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -658,7 +658,7 @@ class UpdateEntityUsageAlertResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -693,7 +693,7 @@ class UpdateEntityBillingControlsResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -750,7 +750,7 @@ class UpdateEntityInvoice(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -838,7 +838,7 @@ class UpdateEntityResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member

View File

@@ -35,7 +35,7 @@ class UpdateFeatureGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -144,7 +144,7 @@ class UpdateFeatureParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -206,7 +206,7 @@ class UpdateFeatureDisplayResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -279,7 +279,7 @@ class UpdateFeatureResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:

View File

@@ -35,7 +35,7 @@ class UpdatePlanGlobals(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -86,7 +86,7 @@ class UpdatePlanBasePrice(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -135,7 +135,7 @@ class UpdatePlanResetRequest(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -171,7 +171,7 @@ class UpdatePlanTier(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -267,7 +267,7 @@ class UpdatePlanPriceRequest(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -352,7 +352,7 @@ class UpdatePlanRolloverRequest(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -414,7 +414,7 @@ class UpdatePlanPlanItem(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -462,7 +462,7 @@ class UpdatePlanFreeTrialParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -552,7 +552,7 @@ class UpdatePlanParams(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -609,7 +609,7 @@ class UpdatePlanPriceDisplay(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -650,7 +650,7 @@ class UpdatePlanPriceResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -749,7 +749,7 @@ class UpdatePlanFeature(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -805,7 +805,7 @@ class UpdatePlanResetResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -898,7 +898,7 @@ class UpdatePlanItemPriceResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -941,7 +941,7 @@ class UpdatePlanItemDisplay(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -992,7 +992,7 @@ class UpdatePlanRolloverResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -1062,7 +1062,7 @@ class UpdatePlanItem(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
@@ -1184,7 +1184,7 @@ class UpdatePlanCustomerEligibility(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
@@ -1283,7 +1283,7 @@ class UpdatePlanResponse(BaseModel):
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
val = serialized.get(k, serialized.get(n))
is_nullable_and_explicitly_set = (
k in nullable_fields
and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member

View File

@@ -53,8 +53,8 @@ class Autumn(BaseSDK):
x_api_version: Optional[str] = None,
fail_open: Optional[bool] = None,
server_idx: Optional[int] = None,
server_url: Optional[str] = None,
url_params: Optional[Dict[str, str]] = None,
server_url: Optional[str] = None,
client: Optional[HttpClient] = None,
async_client: Optional[AsyncHttpClient] = None,
retry_config: OptionalNullable[RetryConfig] = UNSET,

View File

@@ -1,10 +1,9 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from typing import TYPE_CHECKING, Callable, TypeVar
from importlib import import_module
from typing import Any, TYPE_CHECKING, Callable, TypeVar
import asyncio
import builtins
import sys
from .dynamic_imports import lazy_getattr, lazy_dir
_T = TypeVar("_T")
@@ -166,38 +165,11 @@ _dynamic_imports: dict[str, str] = {
}
def dynamic_import(modname, retries=3):
for attempt in range(retries):
try:
return import_module(modname, __package__)
except KeyError:
# Clear any half-initialized module and retry
sys.modules.pop(modname, None)
if attempt == retries - 1:
break
raise KeyError(f"Failed to import module '{modname}' after {retries} attempts")
def __getattr__(attr_name: str) -> object:
module_name = _dynamic_imports.get(attr_name)
if module_name is None:
raise AttributeError(
f"no {attr_name} found in _dynamic_imports, module name -> {__name__} "
)
try:
module = dynamic_import(module_name)
return getattr(module, attr_name)
except ImportError as e:
raise ImportError(
f"Failed to import {attr_name} from {module_name}: {e}"
) from e
except AttributeError as e:
raise AttributeError(
f"Failed to get {attr_name} from {module_name}: {e}"
) from e
def __getattr__(attr_name: str) -> Any:
return lazy_getattr(
attr_name, package=__package__, dynamic_imports=_dynamic_imports
)
def __dir__():
lazy_attrs = builtins.list(_dynamic_imports.keys())
return builtins.sorted(lazy_attrs)
return lazy_dir(dynamic_imports=_dynamic_imports)

View File

@@ -0,0 +1,54 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from importlib import import_module
import builtins
import sys
def dynamic_import(package, modname, retries=3):
"""Import a module relative to package, retrying on KeyError from half-initialized modules."""
for attempt in range(retries):
try:
return import_module(modname, package)
except KeyError:
sys.modules.pop(modname, None)
if attempt == retries - 1:
break
raise KeyError(f"Failed to import module '{modname}' after {retries} attempts")
def lazy_getattr(attr_name, *, package, dynamic_imports, sub_packages=None):
"""Module-level __getattr__ that lazily loads from a dynamic_imports mapping.
Args:
attr_name: The attribute being looked up.
package: The caller's __package__ (for relative imports).
dynamic_imports: Dict mapping attribute names to relative module paths.
sub_packages: Optional list of subpackage names to lazy-load.
"""
module_name = dynamic_imports.get(attr_name)
if module_name is not None:
try:
module = dynamic_import(package, module_name)
return getattr(module, attr_name)
except ImportError as e:
raise ImportError(
f"Failed to import {attr_name} from {module_name}: {e}"
) from e
except AttributeError as e:
raise AttributeError(
f"Failed to get {attr_name} from {module_name}: {e}"
) from e
if sub_packages and attr_name in sub_packages:
return import_module(f".{attr_name}", package)
raise AttributeError(f"module '{package}' has no attribute '{attr_name}'")
def lazy_dir(*, dynamic_imports, sub_packages=None):
"""Module-level __dir__ that lists lazily-loadable attributes."""
lazy_attrs = builtins.list(dynamic_imports.keys())
if sub_packages:
lazy_attrs.extend(sub_packages)
return builtins.sorted(lazy_attrs)

View File

@@ -32,9 +32,12 @@ class EventStream(Generic[T]):
decoder: Callable[[str], T],
sentinel: Optional[str] = None,
client_ref: Optional[object] = None,
data_required: bool = True,
):
self.response = response
self.generator = stream_events(response, decoder, sentinel)
self.generator = stream_events(
response, decoder, sentinel, data_required=data_required
)
self.client_ref = client_ref
self._closed = False
@@ -68,9 +71,12 @@ class EventStreamAsync(Generic[T]):
decoder: Callable[[str], T],
sentinel: Optional[str] = None,
client_ref: Optional[object] = None,
data_required: bool = True,
):
self.response = response
self.generator = stream_events_async(response, decoder, sentinel)
self.generator = stream_events_async(
response, decoder, sentinel, data_required=data_required
)
self.client_ref = client_ref
self._closed = False
@@ -116,6 +122,7 @@ async def stream_events_async(
response: httpx.Response,
decoder: Callable[[str], T],
sentinel: Optional[str] = None,
data_required: bool = True,
) -> AsyncGenerator[T, None]:
buffer = bytearray()
position = 0
@@ -138,7 +145,11 @@ async def stream_events_async(
block = buffer[position:i]
position = i + len(seq)
event, discard, event_id = _parse_event(
raw=block, decoder=decoder, sentinel=sentinel, event_id=event_id
raw=block,
decoder=decoder,
sentinel=sentinel,
event_id=event_id,
data_required=data_required,
)
if event is not None:
yield event
@@ -151,7 +162,11 @@ async def stream_events_async(
position = 0
event, discard, _ = _parse_event(
raw=buffer, decoder=decoder, sentinel=sentinel, event_id=event_id
raw=buffer,
decoder=decoder,
sentinel=sentinel,
event_id=event_id,
data_required=data_required,
)
if event is not None:
yield event
@@ -161,6 +176,7 @@ def stream_events(
response: httpx.Response,
decoder: Callable[[str], T],
sentinel: Optional[str] = None,
data_required: bool = True,
) -> Generator[T, None, None]:
buffer = bytearray()
position = 0
@@ -183,7 +199,11 @@ def stream_events(
block = buffer[position:i]
position = i + len(seq)
event, discard, event_id = _parse_event(
raw=block, decoder=decoder, sentinel=sentinel, event_id=event_id
raw=block,
decoder=decoder,
sentinel=sentinel,
event_id=event_id,
data_required=data_required,
)
if event is not None:
yield event
@@ -196,7 +216,11 @@ def stream_events(
position = 0
event, discard, _ = _parse_event(
raw=buffer, decoder=decoder, sentinel=sentinel, event_id=event_id
raw=buffer,
decoder=decoder,
sentinel=sentinel,
event_id=event_id,
data_required=data_required,
)
if event is not None:
yield event
@@ -208,6 +232,7 @@ def _parse_event(
decoder: Callable[[str], T],
sentinel: Optional[str] = None,
event_id: Optional[str] = None,
data_required: bool = True,
) -> Tuple[Optional[T], bool, Optional[str]]:
block = raw.decode()
lines = re.split(r"\r?\n|\r", block)
@@ -250,6 +275,10 @@ def _parse_event(
if sentinel and data == f"{sentinel}\n":
return None, True, event_id
# Skip data-less events when data is required
if not data and publish and data_required:
return None, False, event_id
if data:
data = data[:-1]
try:

View File

@@ -144,12 +144,7 @@ def retry(func, retries: Retries):
if res.status_code == parsed_code:
raise TemporaryError(res)
except httpx.ConnectError as exception:
if retries.config.retry_connection_errors:
raise
raise PermanentError(exception) from exception
except httpx.TimeoutException as exception:
except (httpx.NetworkError, httpx.TimeoutException) as exception:
if retries.config.retry_connection_errors:
raise
@@ -193,12 +188,7 @@ async def retry_async(func, retries: Retries):
if res.status_code == parsed_code:
raise TemporaryError(res)
except httpx.ConnectError as exception:
if retries.config.retry_connection_errors:
raise
raise PermanentError(exception) from exception
except httpx.TimeoutException as exception:
except (httpx.NetworkError, httpx.TimeoutException) as exception:
if retries.config.retry_connection_errors:
raise

View File

@@ -56,6 +56,9 @@ export const eventsAggregateParamsOutboundSchema = z.object({
custom_range: z
.union([aggregateEventsCustomRangeOutboundSchema, z.undefined()])
.optional(),
filter_by: z
.union([z.record(z.string(), z.string()), z.undefined()])
.optional(),
max_groups: z.union([z.number(), z.undefined()]).optional(),
});
@@ -75,5 +78,8 @@ export const eventsAggregateParamsSchema = z.object({
customRange: z
.union([aggregateEventsCustomRangeSchema, z.undefined()])
.optional(),
filterBy: z
.union([z.record(z.string(), z.string()), z.undefined()])
.optional(),
maxGroups: z.union([z.number(), z.undefined()]).optional(),
});

View File

@@ -11443,6 +11443,14 @@ paths:
- end
description: Custom time range to aggregate events for. If provided, range must
not be provided
filter_by:
type: object
propertyNames:
type: string
additionalProperties:
type: string
description: 'Filter events by property values, e.g. {"model": "gpt-4",
"region": "us"}. Maximum 5 filters.'
max_groups:
type: integer
minimum: 1

View File

@@ -12198,6 +12198,14 @@ paths:
- end
description: Custom time range to aggregate events for. If provided, range must
not be provided
filter_by:
type: object
propertyNames:
type: string
additionalProperties:
type: string
description: 'Filter events by property values, e.g. {"model": "gpt-4",
"region": "us"}. Maximum 5 filters.'
max_groups:
type: integer
minimum: 1

View File

@@ -3,6 +3,7 @@ import { SuccessResponseSchema } from "@api/common/commonResponses.js";
import {
ApiBalanceV1Schema,
ApiCustomerV5Schema,
ApiEventsListParamsSchema,
ApiPlanV1Schema,
AttachParamsV1Schema,
AttachPreviewResponseSchema,
@@ -71,6 +72,7 @@ async function generateOpenApiDocument(): Promise<Record<string, unknown>> {
registerInternalSchemas(CheckResponseV3Schema);
registerInternalSchemas(TrackResponseV3Schema);
registerInternalSchemas(CustomerDataSchema);
registerInternalSchemas(ApiEventsListParamsSchema);
const openApiDocument = (await generator.generate(v2_1ContractRouter, {
info: {

View File

@@ -5,10 +5,14 @@
!/**/*.ts
!/**/*.js
!/**/*.mjs
!/**/*.json
!/package.json
!/jsr.json
!/dist/**/*.json
!/esm/**/*.json
!/**/*.map
/eslint.config.mjs
/.oxlintrc.json
/cjs
/.tshy
/.tshy-*

File diff suppressed because it is too large Load Diff

View File

@@ -11208,6 +11208,13 @@ paths:
- start
- end
description: Custom time range to aggregate events for. If provided, range must not be provided
filter_by:
type: object
propertyNames:
type: string
additionalProperties:
type: string
description: 'Filter events by property values, e.g. {"model": "gpt-4", "region": "us"}. Maximum 5 filters.'
max_groups:
type: integer
minimum: 1

View File

@@ -1,4 +1,4 @@
speakeasyVersion: 1.719.0
speakeasyVersion: 1.759.3
sources:
Autumn API:
sourceNamespace: autumn-api

View File

@@ -30,7 +30,7 @@
"@eslint/js": "^9.26.0",
"eslint": "^9.26.0",
"globals": "^15.14.0",
"tshy": "^2.0.0",
"tshy": "^3.3.2",
"typescript": "~5.8.3",
"typescript-eslint": "^8.26.0"
},

View File

@@ -72,6 +72,6 @@ export const SDK_METADATA = {
language: "typescript",
openapiDocVersion: "2.2.0",
sdkVersion: "0.10.17",
genVersion: "2.824.1",
userAgent: "speakeasy-sdk/typescript 0.10.17 2.824.1 2.2.0 @useautumn/sdk",
genVersion: "2.869.25",
userAgent: "speakeasy-sdk/typescript 0.10.17 2.869.25 2.2.0 @useautumn/sdk",
} as const;

View File

@@ -479,6 +479,23 @@ export const encodeSpaceDelimitedQuery = queryEncoder(encodeSpaceDelimited);
export const encodePipeDelimitedQuery = queryEncoder(encodePipeDelimited);
export const encodeDeepObjectQuery = queryEncoder(encodeDeepObject);
function isBlobLike(val: unknown): val is Blob {
if (val instanceof Blob) {
return true;
}
if (typeof val !== "object" || val == null || !(Symbol.toStringTag in val)) {
return false;
}
const tag = val[Symbol.toStringTag];
if (tag !== "Blob" && tag !== "File") {
return false;
}
return "stream" in val && typeof val.stream === "function";
}
export function appendForm(
fd: FormData,
key: string,
@@ -487,10 +504,12 @@ export function appendForm(
): void {
if (value == null) {
return;
} else if (value instanceof Blob && fileName) {
fd.append(key, value, fileName);
} else if (value instanceof Blob) {
fd.append(key, value);
} else if (isBlobLike(value)) {
if (fileName) {
fd.append(key, value as Blob, fileName);
} else {
fd.append(key, value as Blob);
}
} else if (Array.isArray(value)) {
value.forEach((v) => {
appendForm(fd, key, v);

View File

@@ -80,3 +80,25 @@ export function getContentTypeFromFileName(fileName: string): string | null {
return mimeTypes[ext] || null;
}
/**
* Creates a Blob from file content with the given MIME type.
*
* Node.js Buffers are Uint8Array subclasses that may share a pooled
* ArrayBuffer (byteOffset > 0, byteLength < buffer.byteLength). Passing
* such a Buffer directly to `new Blob([buf])` can include the entire
* underlying pool on some runtimes, producing a Blob with extra bytes
* that corrupts multipart uploads.
*
* Copying into a standalone Uint8Array ensures the Blob receives only the
* intended bytes regardless of runtime behaviour.
*/
export function bytesToBlob(
content: Uint8Array<ArrayBufferLike> | ArrayBuffer | Blob | string,
contentType: string,
): Blob {
if (content instanceof Uint8Array) {
return new Blob([new Uint8Array(content)], { type: contentType });
}
return new Blob([content as BlobPart], { type: contentType });
}

View File

@@ -251,8 +251,9 @@ export function match<T, E>(
raw = body;
break;
default:
encoding satisfies never;
throw new Error(`Unsupported response type: ${encoding}`);
throw new Error(
`Unsupported response type: ${encoding satisfies never}`,
);
}
if (matcher.enc === "fail") {

View File

@@ -127,13 +127,15 @@ export class ClientSDK {
if (!base) {
return ERR(new InvalidRequestError("No base URL provided for operation"));
}
const reqURL = new URL(base);
const inputURL = new URL(path, reqURL);
const baseURL = new URL(base);
let reqURL: URL;
if (path) {
reqURL.pathname += reqURL.pathname.endsWith("/") ? "" : "/";
reqURL.pathname += inputURL.pathname.replace(/^\/+/, "");
baseURL.pathname = baseURL.pathname.replace(/\/+$/, "") + "/";
reqURL = new URL(path, baseURL);
} else {
reqURL = baseURL;
}
reqURL.hash = "";
let finalQuery = query || "";

View File

@@ -198,8 +198,7 @@ export function resolveSecurity(
applyBearer(state, spec);
break;
default:
spec satisfies never;
throw SecurityError.unrecognizedType(type);
throw SecurityError.unrecognizedType((spec satisfies never, type));
}
});

View File

@@ -13,21 +13,23 @@ export function pathToFunc(
const paramRE = /\{([a-zA-Z0-9_][a-zA-Z0-9_-]*?)\}/g;
return function buildURLPath(params: Record<string, unknown> = {}): string {
return pathPattern.replace(paramRE, function (_, placeholder) {
if (!hasOwn.call(params, placeholder)) {
throw new Error(`Parameter '${placeholder}' is required`);
}
return pathPattern
.replace(paramRE, function (_, placeholder) {
if (!hasOwn.call(params, placeholder)) {
throw new Error(`Parameter '${placeholder}' is required`);
}
const value = params[placeholder];
if (typeof value !== "string" && typeof value !== "number") {
throw new Error(
`Parameter '${placeholder}' must be a string or number`,
);
}
const value = params[placeholder];
if (typeof value !== "string" && typeof value !== "number") {
throw new Error(
`Parameter '${placeholder}' must be a string or number`,
);
}
return options?.charEncoding === "percent"
? encodeURIComponent(`${value}`)
: `${value}`;
});
return options?.charEncoding === "percent"
? encodeURIComponent(`${value}`)
: `${value}`;
})
.replace(/^\/+/, "");
};
}

View File

@@ -88,6 +88,9 @@ export type EventsAggregateParams = {
*/
customRange?: AggregateEventsCustomRange | undefined;
/**
* Filter events by property values, e.g. {"model": "gpt-4", "region": "us"}. Maximum 5 filters.
*/
filterBy?: { [k: string]: string } | undefined;
* Maximum number of distinct group values to return per time bin when using group_by. Remaining values are bundled into an 'Other' bucket. Defaults to 9
*/
maxGroups?: number | undefined;
@@ -190,6 +193,7 @@ export type EventsAggregateParams$Outbound = {
range?: string | undefined;
bin_size: string;
custom_range?: AggregateEventsCustomRange$Outbound | undefined;
filter_by?: { [k: string]: string } | undefined;
max_groups?: number | undefined;
};
@@ -208,6 +212,7 @@ export const EventsAggregateParams$outboundSchema: z.ZodMiniType<
customRange: z.optional(
z.lazy(() => AggregateEventsCustomRange$outboundSchema),
),
filterBy: z.optional(z.record(z.string(), z.string())),
maxGroups: z.optional(z.int()),
}),
z.transform((v) => {
@@ -218,6 +223,7 @@ export const EventsAggregateParams$outboundSchema: z.ZodMiniType<
groupBy: "group_by",
binSize: "bin_size",
customRange: "custom_range",
filterBy: "filter_by",
maxGroups: "max_groups",
});
}),

View File

@@ -13,6 +13,7 @@
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"rootDir": "src",
"outDir": ".",
@@ -36,5 +37,5 @@
"forceConsistentCasingInFileNames": true
},
"include": ["src"],
"exclude": ["node_modules"]
"exclude": ["node_modules", "src/__tests__"]
}

View File

@@ -32,6 +32,16 @@ export const aggregateGroupablePipeParamsSchema = z.object({
.enum(["property", "customer_id", "entity_id"])
.default("property"),
property_key: z.string().optional(), // the property name without 'properties.' prefix (not needed when group_column is "customer_id" or "entity_id")
filter_key_0: z.string().optional(),
filter_value_0: z.string().optional(),
filter_key_1: z.string().optional(),
filter_value_1: z.string().optional(),
filter_key_2: z.string().optional(),
filter_value_2: z.string().optional(),
filter_key_3: z.string().optional(),
filter_value_3: z.string().optional(),
filter_key_4: z.string().optional(),
filter_value_4: z.string().optional(),
max_groups: z.number().int().min(1).max(250).optional(),
});

View File

@@ -23,6 +23,16 @@ export const aggregateSimplePipeParamsSchema = z.object({
timezone: z.string(),
customer_id: z.string().optional(),
entity_id: z.string().optional(),
filter_key_0: z.string().optional(),
filter_value_0: z.string().optional(),
filter_key_1: z.string().optional(),
filter_value_1: z.string().optional(),
filter_key_2: z.string().optional(),
filter_value_2: z.string().optional(),
filter_key_3: z.string().optional(),
filter_value_3: z.string().optional(),
filter_key_4: z.string().optional(),
filter_value_4: z.string().optional(),
});
export type AggregateSimplePipeParams = z.infer<

View File

@@ -30,6 +30,16 @@ export const listEventsPaginatedPipeParamsSchema = z.object({
event_names: z.array(z.string()).optional(),
limit: z.number().optional(),
offset: z.number().optional(),
filter_key_0: z.string().optional(),
filter_value_0: z.string().optional(),
filter_key_1: z.string().optional(),
filter_value_1: z.string().optional(),
filter_key_2: z.string().optional(),
filter_value_2: z.string().optional(),
filter_key_3: z.string().optional(),
filter_value_3: z.string().optional(),
filter_key_4: z.string().optional(),
filter_value_4: z.string().optional(),
});
export type ListEventsPaginatedPipeParams = z.infer<

View File

@@ -14,7 +14,6 @@ import { z } from "zod/v4";
import type { DrizzleCli } from "@/db/initDrizzle.js";
import { parseVercelPrepaidQuantities } from "@/external/vercel/misc/vercelInvoicing.js";
import { createRoute } from "@/honoMiddlewares/routeHandler.js";
import { CusService } from "@/internal/customers/CusService.js";
import { ProductService } from "@/internal/products/ProductService.js";
import { findPrepaidPrice } from "@/internal/products/prices/priceUtils/findPriceUtils.js";
import { sortProductsByPrice } from "../../../internal/products/productUtils/sortProductUtils.js";
@@ -245,10 +244,7 @@ export const handleListBillingPlansPerInstall = createRoute({
);
}
const customer = await CusService.getByVercelId({
ctx,
vercelInstallationId: integrationConfigurationId,
});
const { fullCustomer: customer } = ctx;
// Parse metadata from query params
let metadata: Record<string, any> = {};

View File

@@ -1,11 +1,10 @@
import { CustomerExpand, RecaseError } from "@autumn/shared";
import { RecaseError } from "@autumn/shared";
import { ErrCode } from "@shared/enums/ErrCode.js";
import { StatusCodes } from "http-status-codes";
import { z } from "zod/v4";
import { createStripeCli } from "@/external/connect/createStripeCli.js";
import { createVercelSubscription } from "@/external/vercel/misc/vercelSubscriptions.js";
import { createRoute } from "@/honoMiddlewares/routeHandler.js";
import { CusService } from "@/internal/customers/CusService.js";
import type { VercelError, VercelNotification } from "../misc/vercelTypes.js";
import { productToBillingPlan } from "./handleListBillingPlans.js";
@@ -17,17 +16,10 @@ export const handleUpdateVercelBillingPlan = createRoute({
handler: async (c) => {
const { integrationConfigurationId } = c.req.param();
const ctx = c.get("ctx");
const { org, logger } = ctx;
const { org, logger, fullCustomer: customer } = ctx;
const { billingPlanId } = c.req.valid("json");
// Get customer by Vercel installation ID (not by customer.id which may differ)
const customer = await CusService.getByVercelId({
ctx,
vercelInstallationId: integrationConfigurationId,
expand: [CustomerExpand.Entities],
});
if (!customer) {
throw new RecaseError({
message: `Customer not found for Vercel installation ${integrationConfigurationId}`,

View File

@@ -3,7 +3,6 @@ import { sendCustomSvixEvent } from "@/external/svix/svixHelpers.js";
import { VercelResourceService } from "@/external/vercel/services/VercelResourceService.js";
import { createRoute } from "@/honoMiddlewares/routeHandler.js";
import { customerActions } from "@/internal/customers/actions/index.js";
import { CusService } from "@/internal/customers/CusService.js";
import {
type VercelResourceDeletedEvent,
VercelWebhooks,
@@ -13,7 +12,7 @@ export const handleDeleteInstallation = createRoute({
handler: async (c) => {
const ctx = c.get("ctx");
const { integrationConfigurationId, orgId } = c.req.param();
const { db, org, logger } = ctx;
const { db, org, logger, fullCustomer: customer } = ctx;
try {
const resources = await VercelResourceService.listByInstallation({
@@ -49,13 +48,7 @@ export const handleDeleteInstallation = createRoute({
]),
);
// 2. Get customer by Vercel installation ID (customer.id may differ from installation_id)
const customer = await CusService.getByVercelId({
ctx,
vercelInstallationId: integrationConfigurationId,
});
// 3. Delete the customer/installation using the actual customer ID
// 2. Delete the customer/installation using the actual customer ID
if (customer) {
await customerActions.delete({
ctx,

View File

@@ -5,20 +5,13 @@ import {
productV2ToBasePrice,
} from "@autumn/shared";
import { createRoute } from "@/honoMiddlewares/routeHandler.js";
import { CusService } from "@/internal/customers/CusService.js";
import type { VercelBillingPlan } from "../../misc/vercelTypes.js";
import { productToBillingPlan } from "../handleListBillingPlans.js";
export const handleGetInstallation = createRoute({
handler: async (c) => {
const ctx = c.get("ctx");
const { integrationConfigurationId } = c.req.param();
const { org } = ctx;
const customer = await CusService.getByVercelId({
ctx,
vercelInstallationId: integrationConfigurationId,
});
const { org, fullCustomer: customer } = ctx;
if (!customer) {
return c.json(

View File

@@ -1,9 +1,4 @@
import {
AppEnv,
CustomerExpand,
type FullProduct,
RecaseError,
} from "@autumn/shared";
import { AppEnv, type FullProduct, RecaseError } from "@autumn/shared";
import { ErrCode } from "@shared/enums/ErrCode.js";
import { DrizzleError } from "drizzle-orm";
import { StatusCodes } from "http-status-codes";
@@ -14,7 +9,6 @@ import { sendCustomSvixEvent } from "@/external/svix/svixHelpers.js";
import { createVercelSubscription } from "@/external/vercel/misc/vercelSubscriptions.js";
import { VercelResourceService } from "@/external/vercel/services/VercelResourceService.js";
import { createRoute } from "@/honoMiddlewares/routeHandler.js";
import { CusService } from "@/internal/customers/CusService.js";
import { generateId } from "@/utils/genUtils.js";
import {
type VercelResourceCreatedEvent,
@@ -42,16 +36,9 @@ export const handleCreateResource = createRoute({
handler: async (c) => {
const { orgId, env, integrationConfigurationId } = c.req.param();
const ctx = c.get("ctx");
const { db, org } = ctx;
const { db, org, fullCustomer: customer } = ctx;
const { productId, name, metadata, billingPlanId } = c.req.valid("json");
// 1. Get customer by Vercel installation ID (not by customer.id which may differ)
const customer = await CusService.getByVercelId({
ctx,
vercelInstallationId: integrationConfigurationId,
expand: [CustomerExpand.Entities],
});
if (!customer) {
throw new RecaseError({
message: `Customer not found for Vercel installation ${integrationConfigurationId}`,

View File

@@ -3,7 +3,6 @@ import { createStripeCli } from "@/external/connect/createStripeCli.js";
import { sendCustomSvixEvent } from "@/external/svix/svixHelpers.js";
import { VercelResourceService } from "@/external/vercel/services/VercelResourceService.js";
import { createRoute } from "@/honoMiddlewares/routeHandler.js";
import { CusService } from "@/internal/customers/CusService.js";
import {
type VercelResourceDeletedEvent,
VercelWebhooks,
@@ -18,7 +17,7 @@ export const handleDeleteResource = createRoute({
const { orgId, env, integrationConfigurationId, resourceId } =
c.req.param();
const ctx = c.get("ctx");
const { db, org } = ctx;
const { db, org, fullCustomer: customer } = ctx;
const stripeCli = createStripeCli({ org, env: env as AppEnv });
await VercelResourceService.delete({
@@ -45,11 +44,6 @@ export const handleDeleteResource = createRoute({
} satisfies VercelResourceDeletedEvent,
});
const customer = await CusService.getByVercelId({
ctx,
vercelInstallationId: integrationConfigurationId,
});
customer?.customer_products.forEach(async (x) => {
x.subscription_ids?.forEach(async (subId) => {
await stripeCli.subscriptions.cancel(subId);

View File

@@ -0,0 +1,39 @@
import type { Context, Next } from "hono";
import type { HonoEnv } from "@/honoUtils/HonoEnv.js";
import { CusService } from "@/internal/customers/CusService.js";
/** TTL for vercel installation ID -> customer ID cache (1 day) */
export const VERCEL_INSTALLATION_CACHE_TTL_SECONDS = 24 * 60 * 60;
export const buildVercelInstallationCacheKey = ({
orgId,
env,
vercelInstallationId,
}: {
orgId: string;
env: string;
vercelInstallationId: string;
}) => {
return `{${orgId}}:${env}:vercel_install:${vercelInstallationId}`;
};
/**
* Fetches the Autumn customer by Vercel installation ID and sets `ctx.fullCustomer`.
* Tolerant of null — customer may not exist yet (e.g. during `PUT` upsert).
*/
export const vercelCustomerMiddleware = async (
c: Context<HonoEnv>,
next: Next,
) => {
const ctx = c.get("ctx");
const { integrationConfigurationId } = c.req.param();
const customer = await CusService.getByVercelId({
ctx,
vercelInstallationId: integrationConfigurationId,
});
ctx.fullCustomer = customer ?? undefined;
await next();
};

View File

@@ -22,6 +22,7 @@ import {
} from "./handlers/transfers/handleResourceTransfers.js";
import { captureRawBody } from "./misc/rawBodyMiddleware.js";
import { vercelOidcAuthMiddleware } from "./misc/vercelAuth.js";
import { vercelCustomerMiddleware } from "./misc/vercelCustomerMiddleware.js";
import {
vercelLogMiddleware,
vercelSeederMiddleware,
@@ -34,119 +35,82 @@ import {
export const vercelWebhookRouter = new Hono<HonoEnv>();
// Global middlewares for all vercel webhook routes
vercelWebhookRouter.use(
"/:orgId/:env/*",
vercelSeederMiddleware,
analyticsMiddleware,
);
// Product-level plans (no integrationConfigurationId in path)
vercelWebhookRouter.get(
"/:orgId/:env/v1/products/:productId/plans",
vercelSeederMiddleware,
vercelOidcAuthMiddleware,
...handleListBillingPlansPerInstall,
);
vercelWebhookRouter.get(
"/:orgId/:env/v1/installations/:integrationConfigurationId/plans",
vercelSeederMiddleware,
// --- Installation sub-router ---
// Mounted at /:orgId/:env/v1/installations/:integrationConfigurationId
// All routes get OIDC auth + customer middleware automatically
const installationsRouter = new Hono<HonoEnv>();
installationsRouter.use(
"/*",
vercelOidcAuthMiddleware,
...handleListBillingPlansPerInstall,
vercelCustomerMiddleware,
);
installationsRouter.use(
"/",
vercelOidcAuthMiddleware,
vercelCustomerMiddleware,
);
vercelWebhookRouter.get(
"/:orgId/:env/v1/installations/:integrationConfigurationId",
vercelSeederMiddleware,
vercelOidcAuthMiddleware,
...handleGetInstallation,
// Plans
installationsRouter.get("/plans", ...handleListBillingPlansPerInstall);
// Installation CRUD
installationsRouter.get("/", ...handleGetInstallation);
installationsRouter.put("/", ...handleUpsertInstallation);
installationsRouter.patch("/", ...handleUpdateVercelBillingPlan);
installationsRouter.delete("/", ...handleDeleteInstallation);
// Resources
installationsRouter.post("/resources", ...handleCreateResource);
installationsRouter.get("/resources/:resourceId", ...handleGetResource);
installationsRouter.patch("/resources/:resourceId", ...handleUpdateResource);
installationsRouter.delete("/resources/:resourceId", ...handleDeleteResource);
installationsRouter.post(
"/resources/:resourceId/secrets/rotate",
...handleRotateResourceSecret,
);
vercelWebhookRouter.put(
"/:orgId/:env/v1/installations/:integrationConfigurationId",
vercelSeederMiddleware,
vercelOidcAuthMiddleware,
...handleUpsertInstallation,
);
vercelWebhookRouter.patch(
"/:orgId/:env/v1/installations/:integrationConfigurationId",
vercelSeederMiddleware,
vercelOidcAuthMiddleware,
...handleUpdateVercelBillingPlan,
);
vercelWebhookRouter.post(
"/:orgId/:env/v1/installations/:integrationConfigurationId/resources",
vercelSeederMiddleware,
vercelOidcAuthMiddleware,
...handleCreateResource,
);
vercelWebhookRouter.get(
"/:orgId/:env/v1/installations/:integrationConfigurationId/resources/:resourceId",
vercelSeederMiddleware,
vercelOidcAuthMiddleware,
...handleGetResource,
);
vercelWebhookRouter.patch(
"/:orgId/:env/v1/installations/:integrationConfigurationId/resources/:resourceId",
vercelSeederMiddleware,
vercelOidcAuthMiddleware,
...handleUpdateResource,
);
vercelWebhookRouter.post(
"/:orgId/:env/v1/installations/:integrationConfigurationId/resource-transfer-requests",
vercelSeederMiddleware,
vercelOidcAuthMiddleware,
// Resource transfers
installationsRouter.post(
"/resource-transfer-requests",
...handleCreateResourceTransfer,
);
vercelWebhookRouter.get(
"/:orgId/:env/v1/installations/:integrationConfigurationId/resource-transfer-requests/:providerClaimId/verify",
vercelSeederMiddleware,
vercelOidcAuthMiddleware,
installationsRouter.get(
"/resource-transfer-requests/:providerClaimId/verify",
...handleVerifyResourceTransfer,
);
vercelWebhookRouter.post(
"/:orgId/:env/v1/installations/:integrationConfigurationId/resource-transfer-requests/:providerClaimId/accept",
vercelSeederMiddleware,
vercelOidcAuthMiddleware,
installationsRouter.post(
"/resource-transfer-requests/:providerClaimId/accept",
...handleAcceptResourceTransfer,
);
vercelWebhookRouter.delete(
"/:orgId/:env/v1/installations/:integrationConfigurationId/resources/:resourceId",
vercelSeederMiddleware,
vercelOidcAuthMiddleware,
...handleDeleteResource,
);
vercelWebhookRouter.delete(
vercelWebhookRouter.route(
"/:orgId/:env/v1/installations/:integrationConfigurationId",
vercelSeederMiddleware,
vercelOidcAuthMiddleware,
...handleDeleteInstallation,
);
vercelWebhookRouter.post(
"/:orgId/:env/v1/installations/:integrationConfigurationId/resources/:resourceId/secrets/rotate",
vercelSeederMiddleware,
vercelOidcAuthMiddleware,
...handleRotateResourceSecret,
installationsRouter,
);
// Vercel marketplace webhooks - POST with signature validation
vercelWebhookRouter.post(
"/:orgId/:env/*",
vercelSeederMiddleware,
captureRawBody,
vercelSignatureMiddleware,
vercelLogMiddleware,
async (c) => {
const { db, org, env, logger } = c.get("ctx");
const { org, env, logger } = c.get("ctx");
const ctx = c.get("ctx");
let body: any;
try {
@@ -200,6 +164,6 @@ vercelWebhookRouter.post(
);
// Fallback for other methods
vercelWebhookRouter.all("/:orgId/:env/*", vercelSeederMiddleware, async (c) => {
vercelWebhookRouter.all("/:orgId/:env/*", async (c) => {
return c.body(null, 200);
});

View File

@@ -3,6 +3,7 @@ import type {
AppEnv,
AuthType,
Feature,
FullCustomer,
Organization,
} from "@autumn/shared";
import type { User } from "better-auth";
@@ -37,6 +38,8 @@ export type RequestContext = {
extraLogs: Record<string, unknown>;
fullCustomer?: FullCustomer;
testOptions?: {
skipCacheDeletion?: boolean;
skipWebhooks?: boolean;

View File

@@ -17,6 +17,25 @@ import type { AutumnContext } from "@/honoUtils/HonoEnv.js";
import { validatePropertyPathForJSON } from "@/internal/analytics/actions/eventValidationUtils.js";
import { getBillingCycleStartDate } from "../analyticsUtils.js";
/** Flattens filter_by into indexed filter_key_N / filter_value_N params for Tinybird pipes */
const buildFilterParams = ({
filter_by,
}: {
filter_by?: Record<string, string>;
}): Record<string, string> => {
const params: Record<string, string> = {};
if (!filter_by) return params;
const entries = Object.entries(filter_by).slice(0, 5);
for (let i = 0; i < entries.length; i++) {
const [key, value] = entries[i];
validatePropertyPathForJSON({ propertyKey: key });
params[`filter_key_${i}`] = key;
params[`filter_value_${i}`] = value;
}
return params;
};
const DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
/** Validates and sanitizes timezone string to prevent injection */
@@ -384,13 +403,10 @@ export const aggregate = async ({
entity_id: params.entity_id,
group_column: groupColumn,
property_key: propertyKey,
...buildFilterParams({ filter_by: params.filter_by }),
max_groups: params.max_groups,
};
// ctx.logger.debug("Calling Tinybird aggregate_groupable pipe", {
// pipeParams,
// });
const result = await pipes.aggregateGroupable(pipeParams);
// For external API (enforceGroupLimit), truncated is always false
@@ -421,6 +437,7 @@ export const aggregate = async ({
timezone,
customer_id: params.aggregateAll ? undefined : params.customer_id,
entity_id: params.entity_id,
...buildFilterParams({ filter_by: params.filter_by }),
};
const result = await pipes.aggregateSimple(pipeParams);

View File

@@ -11,6 +11,7 @@ import { format, startOfDay, startOfHour, sub } from "date-fns";
import { Decimal } from "decimal.js";
import { getClickhouseClient } from "@/external/tinybird/initClickhouse.js";
import type { AutumnContext } from "@/honoUtils/HonoEnv.js";
import { validatePropertyPathForJSON } from "@/internal/analytics/actions/eventValidationUtils.js";
import { getBillingCycleStartDate } from "../analyticsUtils.js";
const DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss";
@@ -93,13 +94,26 @@ export const getCountAndSum = async ({
const { startDate, endDate } = await calculateDateRange({ ctx, params });
// Build dynamic filter_by clauses using native JSON sub-column access
let filterBySql = "";
const filterByParams: Record<string, string> = {};
if (params.filter_by) {
const entries = Object.entries(params.filter_by).slice(0, 5);
for (let i = 0; i < entries.length; i++) {
const [key, value] = entries[i];
validatePropertyPathForJSON({ propertyKey: key });
filterBySql += `\n\t\t\tAND properties.${key}::String = {filter_value_${i}:String}`;
filterByParams[`filter_value_${i}`] = value;
}
}
const query = `
WITH customer_events AS (
SELECT *
FROM events
WHERE org_id = {org_id:String} AND env = {env:String}
${params.aggregateAll ? "" : "AND customer_id = {customer_id:String}"}
${params.entity_id ? "AND entity_id = {entity_id:String}" : ""}
${params.entity_id ? "AND entity_id = {entity_id:String}" : ""}${filterBySql}
)
SELECT
e.event_name,
@@ -130,6 +144,7 @@ export const getCountAndSum = async ({
start_date: startDate,
end_date: endDate,
event_names: params.event_names,
...filterByParams,
},
format: "JSON",
});

View File

@@ -2,6 +2,7 @@ import type { ApiEventsListItem } from "@autumn/shared";
import { epochToDateTime } from "@autumn/shared/api/common/epochUtils";
import { getTinybirdPipes } from "@/external/tinybird/initTinybird.js";
import type { AutumnContext } from "@/honoUtils/HonoEnv.js";
import { validatePropertyPathForJSON } from "@/internal/analytics/actions/eventValidationUtils.js";
/** Lists events for the external API with offset-based pagination */
export const listEvents = async ({
@@ -16,6 +17,7 @@ export const listEvents = async ({
custom_range?: { start?: number; end?: number };
offset: number;
limit: number;
filter_by?: Record<string, string>;
};
}) => {
const pipes = getTinybirdPipes();
@@ -41,6 +43,18 @@ export const listEvents = async ({
limit: params.limit,
});
// Build filter_by indexed params
const filterParams: Record<string, string> = {};
if (params.filter_by) {
const entries = Object.entries(params.filter_by).slice(0, 5);
for (let i = 0; i < entries.length; i++) {
const [key, value] = entries[i];
validatePropertyPathForJSON({ propertyKey: key });
filterParams[`filter_key_${i}`] = key;
filterParams[`filter_value_${i}`] = value;
}
}
const startTime = performance.now();
const result = await pipes.listEventsPaginated({
org_id: org.id,
@@ -52,6 +66,7 @@ export const listEvents = async ({
event_names: params.feature_ids,
limit: fetchLimit,
offset: params.offset,
...filterParams,
});
const queryDuration = performance.now() - startTime;

View File

@@ -31,6 +31,7 @@ export const handleExternalAggregateEvents = createRoute({
range,
bin_size,
custom_range,
filter_by,
max_groups,
} = c.req.valid("json");
@@ -42,6 +43,7 @@ export const handleExternalAggregateEvents = createRoute({
range,
bin_size,
custom_range,
filter_by,
});
let customer: Awaited<ReturnType<typeof CusService.getFull>> | undefined;
@@ -86,6 +88,7 @@ export const handleExternalAggregateEvents = createRoute({
bin_size: bin_size ?? "day",
custom_range,
enforceGroupLimit: true,
filter_by,
max_groups,
},
}),
@@ -100,6 +103,7 @@ export const handleExternalAggregateEvents = createRoute({
customer,
custom_range,
bin_size: bin_size ?? "day",
filter_by,
},
}),
]);

View File

@@ -26,6 +26,7 @@ export const handleExternalListEvents = createRoute({
custom_range: validatedParams.custom_range,
offset: validatedParams.offset,
limit: validatedParams.limit,
filter_by: validatedParams.filter_by,
},
});

View File

@@ -30,6 +30,21 @@ SQL >
{% if defined(entity_id) %}
AND entity_id = {{ String(entity_id) }}
{% end %}
{% if defined(filter_key_0) and String(filter_key_0, '') != '' %}
AND {{ column('properties.' + String(filter_key_0, '')) }}::String = {{ String(filter_value_0, '') }}
{% end %}
{% if defined(filter_key_1) and String(filter_key_1, '') != '' %}
AND {{ column('properties.' + String(filter_key_1, '')) }}::String = {{ String(filter_value_1, '') }}
{% end %}
{% if defined(filter_key_2) and String(filter_key_2, '') != '' %}
AND {{ column('properties.' + String(filter_key_2, '')) }}::String = {{ String(filter_value_2, '') }}
{% end %}
{% if defined(filter_key_3) and String(filter_key_3, '') != '' %}
AND {{ column('properties.' + String(filter_key_3, '')) }}::String = {{ String(filter_value_3, '') }}
{% end %}
{% if defined(filter_key_4) and String(filter_key_4, '') != '' %}
AND {{ column('properties.' + String(filter_key_4, '')) }}::String = {{ String(filter_value_4, '') }}
{% end %}
NODE aggregate_by_period
TYPE endpoint

View File

@@ -49,6 +49,21 @@ SQL >
{% if defined(entity_id) and String(entity_id, '') != '' %}
AND entity_id = {{ String(entity_id) }}
{% end %}
{% if defined(filter_key_0) and String(filter_key_0, '') != '' %}
AND {{ column('properties.' + String(filter_key_0, '')) }}::String = {{ String(filter_value_0, '') }}
{% end %}
{% if defined(filter_key_1) and String(filter_key_1, '') != '' %}
AND {{ column('properties.' + String(filter_key_1, '')) }}::String = {{ String(filter_value_1, '') }}
{% end %}
{% if defined(filter_key_2) and String(filter_key_2, '') != '' %}
AND {{ column('properties.' + String(filter_key_2, '')) }}::String = {{ String(filter_value_2, '') }}
{% end %}
{% if defined(filter_key_3) and String(filter_key_3, '') != '' %}
AND {{ column('properties.' + String(filter_key_3, '')) }}::String = {{ String(filter_value_3, '') }}
{% end %}
{% if defined(filter_key_4) and String(filter_key_4, '') != '' %}
AND {{ column('properties.' + String(filter_key_4, '')) }}::String = {{ String(filter_value_4, '') }}
{% end %}
{% if String(group_column, 'property') == 'entity_id' %}
AND entity_id IS NOT NULL AND entity_id != ''
{% elif String(group_column, 'property') == 'property' %}

View File

@@ -31,6 +31,21 @@ SQL >
{% if defined(entity_id) and String(entity_id, '') != '' %}
AND entity_id = {{ String(entity_id) }}
{% end %}
{% if defined(filter_key_0) and String(filter_key_0, '') != '' %}
AND {{ column('properties.' + String(filter_key_0, '')) }}::String = {{ String(filter_value_0, '') }}
{% end %}
{% if defined(filter_key_1) and String(filter_key_1, '') != '' %}
AND {{ column('properties.' + String(filter_key_1, '')) }}::String = {{ String(filter_value_1, '') }}
{% end %}
{% if defined(filter_key_2) and String(filter_key_2, '') != '' %}
AND {{ column('properties.' + String(filter_key_2, '')) }}::String = {{ String(filter_value_2, '') }}
{% end %}
{% if defined(filter_key_3) and String(filter_key_3, '') != '' %}
AND {{ column('properties.' + String(filter_key_3, '')) }}::String = {{ String(filter_value_3, '') }}
{% end %}
{% if defined(filter_key_4) and String(filter_key_4, '') != '' %}
AND {{ column('properties.' + String(filter_key_4, '')) }}::String = {{ String(filter_value_4, '') }}
{% end %}
GROUP BY
period,
event_name

View File

@@ -38,6 +38,21 @@ SQL >
{% if defined(entity_id) and String(entity_id, '') != '' %}
AND entity_id = {{ String(entity_id) }}
{% end %}
{% if defined(filter_key_0) and String(filter_key_0, '') != '' %}
AND positionCaseInsensitive(assumeNotNull(properties), concat('"', {{ String(filter_key_0, '') }}, '":"', {{ String(filter_value_0, '') }}, '"')) > 0
{% end %}
{% if defined(filter_key_1) and String(filter_key_1, '') != '' %}
AND positionCaseInsensitive(assumeNotNull(properties), concat('"', {{ String(filter_key_1, '') }}, '":"', {{ String(filter_value_1, '') }}, '"')) > 0
{% end %}
{% if defined(filter_key_2) and String(filter_key_2, '') != '' %}
AND positionCaseInsensitive(assumeNotNull(properties), concat('"', {{ String(filter_key_2, '') }}, '":"', {{ String(filter_value_2, '') }}, '"')) > 0
{% end %}
{% if defined(filter_key_3) and String(filter_key_3, '') != '' %}
AND positionCaseInsensitive(assumeNotNull(properties), concat('"', {{ String(filter_key_3, '') }}, '":"', {{ String(filter_value_3, '') }}, '"')) > 0
{% end %}
{% if defined(filter_key_4) and String(filter_key_4, '') != '' %}
AND positionCaseInsensitive(assumeNotNull(properties), concat('"', {{ String(filter_key_4, '') }}, '":"', {{ String(filter_value_4, '') }}, '"')) > 0
{% end %}
ORDER BY timestamp DESC, id DESC
LIMIT {{ Int32(limit, 101) }}
OFFSET {{ Int32(offset, 0) }}

View File

@@ -55,6 +55,9 @@ export const ExtEventsAggregateParamsSchema = z.object({
description:
"Custom time range to aggregate events for. If provided, range must not be provided",
}),
filter_by: z.record(z.string(), z.string()).optional().meta({
description:
'Filter events by property values, e.g. {"model": "gpt-4", "region": "us"}. Maximum 5 filters.',
max_groups: z.number().int().min(1).max(250).optional().meta({
description:
"Maximum number of distinct group values to return per time bin when using group_by. Remaining values are bundled into an 'Other' bucket. Defaults to 9",
@@ -75,6 +78,13 @@ export const EventsAggregateParamsSchema =
path: ["custom_range", "range"],
},
)
.refine(
(data) => !data.filter_by || Object.keys(data.filter_by).length <= 5,
{
message: "filter_by supports a maximum of 5 filters",
path: ["filter_by"],
},
)
.transform((data) => {
if (!data.range && !data.custom_range) {
return { ...data, range: "1bc" as const };

View File

@@ -30,6 +30,17 @@ export const ApiEventsListParamsSchema = createPaginationParamsSchema({
})
.optional()
.describe("Filter events by time range"),
filter_by: z
.record(z.string(), z.string())
.refine((val) => Object.keys(val).length <= 5, {
message: "filter_by supports a maximum of 5 filters",
})
.optional()
.meta({
internal: true,
description:
'Filter events by property values, e.g. {"model": "gpt-4", "region": "us"}. Maximum 5 filters.',
}),
});
export type ApiEventsListParams = z.infer<typeof ApiEventsListParamsSchema>;

View File

@@ -26,6 +26,7 @@ export type TotalEventsParams = {
interval?: RangeEnum;
customer?: FullCustomer;
bin_size: BinSizeEnum;
filter_by?: Record<string, string>;
};
export type TimeseriesEventsParams = TotalEventsParams & {

View File

@@ -87,9 +87,7 @@ export const ConfigureVercel = () => {
setVercelConfig((prev) => ({
...prev,
allowed_product_ids_live:
vercelOrgConfig.allowed_product_ids_live ??
[],
allowed_product_ids_live: vercelOrgConfig.allowed_product_ids_live ?? [],
allowed_product_ids_sandbox:
vercelOrgConfig.allowed_product_ids_sandbox ?? [],
}));
@@ -103,10 +101,12 @@ export const ConfigureVercel = () => {
value: product.id,
}));
const currentClientIntegrationId = org?.processor_configs?.vercel?.client_integration_id
const currentClientSecret = org?.processor_configs?.vercel?.client_secret
const currentWebhookUrl = org?.processor_configs?.vercel?.webhook_url
const currentCustomPaymentMethod = org?.processor_configs?.vercel?.custom_payment_method
const currentClientIntegrationId =
org?.processor_configs?.vercel?.client_integration_id;
const currentClientSecret = org?.processor_configs?.vercel?.client_secret;
const currentWebhookUrl = org?.processor_configs?.vercel?.webhook_url;
const currentCustomPaymentMethod =
org?.processor_configs?.vercel?.custom_payment_method;
const { isDark } = useTheme();
@@ -140,8 +140,7 @@ export const ConfigureVercel = () => {
if (env === "live") {
filteredConfig.webhook_url = vercelConfig.webhook_url.trim();
} else {
filteredConfig.sandbox_webhook_url =
vercelConfig.webhook_url.trim();
filteredConfig.sandbox_webhook_url = vercelConfig.webhook_url.trim();
}
}
@@ -177,7 +176,8 @@ export const ConfigureVercel = () => {
client_secret: "",
webhook_url: "",
custom_payment_method: "",
marketplace_mode: filteredConfig.marketplace_mode as VercelMarketplaceMode,
marketplace_mode:
filteredConfig.marketplace_mode as VercelMarketplaceMode,
}));
} else {
toast.error("Failed to update Vercel config");
@@ -241,29 +241,11 @@ export const ConfigureVercel = () => {
}))
}
placeholder={
currentClientSecret ||
"eg. VAxvZFz8ST4d5b9pa2EuXkWG"
currentClientSecret || "eg. VAxvZFz8ST4d5b9pa2EuXkWG"
}
/>
</div>
<div>
<FormLabel className="mb-1">
<span className="text-t2">Webhook URL</span>
</FormLabel>
<Input
value={vercelConfig.webhook_url || ""}
onChange={(e) =>
setVercelConfig((prev) => ({
...prev,
webhook_url: e.target.value,
}))
}
placeholder={
currentWebhookUrl || "eg. https://example.com/api/webhooks"
}
/>
</div>
<div>
<div className="col-span-2">
<FormLabel className="mb-1">
<span className="text-t2">
Stripe Custom Payment Method ID
@@ -297,7 +279,9 @@ export const ConfigureVercel = () => {
</div>
<div className="col-span-2">
<FormLabel className="mb-1">
<span className="text-t2">Allowed Product IDs (Optional)</span>
<span className="text-t2">
Allowed Product IDs (Optional)
</span>
</FormLabel>
<p className="text-t3 text-sm mb-2">
Optional: choose product IDs to show in Vercel plans.
@@ -314,8 +298,9 @@ export const ConfigureVercel = () => {
<div className="p-2 text-t6">No products found</div>
) : (
productOptions.map((option) => {
const isSelected =
activeAllowedProductIds.includes(option.value);
const isSelected = activeAllowedProductIds.includes(
option.value,
);
return (
<div
key={option.value}
@@ -338,7 +323,10 @@ export const ConfigureVercel = () => {
? activeAllowedProductIds.filter(
(id) => id !== option.value,
)
: [...activeAllowedProductIds, option.value];
: [
...activeAllowedProductIds,
option.value,
];
setActiveAllowedProductIds(nextValue);
setOpen(false);
}
@@ -373,7 +361,7 @@ export const ConfigureVercel = () => {
</Card>
<div>
<FormLabel className="mb-1">
<FormLabel className="mb-0">
<span className="text-t2">Base URL</span>
</FormLabel>
<p className="text-t3 text-sm mb-2">
@@ -386,6 +374,7 @@ export const ConfigureVercel = () => {
{env === "live" ? "Live" : "Sandbox"}
</CodeGroupTab>
<CodeGroupCopyButton
className="h-full"
onCopy={() =>
navigator.clipboard.writeText(
`https://api.useautumn.com/webhooks/vercel/${org?.id}/${env}`,
@@ -396,7 +385,7 @@ export const ConfigureVercel = () => {
<CodeGroupContent
value={env}
copyText={`https://api.useautumn.com/webhooks/vercel/${org?.id}/${env}`}
className="border-t"
className="p-2 border-t-0"
>
<CodeGroupCodeSolidColour className="text-primary">{`https://api.useautumn.com/webhooks/vercel/${org?.id}/${env}`}</CodeGroupCodeSolidColour>
</CodeGroupContent>