diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock index 774e937..9257bbf 100644 --- a/.speakeasy/gen.lock +++ b/.speakeasy/gen.lock @@ -1,29 +1,29 @@ lockVersion: 2.0.0 id: 0c8d1667-2710-4860-aee3-7d221dbc0a60 management: - docChecksum: be5c022f6de13e02a50df9b4c318826c + docChecksum: fc0fbb532e5f78af1c7abbcd4147185e docVersion: 1.0.0 - speakeasyVersion: 1.771.0 - generationVersion: 2.893.0 - releaseVersion: 1.2.0 - configChecksum: c4c3331ffaa1803aa7003ee9cf596fc7 + speakeasyVersion: 1.788.1 + generationVersion: 2.915.1 + releaseVersion: 1.3.0 + configChecksum: c05e65bfebb246dd7bde95e549f3a7f1 repoURL: https://github.com/kombohq/python-sdk.git installationURL: https://github.com/kombohq/python-sdk.git published: true persistentEdits: - generation_id: 8376918f-2882-4652-8c06-6e1d5686c1dd - pristine_commit_hash: bf630fb39ba1f183d8d4111c242004c3338bff3b - pristine_tree_hash: ed6ab239daa1155eeee85e35248e749660a23339 + generation_id: 8e2cf4c9-d5b6-43f7-8d5f-a0cd8c7d514d + pristine_commit_hash: e212544058faf065b67de483d3bb24f4f07aae7f + pristine_tree_hash: 14973905af9ed8130657d5e5822ff861752f1f0d features: python: additionalDependencies: 1.1.0 constsAndDefaults: 1.0.7 - core: 6.0.24 + core: 6.0.34 defaultEnabledRetries: 0.2.0 deprecations: 3.0.2 enumUnions: 0.1.1 envVarSecurityUsage: 0.3.3 - errors: 3.3.6 + errors: 3.4.4 flatRequests: 1.0.1 flattening: 3.1.1 globalSecurity: 3.0.7 @@ -34,17 +34,17 @@ features: groups: 3.0.1 hiddenGlobals: 1.0.0 ignores: 3.0.1 - methodArguments: 1.1.0 + methodArguments: 1.1.1 nameOverrides: 3.0.3 nullables: 1.0.2 openEnums: 1.0.4 operationTimeout: 0.3.1 pagination: 3.0.10 responseFormat: 1.1.0 - retries: 3.0.5 - sdkHooks: 1.2.1 + retries: 3.0.7 + sdkHooks: 1.3.0 serverIDs: 3.0.0 - unions: 3.1.5 + unions: 3.1.7 webhooks: 2.0.0 trackedFiles: .gitattributes: @@ -1885,8 +1885,8 @@ trackedFiles: pristine_git_object: 95d7af043b98494373f18f3ceae6a530e7e4af71 docs/models/integrationtool.md: id: 59f82e2d180c - last_write_checksum: sha1:155c697eca020f2addbea35baa181b5a406813aa - pristine_git_object: a3fdc3a9b931b0b8dee0bd1eac2b0002da6b52b7 + last_write_checksum: sha1:340548ac9ce660155565daefbe4d7fa26dd94d13 + pristine_git_object: f7fcfdec1a72d6a98beda42efa893521164bbe90 docs/models/internal/globals.md: id: 9c173b87f41f last_write_checksum: sha1:3969d44e1ad9258f466c40b241681eb82c1ac29a @@ -1977,8 +1977,8 @@ trackedFiles: pristine_git_object: 61484b6897a799eaefce5b61a74f6bc7a1371218 docs/models/name.md: id: 6ee802922293 - last_write_checksum: sha1:d91030a1a0109cce72f3f6d513f4f5bb25165314 - pristine_git_object: 21cfd6dc2101725c2efc74b23bf84203eabf0678 + last_write_checksum: sha1:e4f5b729f367089adc515c2a3f36e5ee65c0bc60 + pristine_git_object: 28421643cb2ac83b43148b8985ecd920e1ceed1d docs/models/offer.md: id: e20e1bb1fed4 last_write_checksum: sha1:bcc00146d8b5e5498314dda3c71ccc3839531f38 @@ -2463,6 +2463,10 @@ trackedFiles: id: ba2ad2a72373 last_write_checksum: sha1:0be2bc26f3b7b42af19599230742e52427622836 pristine_git_object: 6e91e32d74176c28dbc8e064fedff4633782045e + docs/models/postatscandidatesrequestbodyaktiv.md: + id: b1a9b6838577 + last_write_checksum: sha1:548881e6b8e795dab7bf3684a0c815f7fe74caba + pristine_git_object: 8062598746c2603b44d0f94fe3541d37741c0d38 docs/models/postatscandidatesrequestbodyanswer.md: id: 34fa4def625e last_write_checksum: sha1:9421c6b15946056ae3e7ed55bd0d265e900e2b4f @@ -2521,8 +2525,8 @@ trackedFiles: pristine_git_object: 825cc4294186d38f956660ceb702f343bc8fb643 docs/models/postatscandidatesrequestbodycovetorestcandidate.md: id: 3da95f5ce314 - last_write_checksum: sha1:8bd175ad12a83e7bcf5826603f356d4b262d52d7 - pristine_git_object: 95eb78e5cff47ac19f472a82bddeadddce682290 + last_write_checksum: sha1:4cc2fb5a3c919b7932d2998bdc04b38f0c58ea51 + pristine_git_object: c6ca9a888d9e8b2c89afce97516b7598fe3c2b85 docs/models/postatscandidatesrequestbodydegreereference.md: id: 80f9c5593c46 last_write_checksum: sha1:57b4c36ae98e1a1ba2ba3189ccac93dca297457d @@ -3063,6 +3067,10 @@ trackedFiles: id: 13103fe3fd19 last_write_checksum: sha1:5e7daafbc534116496a45c46619daeec1332d335 pristine_git_object: 022677d19d941a59776acfaba3d052840ecbbd07 + docs/models/postatsjobsjobidapplicationsrequestbodyaktiv.md: + id: b004afc8c1c0 + last_write_checksum: sha1:366937ba3b4a58852d1b485b548a49a1d5a1f76d + pristine_git_object: 23770fa4d78810c2a7e018cb6daae97a19ca2f06 docs/models/postatsjobsjobidapplicationsrequestbodyanswer.md: id: 8ceefc23692d last_write_checksum: sha1:df5dc671e8e16b9269640c4181e3bf18da23bbef @@ -3117,8 +3125,8 @@ trackedFiles: pristine_git_object: 806f3e2cbf4f21c6cc3958a22fe3dbb9d152e23a docs/models/postatsjobsjobidapplicationsrequestbodycovetorestcandidate.md: id: b6369fa618d1 - last_write_checksum: sha1:9b3a77793f8e3165dcfc691d7d4627b10c829dfc - pristine_git_object: 5cfee8656170c245508522e7629fc67c6a9dee96 + last_write_checksum: sha1:d27d8d36d275c39f5d58173891ed2c903a171d29 + pristine_git_object: 6eacb69599d87903add129ef984d0afb05d66f96 docs/models/postatsjobsjobidapplicationsrequestbodydegreereference.md: id: 0691556b8773 last_write_checksum: sha1:e4fd8479dfb23366dfc26024b82a16f9472aa8d0 @@ -4201,8 +4209,8 @@ trackedFiles: pristine_git_object: cb268794ca5a2389305a908323d1585a0c88d9c4 docs/sdks/general/README.md: id: ce0ada6fa2e1 - last_write_checksum: sha1:fc2bcb3eaca98e61519628c732230ea822daa573 - pristine_git_object: c2b2f9a2d73719786c624ce68468f7e5d0db94f7 + last_write_checksum: sha1:85406ebc6846b1fc9982a7fddc1a47f13087a53f + pristine_git_object: f139ec18ad638a09653e01a55412d7e8bd391c04 docs/sdks/hris/README.md: id: 0baa868a038c last_write_checksum: sha1:f7f2b3d812a1b1b4097d81977cda0a7384585325 @@ -4217,8 +4225,8 @@ trackedFiles: pristine_git_object: f456032107a9387ba6c98afd1c981df2f4b3d636 pyproject.toml: id: 5d07e7d72637 - last_write_checksum: sha1:580500cc0af793786031feb5fab582372a8f9b1a - pristine_git_object: 9af6c441766a04c799f00e85cb771e1c8479df69 + last_write_checksum: sha1:7d8198c69351b1e8481f05c8eb5f6d57e834e6ca + pristine_git_object: a3d7227f4fb2abe17e4bc28ab67f9bc128ace02f scripts/prepare_readme.py: id: e0c5957a6035 last_write_checksum: sha1:b6ad6f0515a952d7cb052befddb6a117d4f627d8 @@ -4241,28 +4249,28 @@ trackedFiles: pristine_git_object: 957ab835887fcd1ed6179f279216d1564658a64d src/kombo/_hooks/types.py: id: d10dbc8d43bf - last_write_checksum: sha1:01ca050bbb2089c0e883d81481ecf666f173db63 - pristine_git_object: e589e541e5fc70d336de44780721f301d754ed72 + last_write_checksum: sha1:c4c47ba7de7a15992749f48dc7c557f733d6fc35 + pristine_git_object: 460080ad13f20f8eac822635c7778a371e892c5d src/kombo/_version.py: id: 45cf440ad1df - last_write_checksum: sha1:195c140de357d9f060a7ff64bc953de837f17b5e - pristine_git_object: e8690c6b73fdf6fdfc80750a56674d6616dcb68c + last_write_checksum: sha1:c570193e97b9319c041a76b203b26ba5e612d8a4 + pristine_git_object: 30bba2f4e956026b74b5097c3130241c22554c41 src/kombo/assessment.py: id: aec6e8a7589f - last_write_checksum: sha1:8d496d8f3b781a727642d4b4f05b598a2eb73312 - pristine_git_object: 3ce2821942baa15829f5ffa13da682d1c1459678 + last_write_checksum: sha1:4d155741d6e52c6b6fcb93cccb6dd2efd191cfb5 + pristine_git_object: b2c845ee7e48489c5dcccb8893d7ca6c8ad123bf src/kombo/ats.py: id: a9839762f5c3 - last_write_checksum: sha1:692427a4775843bded62cc15174c702a7c304501 - pristine_git_object: 4f7b1fd0bb79d601b5ba82ea5b68b56411519c18 + last_write_checksum: sha1:fa4e0f1f58d5118eb747f0f82993c0aea00a3549 + pristine_git_object: d530bb5da99f8f383938653248c7e3585af5922d src/kombo/basesdk.py: id: 8f30a0bd36ff last_write_checksum: sha1:f7cceecb507a387fd50740b9f4cd3cfe5cb3451b pristine_git_object: 9c2ead27b9e5aa9b765bca459a622ddc5e7510c3 src/kombo/connect.py: id: 057799091fa5 - last_write_checksum: sha1:0ce4e74d86c4da1661801e46e07d9f690f2ef4b3 - pristine_git_object: 25bcea1808d0306086d84946249b50913015b63f + last_write_checksum: sha1:cc16c3e36fb98b1cbb410a21ff70a3687accca66 + pristine_git_object: 7ec7a442f478373dee46c60785f0c94a329f959a src/kombo/errors/__init__.py: id: bba7abca7635 last_write_checksum: sha1:e86275cda1b1c87ef6f05fc40834739f333488a2 @@ -4297,20 +4305,20 @@ trackedFiles: pristine_git_object: 16ac2977e80b6eabe4020aa8a21dd28e83032f9a src/kombo/general.py: id: 107ecb9f3651 - last_write_checksum: sha1:ab187ee80dce4bc01acfd1c0f198d222c2f90152 - pristine_git_object: 300563cfc39258f4cef7d0f239783237c3ddf106 + last_write_checksum: sha1:f7620f6f1b6e2e3912d33fb5b92f8310a0d05629 + pristine_git_object: 34c9b45174af69502ee687311a5c0e9ad04dd80d src/kombo/hris.py: id: 9ba1b37ab10a - last_write_checksum: sha1:d1ca512354d793007457f28726e1328c33f4e07e - pristine_git_object: 8cd4b95a3689eaf1bb3a3b722dff73e155bd07e7 + last_write_checksum: sha1:97e4f56bfc487316cbbb5ecdd812933c0104105c + pristine_git_object: 69084b4e952dc5efeaf58070aaf57d9f7c1c7cd8 src/kombo/httpclient.py: id: 4e74c7821304 last_write_checksum: sha1:5e55338d6ee9f01ab648cad4380201a8a3da7dd7 pristine_git_object: 89560b566073785535643e694c112bedbd3db13d src/kombo/models/__init__.py: id: 45e6e8c7f07f - last_write_checksum: sha1:dfd0ef20f72098a755ffbba3d6c77a471a80f6e8 - pristine_git_object: be1fd21d250f0529d6d889f3c80d65d57aaff1ea + last_write_checksum: sha1:202e90805768dd8e9aba69c0e9b5e84b2c12031b + pristine_git_object: d25f8e8c3c15826dc3fee4585e403fa562cba22c src/kombo/models/assessmentorderreceivedwebhookpayload.py: id: 532c2db2ee93 last_write_checksum: sha1:a89544ec063f76ec1faa875bf51141a32963ef51 @@ -4321,8 +4329,8 @@ trackedFiles: pristine_git_object: ab1a25921a9f02ed68cee5bfad5b7c6f567acd82 src/kombo/models/datachangedwebhookpayload.py: id: a4be1cf7f915 - last_write_checksum: sha1:fd82319ed085fe8168817975a6bee18a595f374c - pristine_git_object: 5b09624c7e8bbb345e916f61b956518c1f6e8c06 + last_write_checksum: sha1:2c8ff903b982a0ee89ae613e34424281dea05f4d + pristine_git_object: 2572b04f5a8b0b3dd11e18c23ca45dae47ae1cf9 src/kombo/models/deleteatscandidatescandidateidtagsop.py: id: e636f19f3437 last_write_checksum: sha1:88443050e0c1c2de5c660f3b2ddc92c49d022e44 @@ -4773,8 +4781,8 @@ trackedFiles: pristine_git_object: 7a97ad39aca8886d0999a4573a69626c1bfc5cbb src/kombo/models/postatscandidatesrequestbody.py: id: ac6e98f043e9 - last_write_checksum: sha1:1c2a00a300c5ff1c41c1e229b27d12ffe151fe1c - pristine_git_object: 8b75b535aac4db5cc21e39e15b5741750f310f15 + last_write_checksum: sha1:d16a8de7664b303200e1e54e7e55604f23aaba69 + pristine_git_object: 10c979af1efc590bad89da93b81f8179975d9dbc src/kombo/models/postatsimporttrackedapplicationop.py: id: d36d9960022a last_write_checksum: sha1:e0aa98b306d9e4852785f10e40e97c34f084efef @@ -4797,16 +4805,16 @@ trackedFiles: pristine_git_object: 20ba13411c0885c7b43e5c4c0d6ae721b13f02e1 src/kombo/models/postatsjobsjobidapplicationsrequestbody.py: id: a451a5e6b515 - last_write_checksum: sha1:09db6b0487d91fec741b7ad576d7e4ea07f8d916 - pristine_git_object: 21542d5073ab790ad7230b4065c2f3ba1ef89a19 + last_write_checksum: sha1:8918091ab51b4d494cc6c18e365455df66067a21 + pristine_git_object: 09113eee9879092ca797921e9fbac75d683ae394 src/kombo/models/postconnectcreatelinkpositiveresponse.py: id: a3271239a82f last_write_checksum: sha1:db8f52f9bed614766c9bd4c0f1286ee5859b38f8 pristine_git_object: 91e8d75513c8015aeb3f8dd2e38e2ec090b0770c src/kombo/models/postconnectcreatelinkrequestbody.py: id: 8ae6871fd392 - last_write_checksum: sha1:af4e8bf4687b98a3060358158d7b05ef8c394b31 - pristine_git_object: c0cd102fdac772f321cdbbc75528a7f0a188f11e + last_write_checksum: sha1:c9317c0f66a761f77ba5af1bd91e5d8e48e0c461 + pristine_git_object: 51ad9fba7a2e4af53339981c721847cc72b9023e src/kombo/models/postforcesyncop.py: id: 695738b0e4fb last_write_checksum: sha1:4288d66c5efda40419ee3602e124d5186662a99e @@ -5033,8 +5041,8 @@ trackedFiles: pristine_git_object: faa268137bc01c9d08cfadc4797017db48747a96 src/kombo/types/base64fileinput.py: id: 70d02f7057ad - last_write_checksum: sha1:4780e893d3853b5a6e28d9a6ca3ee102ce0f502d - pristine_git_object: 25fc53989ed497649363f983219fc58705c8bf87 + last_write_checksum: sha1:1522687ae3398374c35710cad993a6e82b5ab99d + pristine_git_object: 862566fe2b1db830276b390e136e65090e5963d2 src/kombo/types/basemodel.py: id: fcedd4cc094d last_write_checksum: sha1:10d84aedeb9d35edfdadf2c3020caa1d24d8b584 @@ -5061,12 +5069,12 @@ trackedFiles: pristine_git_object: 3324e1bc2668c54c4d5f5a1a845675319757a828 src/kombo/utils/eventstreaming.py: id: 5014efc778bb - last_write_checksum: sha1:620d78a8b4e3b854e08d136e02e40a01a786bd70 - pristine_git_object: 3bdcd6d3d4fc772cb7f5fca8685dcdc8c85e13e8 + last_write_checksum: sha1:7d1dc68f8b48486ab646653aa05cc38752e1f912 + pristine_git_object: a8d4fe5cc88d3c7337339e1b36a61bbf7ca8c4eb src/kombo/utils/forms.py: id: 99d47e485fec - last_write_checksum: sha1:15fa7e9ab1611e062a9984cf06cb20969713d295 - pristine_git_object: f961e76beaf0a8b1fe0dda44754a74eebd3608e7 + last_write_checksum: sha1:a971cdb120ad3d416d296d5d0ad89e4808350a7f + pristine_git_object: fdf0dc9b2a67bca773eefe6b471498cccaa83424 src/kombo/utils/headers.py: id: d586650ae4bc last_write_checksum: sha1:7c6df233ee006332b566a8afa9ce9a245941d935 @@ -5089,16 +5097,16 @@ trackedFiles: pristine_git_object: 591415af8e64baa410627b507d2740afb5387d13 src/kombo/utils/retries.py: id: bc594ff11adc - last_write_checksum: sha1:471372f5c5d1dd5583239c9cf3c75f1b636e5d87 - pristine_git_object: af07d4e941007af4213c5ec9047ef8a2fca04e5e + last_write_checksum: sha1:3585b891142f30a597fbf7a2f0340700babef8e4 + pristine_git_object: ca7b59efebbbd9545744d0207ef42725c4cc5143 src/kombo/utils/security.py: id: acd4ded0aa8d last_write_checksum: sha1:c11eef495b6aaa249178c24c796940cc540b7a00 pristine_git_object: 42d8d78e9981eed7507670014d99588e27ab325a src/kombo/utils/serializers.py: id: 5d7d8c5e2d73 - last_write_checksum: sha1:61009f2e4ef6613a1a5af813fe020373dae5a492 - pristine_git_object: d2149f8b909cb96628db140ac3cddb1b1e981367 + last_write_checksum: sha1:7485f1425b0661fd84836186570df90207eec6af + pristine_git_object: 1031ed930bad5ece220cf7416a56c29f40f0588b src/kombo/utils/unmarshal_json_response.py: id: 78f7ac328026 last_write_checksum: sha1:e2ea836c8f9063fbf985278bb705dec1a077ca25 @@ -7714,7 +7722,7 @@ examples: default: application/json: {"status": "error", "error": {"code": "PLATFORM.RATE_LIMIT_EXCEEDED", "title": null, "message": "", "log_url": "https://married-yin.org/"}} examplesVersion: 1.0.2 -releaseNotes: "## Python SDK Changes:\n* `kombo.hris.get_employees()`: `error.code.enum(hris.staffing_entity_closed)` **Added** (Breaking ⚠️)\n* `kombo.hris.get_employee_form()`: \n * `request` **Changed** (Breaking ⚠️)\n * `error.code.enum(hris.staffing_entity_closed)` **Added** (Breaking ⚠️)\n* `kombo.hris.create_employee_with_form()`: \n * `request.staffing_entity_id` **Added**\n * `error.code.enum(hris.staffing_entity_closed)` **Added** (Breaking ⚠️)\n* `kombo.hris.add_employee_document()`: `error.code.enum(hris.staffing_entity_closed)` **Added** (Breaking ⚠️)\n* `kombo.hris.get_employee_document_categories()`: `error.code.enum(hris.staffing_entity_closed)` **Added** (Breaking ⚠️)\n* `kombo.hris.get_groups()`: `error.code.enum(hris.staffing_entity_closed)` **Added** (Breaking ⚠️)\n* `kombo.hris.get_employments()`: `error.code.enum(hris.staffing_entity_closed)` **Added** (Breaking ⚠️)\n* `kombo.hris.get_locations()`: `error.code.enum(hris.staffing_entity_closed)` **Added** (Breaking ⚠️)\n* `kombo.hris.get_absence_types()`: `error.code.enum(hris.staffing_entity_closed)` **Added** (Breaking ⚠️)\n* `kombo.hris.get_time_off_balances()`: `error.code.enum(hris.staffing_entity_closed)` **Added** (Breaking ⚠️)\n* `kombo.hris.get_absences()`: `error.code.enum(hris.staffing_entity_closed)` **Added** (Breaking ⚠️)\n* `kombo.hris.create_absence()`: `error.code.enum(hris.staffing_entity_closed)` **Added** (Breaking ⚠️)\n* `kombo.hris.delete_absence()`: `error.code.enum(hris.staffing_entity_closed)` **Added** (Breaking ⚠️)\n* `kombo.hris.get_legal_entities()`: `error.code.enum(hris.staffing_entity_closed)` **Added** (Breaking ⚠️)\n* `kombo.hris.get_timesheets()`: `error.code.enum(hris.staffing_entity_closed)` **Added** (Breaking ⚠️)\n* `kombo.hris.get_performance_review_cycles()`: `error.code.enum(hris.staffing_entity_closed)` **Added** (Breaking ⚠️)\n* `kombo.hris.get_performance_reviews()`: `error.code.enum(hris.staffing_entity_closed)` **Added** (Breaking ⚠️)\n* `kombo.hris.get_staffing_entities()`: `error.code.enum(hris.staffing_entity_closed)` **Added** (Breaking ⚠️)\n* `kombo.ats.create_candidate()`: \n * `request.remote_fields.covetorest.candidate.status` **Added**\n* `kombo.ats.create_application()`: \n * `request.remote_fields.covetorest.candidate.status` **Added**\n* `kombo.assessment.update_order_result()`: \n * `request.remote_fields.workday` **Added**\n* `kombo.connect.create_connection_link()`: `request.integration_tool` **Changed**\n" +releaseNotes: "## Python SDK Changes:\n* `kombo.ats.create_candidate()`: \n * `request.remote_fields.covetorest.candidate.aktiv` **Added**\n* `kombo.ats.create_application()`: \n * `request.remote_fields.covetorest.candidate.aktiv` **Added**\n* `kombo.connect.create_connection_link()`: `request.integration_tool` **Changed**\n" generatedFiles: - .gitattributes - .vscode/settings.json diff --git a/.speakeasy/gen.yaml b/.speakeasy/gen.yaml index aa0d58c..f782145 100644 --- a/.speakeasy/gen.yaml +++ b/.speakeasy/gen.yaml @@ -31,7 +31,7 @@ generation: generateNewTests: true skipResponseBodyAssertions: false python: - version: 1.2.0 + version: 1.3.0 additionalDependencies: dev: inline-snapshot: '>=0.13.0' @@ -53,6 +53,10 @@ python: description: The official Python SDK for the Kombo Unified API enableCustomCodeRegions: false enumFormat: union + errorSchemaValidation: true + eventStreamClassNames: + async: EventStreamAsync + sync: EventStream fixFlags: asyncPaginationSep2025: true conflictResistantModelImportsFeb2026: false @@ -72,6 +76,7 @@ python: webhooks: "" inferUnionDiscriminators: true inputModelSuffix: input + inputTypedDictSuffix: TypedDict legacyPyright: false license: "" maxMethodParams: 999 @@ -89,6 +94,7 @@ python: pytestTimeout: 0 rawResponseHelpers: false responseFormat: flat + responseSchemaValidation: true sseFlatResponse: false templateVersion: v2 useAsyncHooks: false diff --git a/.speakeasy/workflow.lock b/.speakeasy/workflow.lock index 7931567..962112a 100644 --- a/.speakeasy/workflow.lock +++ b/.speakeasy/workflow.lock @@ -1,9 +1,9 @@ -speakeasyVersion: 1.771.0 +speakeasyVersion: 1.788.1 sources: kombo-prepared-spec: sourceNamespace: kombo-api - sourceRevisionDigest: sha256:26400cad28773013cca90a0c587483fb4d201d1807badde6f783b44a77d0a550 - sourceBlobDigest: sha256:b5916e82d018ffec07eae810ab9a36840e04c9ca308f46d447a48f5cf4899b59 + sourceRevisionDigest: sha256:c80f9c3043d151711936a249656914e59493352a184cf3b9f4e70a612833bd82 + sourceBlobDigest: sha256:9df3df58bc7e77e038e6edfb1f4e6e5f65dcf9d1c817008de1a42dd1361cdd00 tags: - latest - 1.0.0 @@ -11,10 +11,10 @@ targets: kombo-python: source: kombo-prepared-spec sourceNamespace: kombo-api - sourceRevisionDigest: sha256:26400cad28773013cca90a0c587483fb4d201d1807badde6f783b44a77d0a550 - sourceBlobDigest: sha256:b5916e82d018ffec07eae810ab9a36840e04c9ca308f46d447a48f5cf4899b59 + sourceRevisionDigest: sha256:c80f9c3043d151711936a249656914e59493352a184cf3b9f4e70a612833bd82 + sourceBlobDigest: sha256:9df3df58bc7e77e038e6edfb1f4e6e5f65dcf9d1c817008de1a42dd1361cdd00 codeSamplesNamespace: kombo-api-python-code-samples - codeSamplesRevisionDigest: sha256:8c0d04c52852071bedbdec19d6148e3bf239304c7d5bd5a38ec1591a9ee58772 + codeSamplesRevisionDigest: sha256:d298f7465906d0caf75af33252c8215e6b5ddd3310600b6752ec21d737bcdd68 workflow: workflowVersion: 1.0.0 speakeasyVersion: latest diff --git a/RELEASES.md b/RELEASES.md index 8a1f8ef..87cadf1 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -218,4 +218,14 @@ Based on: ### Generated - [python v1.2.0] . ### Releases -- [PyPI v1.2.0] https://pypi.org/project/kombo/1.2.0 - . \ No newline at end of file +- [PyPI v1.2.0] https://pypi.org/project/kombo/1.2.0 - . + +## 2026-07-05 00:45:40 +### Changes +Based on: +- OpenAPI Doc +- Speakeasy CLI 1.788.1 (2.915.1) https://github.com/speakeasy-api/speakeasy +### Generated +- [python v1.3.0] . +### Releases +- [PyPI v1.3.0] https://pypi.org/project/kombo/1.3.0 - . \ No newline at end of file diff --git a/docs/models/integrationtool.md b/docs/models/integrationtool.md index a3fdc3a..f7fcfde 100644 --- a/docs/models/integrationtool.md +++ b/docs/models/integrationtool.md @@ -123,9 +123,13 @@ value: IntegrationTool = "workday" - `"logicmelon"` - `"loxo"` - `"kula"` +- `"trackerrms"` +- `"databites"` +- `"pageup"` - `"workdaycustomreport"` - `"workdaycustomreportsftp"` - `"ukgprowfm"` +- `"adpdecidium"` - `"payfitcustomer"` - `"payfitpartner"` - `"payfit"` @@ -204,6 +208,8 @@ value: IntegrationTool = "workday" - `"sftpfetch"` - `"360learning"` - `"talentlms"` +- `"docebo"` +- `"coursera"` - `"udemy"` - `"linkedinlearning"` - `"moodle"` diff --git a/docs/models/name.md b/docs/models/name.md index 21cfd6d..2842164 100644 --- a/docs/models/name.md +++ b/docs/models/name.md @@ -25,6 +25,10 @@ value: Name = "hris_legal_entities" - `"hris_performance_reviews"` - `"hris_performance_review_cycles"` - `"hris_staffing_entities"` +- `"hris_skill_proficiency_scales"` +- `"hris_skills"` +- `"hris_skill_rating_providers"` +- `"hris_employee_skill_proficiency_ratings"` - `"ats_users"` - `"ats_jobs"` - `"ats_job_postings"` diff --git a/docs/models/postatscandidatesrequestbodyaktiv.md b/docs/models/postatscandidatesrequestbodyaktiv.md new file mode 100644 index 0000000..8062598 --- /dev/null +++ b/docs/models/postatscandidatesrequestbodyaktiv.md @@ -0,0 +1,16 @@ +# PostAtsCandidatesRequestBodyAktiv + +Whether the candidate is created as active (`Ja`) or inactive (`Nein`) in Coveto. If omitted, Coveto applies its default (active). + +## Example Usage + +```python +from kombo.models import PostAtsCandidatesRequestBodyAktiv +value: PostAtsCandidatesRequestBodyAktiv = "Ja" +``` + + +## Values + +- `"Ja"` +- `"Nein"` diff --git a/docs/models/postatscandidatesrequestbodycovetorestcandidate.md b/docs/models/postatscandidatesrequestbodycovetorestcandidate.md index 95eb78e..c6ca9a8 100644 --- a/docs/models/postatscandidatesrequestbodycovetorestcandidate.md +++ b/docs/models/postatscandidatesrequestbodycovetorestcandidate.md @@ -8,4 +8,5 @@ Additional candidate fields that will be passed to the Coveto candidate creation | Field | Type | Required | Description | | ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | | `mandant` | *Optional[float]* | :heavy_minus_sign: | The mandant field for the candidate in Coveto. | -| `status` | *Optional[int]* | :heavy_minus_sign: | The numeric status ID to assign to the candidate on creation in Coveto. Refer to your Coveto `/bewerber-status` endpoint for available IDs. | \ No newline at end of file +| `status` | *Optional[int]* | :heavy_minus_sign: | The numeric status ID to assign to the candidate on creation in Coveto. Refer to your Coveto `/bewerber-status` endpoint for available IDs. | +| `aktiv` | [Optional[models.PostAtsCandidatesRequestBodyAktiv]](../models/postatscandidatesrequestbodyaktiv.md) | :heavy_minus_sign: | Whether the candidate is created as active (`Ja`) or inactive (`Nein`) in Coveto. If omitted, Coveto applies its default (active). | \ No newline at end of file diff --git a/docs/models/postatsjobsjobidapplicationsrequestbodyaktiv.md b/docs/models/postatsjobsjobidapplicationsrequestbodyaktiv.md new file mode 100644 index 0000000..23770fa --- /dev/null +++ b/docs/models/postatsjobsjobidapplicationsrequestbodyaktiv.md @@ -0,0 +1,16 @@ +# PostAtsJobsJobIDApplicationsRequestBodyAktiv + +Whether the candidate is created as active (`Ja`) or inactive (`Nein`) in Coveto. If omitted, Coveto applies its default (active). + +## Example Usage + +```python +from kombo.models import PostAtsJobsJobIDApplicationsRequestBodyAktiv +value: PostAtsJobsJobIDApplicationsRequestBodyAktiv = "Ja" +``` + + +## Values + +- `"Ja"` +- `"Nein"` diff --git a/docs/models/postatsjobsjobidapplicationsrequestbodycovetorestcandidate.md b/docs/models/postatsjobsjobidapplicationsrequestbodycovetorestcandidate.md index 5cfee86..6eacb69 100644 --- a/docs/models/postatsjobsjobidapplicationsrequestbodycovetorestcandidate.md +++ b/docs/models/postatsjobsjobidapplicationsrequestbodycovetorestcandidate.md @@ -8,4 +8,5 @@ Additional candidate fields that will be passed to the Coveto candidate creation | Field | Type | Required | Description | | ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | | `mandant` | *Optional[float]* | :heavy_minus_sign: | The mandant field for the candidate in Coveto. | -| `status` | *Optional[int]* | :heavy_minus_sign: | The numeric status ID to assign to the candidate on creation in Coveto. Refer to your Coveto `/bewerber-status` endpoint for available IDs. | \ No newline at end of file +| `status` | *Optional[int]* | :heavy_minus_sign: | The numeric status ID to assign to the candidate on creation in Coveto. Refer to your Coveto `/bewerber-status` endpoint for available IDs. | +| `aktiv` | [Optional[models.PostAtsJobsJobIDApplicationsRequestBodyAktiv]](../models/postatsjobsjobidapplicationsrequestbodyaktiv.md) | :heavy_minus_sign: | Whether the candidate is created as active (`Ja`) or inactive (`Nein`) in Coveto. If omitted, Coveto applies its default (active). | \ No newline at end of file diff --git a/docs/sdks/general/README.md b/docs/sdks/general/README.md index c2b2f9a..f139ec1 100644 --- a/docs/sdks/general/README.md +++ b/docs/sdks/general/README.md @@ -153,6 +153,7 @@ To get started, please pick the relevant API (some tools provide multiple to due |Abacus Umantis|`abacusumantis/v1`|[Umantis API v1](https://recruitingapp-91005709.umantis.com/api/v1/swagger-ui). We automatically authenticate all requests and use `https://\{subdomain\}.umantis.com/api/v1` as the base URL.| |Abacus|`abacus/api`|Abacus [REST API](https://apihub.abacus.ch/). We automatically authenticate all requests and use `https://\{\{abacusUrl\}\}/api/entity/v1/mandants/\{\{mandantId\}\}` as the base URL.| |Absence.io|`absenceio/v2`|Absence.io [API](https://docs.absence.io/). We automatically authenticate all requests and use `https://app.absence.io/api/v2` as the base URL.| +|ADP Decidium|`adpdecidium/default`|[ADP Decidium API](https://developers.adp.com/apis/api-explorer/hcm-offrg-dge). We automatically authenticate all requests and use `https://api.eu.adp.com` as the base URL.| |ADP Workforce Now|`adpworkforcenow/default`|[ADP Workforce Now API v2](https://developers.adp.com/build/api-explorer/hcm-offrg-wfn). We automatically authenticate all requests and use the correct subdomain.| |AFAS Software|`afas/api`|AFAS' [API](https://connect.afas.nl/rest/get). We automatically authenticate all requests and use `https://\{domain\}/ProfitRestServices` as the base URL.| |AlexisHR|`alexishr/v1`|[AlexisHR's v1 API](https://docs.alexishr.com/) We automatically authenticate all requests and use `https://\{subdomain\}.alexishr.com` as base URL.| @@ -182,6 +183,7 @@ To get started, please pick the relevant API (some tools provide multiple to due |Cornerstone OnDemand|`cornerstoneondemand/recruiting`|Cornerstone's [Recruiting API](https://csod.dev/reference/recruiting/). We automatically authenticate all requests using the client ID and secret and use `https://\{your_domain\}.csod.com/services/api` as the base URL.| |Cornerstone TalentLink|`cornerstonetalentlink/apply`|Cornerstone TalentLink's Apply API. We automatically authenticate all requests using the provided credentials and API key, and use `https://apiproxy.shared.lumessetalentlink.com/apply` as the base URL.| |Cornerstone TalentLink|`cornerstonetalentlink/rest`|Cornerstone TalentLink's [REST API](https://developer.lumesse-talenthub.com/rest-api-developers-guide/1.21.33/index.html?page=rest-api&subpage=introduction). We automatically authenticate all requests using the provided credentials and API key, and use `https://apiproxy.shared.lumessetalentlink.com/tlk/rest` as the base URL.| +|Coursera|`coursera/v1`|We use `https://api.coursera.com/ent` as the base URL. Find the official docs [here](https://dev.coursera.com).| |Coveto (legacy SOAP API)|`coveto/public`|We automatically use `https://\{subdomain\}.coveto.de` as the base URL.| |Coveto (REST API)|`covetorest/v1`|We automatically use `https://\{subdomain\}.coveto.de/public/api/v1` as the base URL. https://demo.coveto.de/swagger-ui/index.html#/| |Crelate|`crelate/api`|Crelate [REST API](https://app.crelate.com/api3/docs/index.html). We automatically authenticate all requests and use `https://app.crelate.com/api3` as the base URL.| @@ -189,14 +191,16 @@ To get started, please pick the relevant API (some tools provide multiple to due |d.vinci admin|`dvinciadmin/rest-api`|[DVinci REST API](https://static.dvinci-easy.com/files/d.vinci%20rest-api.html).| |d.vinci|`dvinci/apply-api`|The [DVinci Apply API](https://static.dvinci-easy.com/files/d.vinci%20application-apply-api.html). All requests are authenticated by Kombo and use `https://\{dvinci_domain\}/p/\{portal_path\}/` as the base URL.| |d.vinci|`dvinci/rest-api`|The [DVinci REST API](https://static.dvinci-easy.com/files/d.vinci%20rest-api.html). All requests are authenticated by Kombo and use `https://\{dvinci_domain\}/restApi/` as the base URL.| -|DATEV LAUDS|`datevlauds/lauds`|DATEV's [hr-exchange](https://developer.datev.de/de/product-detail/hr-exchange/1.0.0/overview). We automatically authenticate all requests and use `https://hr-exchange.api.datev.de/\{platform|platform-sandbox\}/v1/clients/\{client-id\}` as the base URL.| +|Databites|`databites/v1`|We use `https://\{subdomain\}.databites.de` as the base URL. Find the official docs [here](https://\{subdomain\}.databites.de/api-dokumentationen/public-integrations/index).| |DATEV LODAS|`datev/eau`|DATEV's [eau](https://developer.datev.de/en/product-detail/eau-api/1.0.0/overview) API. We automatically authenticate all requests and use `https://eau.api.datev.de/\{platform|platform-sandbox\}/v1/clients/\{client-id\}/` as the base URL.| +|DATEV Lohnaustauschdatenservice|`datevlauds/lauds`|DATEV's [hr-exchange](https://developer.datev.de/de/product-detail/hr-exchange/1.0.0/overview). We automatically authenticate all requests and use `https://hr-exchange.api.datev.de/\{platform|platform-sandbox\}/v1/clients/\{client-id\}` as the base URL.| |DATEV|`datevhr/eau`|DATEV's [eau](https://developer.datev.de/en/product-detail/eau-api/1.0.0/overview) API. We automatically authenticate all requests and use `https://eau.api.datev.de/\{platform|platform-sandbox\}/v1/clients/\{client-id\}/` as the base URL.| |DATEV|`datevhr/hr-exports`|DATEV's [hr-exports](https://developer.datev.de/en/product-detail/hr-exports/1.0.0/overview). We automatically authenticate all requests and use `https://hr-exports.api.datev.de/\{platform|platform-sandbox\}/v1/clients/\{client-id\}` as the base URL.| |DATEV|`datevhr/hr:payrollreports`|DATEV's [hr:payrollreports](https://developer.datev.de/en/product-detail/hr-payrollreports/2.0.0/overview) API. We automatically authenticate all requests and use `https://hr-payrollreports.api.datev.de/\{platform|platform-sandbox\}/v1/clients/\{client-id\}/` as the base URL.| |Dayforce|`dayforce/V1`|[Dayforce's API](https://developers.dayforce.com/Build/Home.aspx). We automatically authenticate all requests and use `\{\{baseUrl\}\}/Api/\{\{clientNamespace\}\}/V1` as the base URL| |Deel|`deel/api`|Deel's [API](https://developer.deel.com/reference/). We automatically authenticate all requests using the provided credentials and use `https://\{api_domain\}/rest` as the base URL.| |Digital Recruiters|`digitalrecruiters/api`|Cegid Digital Recruiters [Talent Acquisition API](https://cegid-hr-developers.talentsoft.net/docs/tutorial-basics/Talent%20Acquisition/Getting%20Started). We automatically authenticate all requests by replacing `:token` in the request URL with your configured access token and use your configured Digital Recruiters domain as the base URL.| +|Docebo|`docebo/api`|Docebo [API](https://developer.docebo.com). We automatically handle authentication and use `https://\{subdomain\}.docebosaas.com` as the base URL.| |Eightfold|`eightfold/api`|Eightfold's [API](https://apidocs.eightfold.ai/). We automatically authenticate all requests and use `https://apiv2.\{region\}/api/v2/core/` as the base URL.| |Employment Hero|`employmenthero/default`|EmploymentHero [API](https://developer.employmenthero.com/api-references/#icon-book-open-introduction). We automatically authenticate all requests using the credentials supplied by the customer and use `https://api.employmenthero.com/api` as the base URL.| |Eploy|`eploy/api`|Eploy's [API](https://www.eploy.com/resources/developers/api-documentation/). We automatically authenticate all requests. The base URL is `https://\{hostname\}/api`, where `\{hostname\}` is either `\{subdomain\}.eploy.net` or your full custom hostname when applicable.| @@ -277,6 +281,8 @@ To get started, please pick the relevant API (some tools provide multiple to due |Oracle Recruiting Cloud|`oraclerecruiting/rest`|[Oracles's REST API](https://docs.oracle.com/en/cloud/saas/human-resources/24d/farws/rest-endpoints.html). We automatically authenticate all requests and use 'https://\{company_url\}' as the base url.| |Oracle Taleo|`taleo/soap`|[Taleo's API](https://docs.oracle.com/en/cloud/saas/taleo-enterprise/23b/otwsu/c-taleoapi.html). We automatically authenticate all requests and use 'https://\{your-subdomain\}.taleo.net/enterprise/soap' as base URL.| |OTYS|`otys/json-rpc`|[OTYS JSON-RPC API](https://ows.otys.nl/info/). We authenticate with your stored API key and inject the session token as the first element of the JSON-RPC `params` array on each request (except `loginByUid`, which uses `params` as sent). Requests use `https://ows.otys.nl` as the base URL (for example `POST /jservice.php` with the RPC method in the URL fragment, matching OTYS conventions).| +|PageUp People|`pageup/v1`|We use `https://assessment-mock-api.dc0.pageuppeople.com` as the base URL. Find the official docs [here](https://developers.pageuppeople.com/Api/Partners/Assessment).| +|PageUp People|`pageup/v3`|We use `https://\.\.pageuppeople.com/v3/\/recruitment` as the base URL. Find the official docs [here](https://developers.pageuppeople.com/Api/Recruitment).| |Paradox|`paradox/v1`|We use `\{api_url\}/api/v1` as the base URL. Find the official docs [here](https://paradox.readme.io/).| |Paradox|`paradox/v1public`|We use `\{api_url\}/api/v1/public` as the base URL. Find the official docs [here](https://paradox.readme.io/).| |Paychex|`paychex/api`|Paychex [REST API](https://developer.paychex.com/documentation). We automatically authenticate all requests and use `https://api.paychex.com` as the base URL.| @@ -322,6 +328,7 @@ To get started, please pick the relevant API (some tools provide multiple to due |TalentLMS|`talentlms/v2`|We use `https://\{subdomain\}.talentlms.com/api/v2` as the base URL.| |Teamtailor Job Boards|`teamtailorjobboards/direct-apply`|Teamtailor's [Job Board Direct Apply API](https://partner.teamtailor.com/job_boards/direct_apply/#direct-apply). We automatically authenticate all requests and use `https://5qbn6o9x4h.execute-api.eu-west-1.amazonaws.com/production` as the base URL. All requests are automatically signed with HMAC-SHA256 signature.| |Teamtailor|`teamtailor/v1`|We use `https://api.teamtailor.com/v1` as the base URL. Find the official docs [here](https://docs.teamtailor.com/).| +|TrackerRMS|`trackerrms/v1`|We use `https://evousapi.tracker-rms.com` as the base URL. Find the official docs [here](https://evousapi.tracker-rms.com/swagger/index.html).| |TRAFFIT|`traffit/v2`|Traffit's [v2 API](https://api.traffit.com). We authenticate all requests with the Traffit API key and use the base URL `https://yourdomain.traffit.com/api/integration/v2`.| |TriNet PEO|`trinetpeo/v1`|We use `https://api.trinet.com` as the base URL. Find the official docs [here](https://developers.trinet.com).| |Ubeeo|`ubeeo/api`|Ubeeo ATS API. We automatically authenticate all requests using OAuth client credentials and use `https://api.ats-platform.com` as the base URL (sandbox: `https://api.acc.ats-platform.com`).| @@ -335,6 +342,7 @@ To get started, please pick the relevant API (some tools provide multiple to due |Visma YouServe|`youserve/learning`|Visma YouServe [Learning API](https://youserve-domain-api.github.io/SwaggerUI/learning.html). We automatically authenticate all requests using OAuth 2.0 with the provided credentials and use `https://api.youserve.nl/learning/v1.0` as the base URL.| |Workable|`workable/v1`|**Deprecated: Use `v3` instead.** Workable's [API](https://workable.readme.io/reference/generate-an-access-token). We automatically authenticate all requests using the client ID and secret and use `https://\{subdomain\}.\{environment\}.com/spi/v3` as the base URL.| |Workable|`workable/v3`|Workable's [API](https://workable.readme.io/reference/generate-an-access-token). We automatically authenticate all requests using the client ID and secret and use `https://\{subdomain\}.\{environment\}.com/spi/v3` as the base URL.| +|Workday|`workday/custom-report`|[Workday's Custom Reports](https://community.workday.com/sites/default/files/file-hosting/productionapi/index.html). We automatically authenticate all requests and use `https://\{domain\}/ccx/service/customreport2/\{tenant\}/` as the base URL. Set your `method` to `GET`. The `path` should be the report path after the tenant, e.g., `/\{report_owner\}/\{report_name\}`. You can include query parameters in the `params` object (e.g., `format=json`).| |Workday|`workday/rest`|[Workday's REST API](https://community.workday.com/sites/default/files/file-hosting/restapi/index.html). We automatically authenticate all requests and use the correct Workday REST base URL for your tenant. The base URL follows the format: https://\{domain\}/api/\{service_name\}/\{version\}/\{tenant\}. You can specify any valid REST endpoint and method. See the Workday REST API documentation for available endpoints. You must specify the `api_options` object and set `service_name` to the name of the service you want to call. You can also specify the `version` (e.g., "v1", "v2"); if omitted, it defaults to "v1".| |Workday|`workday/soap`|[Workday's SOAP API](https://community.workday.com/sites/default/files/file-hosting/productionapi/index.html). We automatically authenticate all requests. Set `data` to your raw xml string. Use `/` as your `path`, as we will always send requests to `https://\{domain\}/ccx/service/\{tenant\}/\{service_name\}`. Set your `method` to `POST`. You need to specify the `api_options` object and set `service_name` to the name of the service you want to call. Find all available services [here](https://community.workday.com/sites/default/files/file-hosting/productionapi/versions/v41.0/index.html). The string that you submit as `data` will be the content of the `soapenv:Body` tag in the request. You can set the `service_version` to any valid Workday service version (the default is `38.2`).| |workforce.com|`workforcecom/api`|Workforce.com [API](https://my.workforce.com/api/v2/documentation). We automatically authenticate all requests using the provided credentials and use `https://my.tanda.co` as the base URL.| diff --git a/pyproject.toml b/pyproject.toml index 9af6c44..a3d7227 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "kombo" -version = "1.2.0" +version = "1.3.0" description = "The official Python SDK for the Kombo Unified API" authors = [{ name = "Kombo Technologies GmbH" },] readme = "README-PYPI.md" @@ -9,7 +9,7 @@ dependencies = [ "httpcore >=1.0.9", "httpx >=0.28.1", "jsonpath-python >=1.0.6", - "pydantic >=2.11.2", + "pydantic >=2.11.2,<2.13", ] urls.repository = "https://github.com/kombohq/python-sdk.git" diff --git a/src/kombo/_hooks/types.py b/src/kombo/_hooks/types.py index e589e54..460080a 100644 --- a/src/kombo/_hooks/types.py +++ b/src/kombo/_hooks/types.py @@ -3,7 +3,7 @@ from abc import ABC, abstractmethod import httpx from kombo.sdkconfiguration import SDKConfiguration -from typing import Any, Callable, List, Optional, Tuple, Union +from typing import Any, Callable, Dict, List, Optional, Tuple, Union class HookContext: @@ -12,6 +12,8 @@ class HookContext: operation_id: str oauth2_scopes: Optional[List[str]] = None security_source: Optional[Union[Any, Callable[[], Any]]] = None + tags: Optional[List[str]] = None + extensions: Optional[Dict[str, Any]] = None def __init__( self, @@ -20,12 +22,16 @@ def __init__( operation_id: str, oauth2_scopes: Optional[List[str]], security_source: Optional[Union[Any, Callable[[], Any]]], + tags: Optional[List[str]], + extensions: Optional[Dict[str, Any]], ): self.config = config self.base_url = base_url self.operation_id = operation_id self.oauth2_scopes = oauth2_scopes self.security_source = security_source + self.tags = tags + self.extensions = extensions class BeforeRequestContext(HookContext): @@ -36,6 +42,8 @@ def __init__(self, hook_ctx: HookContext): hook_ctx.operation_id, hook_ctx.oauth2_scopes, hook_ctx.security_source, + hook_ctx.tags, + hook_ctx.extensions, ) @@ -47,6 +55,8 @@ def __init__(self, hook_ctx: HookContext): hook_ctx.operation_id, hook_ctx.oauth2_scopes, hook_ctx.security_source, + hook_ctx.tags, + hook_ctx.extensions, ) @@ -58,6 +68,8 @@ def __init__(self, hook_ctx: HookContext): hook_ctx.operation_id, hook_ctx.oauth2_scopes, hook_ctx.security_source, + hook_ctx.tags, + hook_ctx.extensions, ) diff --git a/src/kombo/_version.py b/src/kombo/_version.py index e8690c6..30bba2f 100644 --- a/src/kombo/_version.py +++ b/src/kombo/_version.py @@ -3,10 +3,10 @@ import importlib.metadata __title__: str = "kombo" -__version__: str = "1.2.0" +__version__: str = "1.3.0" __openapi_doc_version__: str = "1.0.0" -__gen_version__: str = "2.893.0" -__user_agent__: str = "speakeasy-sdk/python 1.2.0 2.893.0 1.0.0 kombo" +__gen_version__: str = "2.915.1" +__user_agent__: str = "speakeasy-sdk/python 1.3.0 2.915.1 1.0.0 kombo" try: if __package__ is not None: diff --git a/src/kombo/assessment.py b/src/kombo/assessment.py index 3ce2821..b2c845e 100644 --- a/src/kombo/assessment.py +++ b/src/kombo/assessment.py @@ -7,7 +7,7 @@ from kombo._hooks import HookContext from kombo.types import BaseModel, OptionalNullable, UNSET from kombo.utils.unmarshal_json_response import unmarshal_json_response -from typing import Any, Awaitable, Dict, List, Mapping, Optional, Union, cast +from typing import Any, Awaitable, Dict, Iterable, List, Mapping, Optional, Union, cast class Assessment(BaseSDK): @@ -84,6 +84,8 @@ def get_packages( operation_id="GetAssessmentPackages", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS (Assessment & Background Check) API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -174,6 +176,8 @@ async def get_packages_async( operation_id="GetAssessmentPackages", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS (Assessment & Background Check) API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -195,8 +199,8 @@ def set_packages( self, *, packages: Union[ - List[models.PutAssessmentPackagesRequestBodyPackage], - List[models.PutAssessmentPackagesRequestBodyPackageTypedDict], + Iterable[models.PutAssessmentPackagesRequestBodyPackage], + Iterable[models.PutAssessmentPackagesRequestBodyPackageTypedDict], ], retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, @@ -292,6 +296,8 @@ def set_packages( operation_id="PutAssessmentPackages", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS (Assessment & Background Check) API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -313,8 +319,8 @@ async def set_packages_async( self, *, packages: Union[ - List[models.PutAssessmentPackagesRequestBodyPackage], - List[models.PutAssessmentPackagesRequestBodyPackageTypedDict], + Iterable[models.PutAssessmentPackagesRequestBodyPackage], + Iterable[models.PutAssessmentPackagesRequestBodyPackageTypedDict], ], retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, @@ -410,6 +416,8 @@ async def set_packages_async( operation_id="PutAssessmentPackages", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS (Assessment & Background Check) API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -432,8 +440,8 @@ def get_assessment_orders( *, cursor: Optional[str] = None, page_size: Optional[int] = 100, - ids: Optional[List[str]] = None, - statuses: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + statuses: Optional[Iterable[str]] = None, created_after: Optional[datetime] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, @@ -469,8 +477,8 @@ def get_assessment_orders( request = models.GetAssessmentOrdersRequest( cursor=cursor, page_size=page_size, - ids=ids, - statuses=statuses, + ids=utils.unmarshal(ids, Optional[List[str]]), + statuses=utils.unmarshal(statuses, Optional[List[str]]), created_after=created_after, ) @@ -509,6 +517,8 @@ def get_assessment_orders( operation_id="GetAssessmentOrders", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS (Assessment & Background Check) API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -558,8 +568,8 @@ async def get_assessment_orders_async( *, cursor: Optional[str] = None, page_size: Optional[int] = 100, - ids: Optional[List[str]] = None, - statuses: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + statuses: Optional[Iterable[str]] = None, created_after: Optional[datetime] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, @@ -595,8 +605,8 @@ async def get_assessment_orders_async( request = models.GetAssessmentOrdersRequest( cursor=cursor, page_size=page_size, - ids=ids, - statuses=statuses, + ids=utils.unmarshal(ids, Optional[List[str]]), + statuses=utils.unmarshal(statuses, Optional[List[str]]), created_after=created_after, ) @@ -635,6 +645,8 @@ async def get_assessment_orders_async( operation_id="GetAssessmentOrders", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS (Assessment & Background Check) API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -692,14 +704,14 @@ def update_order_result( score: Optional[float] = None, max_score: Optional[float] = None, attributes: Optional[ - Union[List[models.Attribute], List[models.AttributeTypedDict]] + Union[Iterable[models.Attribute], Iterable[models.AttributeTypedDict]] ] = None, attachments: Optional[ Union[ - List[ + Iterable[ models.PutAssessmentOrdersAssessmentOrderIDResultRequestBodyAttachment ], - List[ + Iterable[ models.PutAssessmentOrdersAssessmentOrderIDResultRequestBodyAttachmentTypedDict ], ] @@ -855,6 +867,8 @@ def update_order_result( operation_id="PutAssessmentOrdersAssessmentOrderIdResult", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS (Assessment & Background Check) API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -883,14 +897,14 @@ async def update_order_result_async( score: Optional[float] = None, max_score: Optional[float] = None, attributes: Optional[ - Union[List[models.Attribute], List[models.AttributeTypedDict]] + Union[Iterable[models.Attribute], Iterable[models.AttributeTypedDict]] ] = None, attachments: Optional[ Union[ - List[ + Iterable[ models.PutAssessmentOrdersAssessmentOrderIDResultRequestBodyAttachment ], - List[ + Iterable[ models.PutAssessmentOrdersAssessmentOrderIDResultRequestBodyAttachmentTypedDict ], ] @@ -1046,6 +1060,8 @@ async def update_order_result_async( operation_id="PutAssessmentOrdersAssessmentOrderIdResult", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS (Assessment & Background Check) API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), diff --git a/src/kombo/ats.py b/src/kombo/ats.py index 4f7b1fd..d530bb5 100644 --- a/src/kombo/ats.py +++ b/src/kombo/ats.py @@ -7,7 +7,7 @@ from kombo._hooks import HookContext from kombo.types import Nullable, OptionalNullable, UNSET from kombo.utils.unmarshal_json_response import unmarshal_json_response -from typing import Any, Awaitable, Dict, List, Mapping, Optional, Union +from typing import Any, Awaitable, Dict, Iterable, List, Mapping, Optional, Union class Ats(BaseSDK): @@ -19,12 +19,12 @@ def get_applications( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, - outcomes: Optional[List[str]] = None, - job_ids: Optional[List[str]] = None, - job_remote_ids: Optional[List[str]] = None, - current_stage_ids: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, + outcomes: Optional[Iterable[str]] = None, + job_ids: Optional[Iterable[str]] = None, + job_remote_ids: Optional[Iterable[str]] = None, + current_stage_ids: Optional[Iterable[str]] = None, remote_created_after: Optional[datetime] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, @@ -100,12 +100,12 @@ def get_applications( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, - outcomes=outcomes, - job_ids=job_ids, - job_remote_ids=job_remote_ids, - current_stage_ids=current_stage_ids, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), + outcomes=utils.unmarshal(outcomes, Optional[List[str]]), + job_ids=utils.unmarshal(job_ids, Optional[List[str]]), + job_remote_ids=utils.unmarshal(job_remote_ids, Optional[List[str]]), + current_stage_ids=utils.unmarshal(current_stage_ids, Optional[List[str]]), remote_created_after=remote_created_after, ) @@ -144,6 +144,8 @@ def get_applications( operation_id="GetAtsApplications", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -203,12 +205,12 @@ async def get_applications_async( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, - outcomes: Optional[List[str]] = None, - job_ids: Optional[List[str]] = None, - job_remote_ids: Optional[List[str]] = None, - current_stage_ids: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, + outcomes: Optional[Iterable[str]] = None, + job_ids: Optional[Iterable[str]] = None, + job_remote_ids: Optional[Iterable[str]] = None, + current_stage_ids: Optional[Iterable[str]] = None, remote_created_after: Optional[datetime] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, @@ -284,12 +286,12 @@ async def get_applications_async( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, - outcomes=outcomes, - job_ids=job_ids, - job_remote_ids=job_remote_ids, - current_stage_ids=current_stage_ids, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), + outcomes=utils.unmarshal(outcomes, Optional[List[str]]), + job_ids=utils.unmarshal(job_ids, Optional[List[str]]), + job_remote_ids=utils.unmarshal(job_remote_ids, Optional[List[str]]), + current_stage_ids=utils.unmarshal(current_stage_ids, Optional[List[str]]), remote_created_after=remote_created_after, ) @@ -328,6 +330,8 @@ async def get_applications_async( operation_id="GetAtsApplications", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -488,6 +492,8 @@ def move_application_to_stage( operation_id="PutAtsApplicationsApplicationIdStage", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -611,6 +617,8 @@ async def move_application_to_stage_async( operation_id="PutAtsApplicationsApplicationIdStage", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -772,6 +780,8 @@ def add_application_result_link( operation_id="PostAtsApplicationsApplicationIdResultLinks", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -934,6 +944,8 @@ async def add_application_result_link_async( operation_id="PostAtsApplicationsApplicationIdResultLinks", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -1067,6 +1079,8 @@ def add_application_note( operation_id="PostAtsApplicationsApplicationIdNotes", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -1199,6 +1213,8 @@ async def add_application_note_async( operation_id="PostAtsApplicationsApplicationIdNotes", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -1290,6 +1306,8 @@ def get_application_attachments( operation_id="GetAtsApplicationsApplicationIdAttachments", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -1382,6 +1400,8 @@ async def get_application_attachments_async( operation_id="GetAtsApplicationsApplicationIdAttachments", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -1525,6 +1545,8 @@ def add_application_attachment( operation_id="PostAtsApplicationsApplicationIdAttachments", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -1668,6 +1690,8 @@ async def add_application_attachment_async( operation_id="PostAtsApplicationsApplicationIdAttachments", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -1801,6 +1825,8 @@ def reject_application( operation_id="PostAtsApplicationsApplicationIdReject", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -1933,6 +1959,8 @@ async def reject_application_async( operation_id="PostAtsApplicationsApplicationIdReject", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -1958,10 +1986,10 @@ def get_candidates( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, email: Optional[str] = None, - job_ids: Optional[List[str]] = None, + job_ids: Optional[Iterable[str]] = None, first_name: Optional[str] = None, last_name: Optional[str] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, @@ -2022,10 +2050,10 @@ def get_candidates( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), email=email, - job_ids=job_ids, + job_ids=utils.unmarshal(job_ids, Optional[List[str]]), first_name=first_name, last_name=last_name, ) @@ -2065,6 +2093,8 @@ def get_candidates( operation_id="GetAtsCandidates", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -2123,10 +2153,10 @@ async def get_candidates_async( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, email: Optional[str] = None, - job_ids: Optional[List[str]] = None, + job_ids: Optional[Iterable[str]] = None, first_name: Optional[str] = None, last_name: Optional[str] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, @@ -2187,10 +2217,10 @@ async def get_candidates_async( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), email=email, - job_ids=job_ids, + job_ids=utils.unmarshal(job_ids, Optional[List[str]]), first_name=first_name, last_name=last_name, ) @@ -2230,6 +2260,8 @@ async def get_candidates_async( operation_id="GetAtsCandidates", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -2296,16 +2328,16 @@ def create_candidate( ], screening_question_answers: Optional[ Union[ - List[models.PostAtsCandidatesRequestBodyScreeningQuestionAnswer], - List[ + Iterable[models.PostAtsCandidatesRequestBodyScreeningQuestionAnswer], + Iterable[ models.PostAtsCandidatesRequestBodyScreeningQuestionAnswerTypedDict ], ] ] = None, attachments: Optional[ Union[ - List[models.PostAtsCandidatesRequestBodyAttachment], - List[models.PostAtsCandidatesRequestBodyAttachmentTypedDict], + Iterable[models.PostAtsCandidatesRequestBodyAttachment], + Iterable[models.PostAtsCandidatesRequestBodyAttachmentTypedDict], ] ] = None, source: Optional[ @@ -2517,6 +2549,8 @@ def create_candidate( operation_id="PostAtsCandidates", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -2547,16 +2581,16 @@ async def create_candidate_async( ], screening_question_answers: Optional[ Union[ - List[models.PostAtsCandidatesRequestBodyScreeningQuestionAnswer], - List[ + Iterable[models.PostAtsCandidatesRequestBodyScreeningQuestionAnswer], + Iterable[ models.PostAtsCandidatesRequestBodyScreeningQuestionAnswerTypedDict ], ] ] = None, attachments: Optional[ Union[ - List[models.PostAtsCandidatesRequestBodyAttachment], - List[models.PostAtsCandidatesRequestBodyAttachmentTypedDict], + Iterable[models.PostAtsCandidatesRequestBodyAttachment], + Iterable[models.PostAtsCandidatesRequestBodyAttachmentTypedDict], ] ] = None, source: Optional[ @@ -2768,6 +2802,8 @@ async def create_candidate_async( operation_id="PostAtsCandidates", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -2857,6 +2893,8 @@ def get_candidate_attachments( operation_id="GetAtsCandidatesCandidateIdAttachments", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -2946,6 +2984,8 @@ async def get_candidate_attachments_async( operation_id="GetAtsCandidatesCandidateIdAttachments", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -3089,6 +3129,8 @@ def add_candidate_attachment( operation_id="PostAtsCandidatesCandidateIdAttachments", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -3232,6 +3274,8 @@ async def add_candidate_attachment_async( operation_id="PostAtsCandidatesCandidateIdAttachments", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -3398,6 +3442,8 @@ def add_candidate_result_link( operation_id="PostAtsCandidatesCandidateIdResultLinks", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -3564,6 +3610,8 @@ async def add_candidate_result_link_async( operation_id="PostAtsCandidatesCandidateIdResultLinks", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -3698,6 +3746,8 @@ def add_candidate_tag( operation_id="PostAtsCandidatesCandidateIdTags", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -3832,6 +3882,8 @@ async def add_candidate_tag_async( operation_id="PostAtsCandidatesCandidateIdTags", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -3963,6 +4015,8 @@ def remove_candidate_tag( operation_id="DeleteAtsCandidatesCandidateIdTags", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -4094,6 +4148,8 @@ async def remove_candidate_tag_async( operation_id="DeleteAtsCandidatesCandidateIdTags", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -4119,8 +4175,8 @@ def get_tags( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, @@ -4166,8 +4222,8 @@ def get_tags( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), ) req = self._build_request( @@ -4205,6 +4261,8 @@ def get_tags( operation_id="GetAtsTags", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -4259,8 +4317,8 @@ async def get_tags_async( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, @@ -4306,8 +4364,8 @@ async def get_tags_async( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), ) req = self._build_request_async( @@ -4345,6 +4403,8 @@ async def get_tags_async( operation_id="GetAtsTags", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -4402,8 +4462,8 @@ def get_application_stages( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, @@ -4459,8 +4519,8 @@ def get_application_stages( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), ) req = self._build_request( @@ -4498,6 +4558,8 @@ def get_application_stages( operation_id="GetAtsApplicationStages", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -4552,8 +4614,8 @@ async def get_application_stages_async( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, @@ -4609,8 +4671,8 @@ async def get_application_stages_async( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), ) req = self._build_request_async( @@ -4648,6 +4710,8 @@ async def get_application_stages_async( operation_id="GetAtsApplicationStages", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -4705,13 +4769,13 @@ def get_jobs( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, - job_codes: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, + job_codes: Optional[Iterable[str]] = None, post_url: Optional[str] = None, - statuses: Optional[List[str]] = None, - employment_types: Optional[List[str]] = None, - visibilities: Optional[List[str]] = None, + statuses: Optional[Iterable[str]] = None, + employment_types: Optional[Iterable[str]] = None, + visibilities: Optional[Iterable[str]] = None, remote_created_after: Optional[datetime] = None, name_contains: Optional[str] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, @@ -4789,13 +4853,13 @@ def get_jobs( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, - job_codes=job_codes, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), + job_codes=utils.unmarshal(job_codes, Optional[List[str]]), post_url=post_url, - statuses=statuses, - employment_types=employment_types, - visibilities=visibilities, + statuses=utils.unmarshal(statuses, Optional[List[str]]), + employment_types=utils.unmarshal(employment_types, Optional[List[str]]), + visibilities=utils.unmarshal(visibilities, Optional[List[str]]), remote_created_after=remote_created_after, name_contains=name_contains, ) @@ -4835,6 +4899,8 @@ def get_jobs( operation_id="GetAtsJobs", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -4896,13 +4962,13 @@ async def get_jobs_async( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, - job_codes: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, + job_codes: Optional[Iterable[str]] = None, post_url: Optional[str] = None, - statuses: Optional[List[str]] = None, - employment_types: Optional[List[str]] = None, - visibilities: Optional[List[str]] = None, + statuses: Optional[Iterable[str]] = None, + employment_types: Optional[Iterable[str]] = None, + visibilities: Optional[Iterable[str]] = None, remote_created_after: Optional[datetime] = None, name_contains: Optional[str] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, @@ -4980,13 +5046,13 @@ async def get_jobs_async( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, - job_codes=job_codes, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), + job_codes=utils.unmarshal(job_codes, Optional[List[str]]), post_url=post_url, - statuses=statuses, - employment_types=employment_types, - visibilities=visibilities, + statuses=utils.unmarshal(statuses, Optional[List[str]]), + employment_types=utils.unmarshal(employment_types, Optional[List[str]]), + visibilities=utils.unmarshal(visibilities, Optional[List[str]]), remote_created_after=remote_created_after, name_contains=name_contains, ) @@ -5026,6 +5092,8 @@ async def get_jobs_async( operation_id="GetAtsJobs", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -5093,8 +5161,10 @@ def create_application( stage_id: Optional[str] = None, attachments: Optional[ Union[ - List[models.PostAtsJobsJobIDApplicationsRequestBodyAttachment], - List[models.PostAtsJobsJobIDApplicationsRequestBodyAttachmentTypedDict], + Iterable[models.PostAtsJobsJobIDApplicationsRequestBodyAttachment], + Iterable[ + models.PostAtsJobsJobIDApplicationsRequestBodyAttachmentTypedDict + ], ] ] = None, source: Optional[ @@ -5123,10 +5193,10 @@ def create_application( ] = None, screening_question_answers: Optional[ Union[ - List[ + Iterable[ models.PostAtsJobsJobIDApplicationsRequestBodyScreeningQuestionAnswer ], - List[ + Iterable[ models.PostAtsJobsJobIDApplicationsRequestBodyScreeningQuestionAnswerTypedDict ], ] @@ -5322,6 +5392,8 @@ def create_application( operation_id="PostAtsJobsJobIdApplications", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -5350,8 +5422,10 @@ async def create_application_async( stage_id: Optional[str] = None, attachments: Optional[ Union[ - List[models.PostAtsJobsJobIDApplicationsRequestBodyAttachment], - List[models.PostAtsJobsJobIDApplicationsRequestBodyAttachmentTypedDict], + Iterable[models.PostAtsJobsJobIDApplicationsRequestBodyAttachment], + Iterable[ + models.PostAtsJobsJobIDApplicationsRequestBodyAttachmentTypedDict + ], ] ] = None, source: Optional[ @@ -5380,10 +5454,10 @@ async def create_application_async( ] = None, screening_question_answers: Optional[ Union[ - List[ + Iterable[ models.PostAtsJobsJobIDApplicationsRequestBodyScreeningQuestionAnswer ], - List[ + Iterable[ models.PostAtsJobsJobIDApplicationsRequestBodyScreeningQuestionAnswerTypedDict ], ] @@ -5579,6 +5653,8 @@ async def create_application_async( operation_id="PostAtsJobsJobIdApplications", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -5604,9 +5680,9 @@ def get_users( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, - emails: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, + emails: Optional[Iterable[str]] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, @@ -5659,9 +5735,9 @@ def get_users( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, - emails=emails, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), + emails=utils.unmarshal(emails, Optional[List[str]]), ) req = self._build_request( @@ -5699,6 +5775,8 @@ def get_users( operation_id="GetAtsUsers", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -5754,9 +5832,9 @@ async def get_users_async( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, - emails: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, + emails: Optional[Iterable[str]] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, @@ -5809,9 +5887,9 @@ async def get_users_async( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, - emails=emails, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), + emails=utils.unmarshal(emails, Optional[List[str]]), ) req = self._build_request_async( @@ -5849,6 +5927,8 @@ async def get_users_async( operation_id="GetAtsUsers", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -5907,9 +5987,9 @@ def get_roles( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, - scopes: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, + scopes: Optional[Iterable[str]] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, @@ -5963,9 +6043,9 @@ def get_roles( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, - scopes=scopes, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), + scopes=utils.unmarshal(scopes, Optional[List[str]]), ) req = self._build_request( @@ -6003,6 +6083,8 @@ def get_roles( operation_id="GetAtsRoles", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -6058,9 +6140,9 @@ async def get_roles_async( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, - scopes: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, + scopes: Optional[Iterable[str]] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, @@ -6114,9 +6196,9 @@ async def get_roles_async( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, - scopes=scopes, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), + scopes=utils.unmarshal(scopes, Optional[List[str]]), ) req = self._build_request_async( @@ -6154,6 +6236,8 @@ async def get_roles_async( operation_id="GetAtsRoles", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -6212,8 +6296,8 @@ def get_offers( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, @@ -6267,8 +6351,8 @@ def get_offers( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), ) req = self._build_request( @@ -6306,6 +6390,8 @@ def get_offers( operation_id="GetAtsOffers", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -6360,8 +6446,8 @@ async def get_offers_async( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, @@ -6415,8 +6501,8 @@ async def get_offers_async( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), ) req = self._build_request_async( @@ -6454,6 +6540,8 @@ async def get_offers_async( operation_id="GetAtsOffers", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -6511,8 +6599,8 @@ def get_rejection_reasons( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, @@ -6560,8 +6648,8 @@ def get_rejection_reasons( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), ) req = self._build_request( @@ -6599,6 +6687,8 @@ def get_rejection_reasons( operation_id="GetAtsRejectionReasons", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -6653,8 +6743,8 @@ async def get_rejection_reasons_async( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, @@ -6702,8 +6792,8 @@ async def get_rejection_reasons_async( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), ) req = self._build_request_async( @@ -6741,6 +6831,8 @@ async def get_rejection_reasons_async( operation_id="GetAtsRejectionReasons", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -6798,9 +6890,9 @@ def get_interviews( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, - job_ids: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, + job_ids: Optional[Iterable[str]] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, @@ -6856,9 +6948,9 @@ def get_interviews( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, - job_ids=job_ids, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), + job_ids=utils.unmarshal(job_ids, Optional[List[str]]), ) req = self._build_request( @@ -6896,6 +6988,8 @@ def get_interviews( operation_id="GetAtsInterviews", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -6951,9 +7045,9 @@ async def get_interviews_async( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, - job_ids: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, + job_ids: Optional[Iterable[str]] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, @@ -7009,9 +7103,9 @@ async def get_interviews_async( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, - job_ids=job_ids, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), + job_ids=utils.unmarshal(job_ids, Optional[List[str]]), ) req = self._build_request_async( @@ -7049,6 +7143,8 @@ async def get_interviews_async( operation_id="GetAtsInterviews", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -7284,6 +7380,8 @@ def import_tracked_application( operation_id="PostAtsImportTrackedApplication", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -7486,6 +7584,8 @@ async def import_tracked_application_async( operation_id="PostAtsImportTrackedApplication", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified ATS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), diff --git a/src/kombo/connect.py b/src/kombo/connect.py index 25bcea1..7ec7a44 100644 --- a/src/kombo/connect.py +++ b/src/kombo/connect.py @@ -136,6 +136,8 @@ def create_connection_link( operation_id="PostConnectCreateLink", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Kombo Connect"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -282,6 +284,8 @@ async def create_connection_link_async( operation_id="PostConnectCreateLink", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Kombo Connect"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -376,6 +380,8 @@ def get_integration_by_token( operation_id="GetConnectIntegrationByTokenToken", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Kombo Connect"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -470,6 +476,8 @@ async def get_integration_by_token_async( operation_id="GetConnectIntegrationByTokenToken", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Kombo Connect"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), diff --git a/src/kombo/general.py b/src/kombo/general.py index 300563c..34c9b45 100644 --- a/src/kombo/general.py +++ b/src/kombo/general.py @@ -6,7 +6,7 @@ from kombo._hooks import HookContext from kombo.types import Nullable, OptionalNullable, UNSET from kombo.utils.unmarshal_json_response import unmarshal_json_response -from typing import Any, Awaitable, Dict, List, Mapping, Optional, Union +from typing import Any, Awaitable, Dict, Iterable, List, Mapping, Optional, Union class General(BaseSDK): @@ -68,6 +68,8 @@ def check_api_key( operation_id="GetCheckApiKey", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["General"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -145,6 +147,8 @@ async def check_api_key_async( operation_id="GetCheckApiKey", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["General"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -240,6 +244,8 @@ def trigger_sync( operation_id="PostForceSync", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["General"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -335,6 +341,8 @@ async def trigger_sync_async( operation_id="PostForceSync", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["General"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -361,17 +369,17 @@ def send_passthrough_request( api: str, method: models.Method, path: str, - headers: Optional[Dict[str, str]] = None, - params: Optional[Dict[str, str]] = None, + headers: Optional[Mapping[str, str]] = None, + params: Optional[Mapping[str, str]] = None, data: Optional[Any] = None, response_as_base64: Optional[bool] = None, multipart_form_data: Optional[ Union[ - List[models.MultipartFormDatum], - List[models.MultipartFormDatumTypedDict], + Iterable[models.MultipartFormDatum], + Iterable[models.MultipartFormDatumTypedDict], ] ] = None, - api_options: Optional[Dict[str, str]] = None, + api_options: Optional[Mapping[str, str]] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, @@ -394,6 +402,7 @@ def send_passthrough_request( |Abacus Umantis|`abacusumantis/v1`|[Umantis API v1](https://recruitingapp-91005709.umantis.com/api/v1/swagger-ui). We automatically authenticate all requests and use `https://\{subdomain\}.umantis.com/api/v1` as the base URL.| |Abacus|`abacus/api`|Abacus [REST API](https://apihub.abacus.ch/). We automatically authenticate all requests and use `https://\{\{abacusUrl\}\}/api/entity/v1/mandants/\{\{mandantId\}\}` as the base URL.| |Absence.io|`absenceio/v2`|Absence.io [API](https://docs.absence.io/). We automatically authenticate all requests and use `https://app.absence.io/api/v2` as the base URL.| + |ADP Decidium|`adpdecidium/default`|[ADP Decidium API](https://developers.adp.com/apis/api-explorer/hcm-offrg-dge). We automatically authenticate all requests and use `https://api.eu.adp.com` as the base URL.| |ADP Workforce Now|`adpworkforcenow/default`|[ADP Workforce Now API v2](https://developers.adp.com/build/api-explorer/hcm-offrg-wfn). We automatically authenticate all requests and use the correct subdomain.| |AFAS Software|`afas/api`|AFAS' [API](https://connect.afas.nl/rest/get). We automatically authenticate all requests and use `https://\{domain\}/ProfitRestServices` as the base URL.| |AlexisHR|`alexishr/v1`|[AlexisHR's v1 API](https://docs.alexishr.com/) We automatically authenticate all requests and use `https://\{subdomain\}.alexishr.com` as base URL.| @@ -423,6 +432,7 @@ def send_passthrough_request( |Cornerstone OnDemand|`cornerstoneondemand/recruiting`|Cornerstone's [Recruiting API](https://csod.dev/reference/recruiting/). We automatically authenticate all requests using the client ID and secret and use `https://\{your_domain\}.csod.com/services/api` as the base URL.| |Cornerstone TalentLink|`cornerstonetalentlink/apply`|Cornerstone TalentLink's Apply API. We automatically authenticate all requests using the provided credentials and API key, and use `https://apiproxy.shared.lumessetalentlink.com/apply` as the base URL.| |Cornerstone TalentLink|`cornerstonetalentlink/rest`|Cornerstone TalentLink's [REST API](https://developer.lumesse-talenthub.com/rest-api-developers-guide/1.21.33/index.html?page=rest-api&subpage=introduction). We automatically authenticate all requests using the provided credentials and API key, and use `https://apiproxy.shared.lumessetalentlink.com/tlk/rest` as the base URL.| + |Coursera|`coursera/v1`|We use `https://api.coursera.com/ent` as the base URL. Find the official docs [here](https://dev.coursera.com).| |Coveto (legacy SOAP API)|`coveto/public`|We automatically use `https://\{subdomain\}.coveto.de` as the base URL.| |Coveto (REST API)|`covetorest/v1`|We automatically use `https://\{subdomain\}.coveto.de/public/api/v1` as the base URL. https://demo.coveto.de/swagger-ui/index.html#/| |Crelate|`crelate/api`|Crelate [REST API](https://app.crelate.com/api3/docs/index.html). We automatically authenticate all requests and use `https://app.crelate.com/api3` as the base URL.| @@ -430,14 +440,16 @@ def send_passthrough_request( |d.vinci admin|`dvinciadmin/rest-api`|[DVinci REST API](https://static.dvinci-easy.com/files/d.vinci%20rest-api.html).| |d.vinci|`dvinci/apply-api`|The [DVinci Apply API](https://static.dvinci-easy.com/files/d.vinci%20application-apply-api.html). All requests are authenticated by Kombo and use `https://\{dvinci_domain\}/p/\{portal_path\}/` as the base URL.| |d.vinci|`dvinci/rest-api`|The [DVinci REST API](https://static.dvinci-easy.com/files/d.vinci%20rest-api.html). All requests are authenticated by Kombo and use `https://\{dvinci_domain\}/restApi/` as the base URL.| - |DATEV LAUDS|`datevlauds/lauds`|DATEV's [hr-exchange](https://developer.datev.de/de/product-detail/hr-exchange/1.0.0/overview). We automatically authenticate all requests and use `https://hr-exchange.api.datev.de/\{platform|platform-sandbox\}/v1/clients/\{client-id\}` as the base URL.| + |Databites|`databites/v1`|We use `https://\{subdomain\}.databites.de` as the base URL. Find the official docs [here](https://\{subdomain\}.databites.de/api-dokumentationen/public-integrations/index).| |DATEV LODAS|`datev/eau`|DATEV's [eau](https://developer.datev.de/en/product-detail/eau-api/1.0.0/overview) API. We automatically authenticate all requests and use `https://eau.api.datev.de/\{platform|platform-sandbox\}/v1/clients/\{client-id\}/` as the base URL.| + |DATEV Lohnaustauschdatenservice|`datevlauds/lauds`|DATEV's [hr-exchange](https://developer.datev.de/de/product-detail/hr-exchange/1.0.0/overview). We automatically authenticate all requests and use `https://hr-exchange.api.datev.de/\{platform|platform-sandbox\}/v1/clients/\{client-id\}` as the base URL.| |DATEV|`datevhr/eau`|DATEV's [eau](https://developer.datev.de/en/product-detail/eau-api/1.0.0/overview) API. We automatically authenticate all requests and use `https://eau.api.datev.de/\{platform|platform-sandbox\}/v1/clients/\{client-id\}/` as the base URL.| |DATEV|`datevhr/hr-exports`|DATEV's [hr-exports](https://developer.datev.de/en/product-detail/hr-exports/1.0.0/overview). We automatically authenticate all requests and use `https://hr-exports.api.datev.de/\{platform|platform-sandbox\}/v1/clients/\{client-id\}` as the base URL.| |DATEV|`datevhr/hr:payrollreports`|DATEV's [hr:payrollreports](https://developer.datev.de/en/product-detail/hr-payrollreports/2.0.0/overview) API. We automatically authenticate all requests and use `https://hr-payrollreports.api.datev.de/\{platform|platform-sandbox\}/v1/clients/\{client-id\}/` as the base URL.| |Dayforce|`dayforce/V1`|[Dayforce's API](https://developers.dayforce.com/Build/Home.aspx). We automatically authenticate all requests and use `\{\{baseUrl\}\}/Api/\{\{clientNamespace\}\}/V1` as the base URL| |Deel|`deel/api`|Deel's [API](https://developer.deel.com/reference/). We automatically authenticate all requests using the provided credentials and use `https://\{api_domain\}/rest` as the base URL.| |Digital Recruiters|`digitalrecruiters/api`|Cegid Digital Recruiters [Talent Acquisition API](https://cegid-hr-developers.talentsoft.net/docs/tutorial-basics/Talent%20Acquisition/Getting%20Started). We automatically authenticate all requests by replacing `:token` in the request URL with your configured access token and use your configured Digital Recruiters domain as the base URL.| + |Docebo|`docebo/api`|Docebo [API](https://developer.docebo.com). We automatically handle authentication and use `https://\{subdomain\}.docebosaas.com` as the base URL.| |Eightfold|`eightfold/api`|Eightfold's [API](https://apidocs.eightfold.ai/). We automatically authenticate all requests and use `https://apiv2.\{region\}/api/v2/core/` as the base URL.| |Employment Hero|`employmenthero/default`|EmploymentHero [API](https://developer.employmenthero.com/api-references/#icon-book-open-introduction). We automatically authenticate all requests using the credentials supplied by the customer and use `https://api.employmenthero.com/api` as the base URL.| |Eploy|`eploy/api`|Eploy's [API](https://www.eploy.com/resources/developers/api-documentation/). We automatically authenticate all requests. The base URL is `https://\{hostname\}/api`, where `\{hostname\}` is either `\{subdomain\}.eploy.net` or your full custom hostname when applicable.| @@ -518,6 +530,8 @@ def send_passthrough_request( |Oracle Recruiting Cloud|`oraclerecruiting/rest`|[Oracles's REST API](https://docs.oracle.com/en/cloud/saas/human-resources/24d/farws/rest-endpoints.html). We automatically authenticate all requests and use 'https://\{company_url\}' as the base url.| |Oracle Taleo|`taleo/soap`|[Taleo's API](https://docs.oracle.com/en/cloud/saas/taleo-enterprise/23b/otwsu/c-taleoapi.html). We automatically authenticate all requests and use 'https://\{your-subdomain\}.taleo.net/enterprise/soap' as base URL.| |OTYS|`otys/json-rpc`|[OTYS JSON-RPC API](https://ows.otys.nl/info/). We authenticate with your stored API key and inject the session token as the first element of the JSON-RPC `params` array on each request (except `loginByUid`, which uses `params` as sent). Requests use `https://ows.otys.nl` as the base URL (for example `POST /jservice.php` with the RPC method in the URL fragment, matching OTYS conventions).| + |PageUp People|`pageup/v1`|We use `https://assessment-mock-api.dc0.pageuppeople.com` as the base URL. Find the official docs [here](https://developers.pageuppeople.com/Api/Partners/Assessment).| + |PageUp People|`pageup/v3`|We use `https://\.\.pageuppeople.com/v3/\/recruitment` as the base URL. Find the official docs [here](https://developers.pageuppeople.com/Api/Recruitment).| |Paradox|`paradox/v1`|We use `\{api_url\}/api/v1` as the base URL. Find the official docs [here](https://paradox.readme.io/).| |Paradox|`paradox/v1public`|We use `\{api_url\}/api/v1/public` as the base URL. Find the official docs [here](https://paradox.readme.io/).| |Paychex|`paychex/api`|Paychex [REST API](https://developer.paychex.com/documentation). We automatically authenticate all requests and use `https://api.paychex.com` as the base URL.| @@ -563,6 +577,7 @@ def send_passthrough_request( |TalentLMS|`talentlms/v2`|We use `https://\{subdomain\}.talentlms.com/api/v2` as the base URL.| |Teamtailor Job Boards|`teamtailorjobboards/direct-apply`|Teamtailor's [Job Board Direct Apply API](https://partner.teamtailor.com/job_boards/direct_apply/#direct-apply). We automatically authenticate all requests and use `https://5qbn6o9x4h.execute-api.eu-west-1.amazonaws.com/production` as the base URL. All requests are automatically signed with HMAC-SHA256 signature.| |Teamtailor|`teamtailor/v1`|We use `https://api.teamtailor.com/v1` as the base URL. Find the official docs [here](https://docs.teamtailor.com/).| + |TrackerRMS|`trackerrms/v1`|We use `https://evousapi.tracker-rms.com` as the base URL. Find the official docs [here](https://evousapi.tracker-rms.com/swagger/index.html).| |TRAFFIT|`traffit/v2`|Traffit's [v2 API](https://api.traffit.com). We authenticate all requests with the Traffit API key and use the base URL `https://yourdomain.traffit.com/api/integration/v2`.| |TriNet PEO|`trinetpeo/v1`|We use `https://api.trinet.com` as the base URL. Find the official docs [here](https://developers.trinet.com).| |Ubeeo|`ubeeo/api`|Ubeeo ATS API. We automatically authenticate all requests using OAuth client credentials and use `https://api.ats-platform.com` as the base URL (sandbox: `https://api.acc.ats-platform.com`).| @@ -576,6 +591,7 @@ def send_passthrough_request( |Visma YouServe|`youserve/learning`|Visma YouServe [Learning API](https://youserve-domain-api.github.io/SwaggerUI/learning.html). We automatically authenticate all requests using OAuth 2.0 with the provided credentials and use `https://api.youserve.nl/learning/v1.0` as the base URL.| |Workable|`workable/v1`|**Deprecated: Use `v3` instead.** Workable's [API](https://workable.readme.io/reference/generate-an-access-token). We automatically authenticate all requests using the client ID and secret and use `https://\{subdomain\}.\{environment\}.com/spi/v3` as the base URL.| |Workable|`workable/v3`|Workable's [API](https://workable.readme.io/reference/generate-an-access-token). We automatically authenticate all requests using the client ID and secret and use `https://\{subdomain\}.\{environment\}.com/spi/v3` as the base URL.| + |Workday|`workday/custom-report`|[Workday's Custom Reports](https://community.workday.com/sites/default/files/file-hosting/productionapi/index.html). We automatically authenticate all requests and use `https://\{domain\}/ccx/service/customreport2/\{tenant\}/` as the base URL. Set your `method` to `GET`. The `path` should be the report path after the tenant, e.g., `/\{report_owner\}/\{report_name\}`. You can include query parameters in the `params` object (e.g., `format=json`).| |Workday|`workday/rest`|[Workday's REST API](https://community.workday.com/sites/default/files/file-hosting/restapi/index.html). We automatically authenticate all requests and use the correct Workday REST base URL for your tenant. The base URL follows the format: https://\{domain\}/api/\{service_name\}/\{version\}/\{tenant\}. You can specify any valid REST endpoint and method. See the Workday REST API documentation for available endpoints. You must specify the `api_options` object and set `service_name` to the name of the service you want to call. You can also specify the `version` (e.g., \"v1\", \"v2\"); if omitted, it defaults to \"v1\".| |Workday|`workday/soap`|[Workday's SOAP API](https://community.workday.com/sites/default/files/file-hosting/productionapi/index.html). We automatically authenticate all requests. Set `data` to your raw xml string. Use `/` as your `path`, as we will always send requests to `https://\{domain\}/ccx/service/\{tenant\}/\{service_name\}`. Set your `method` to `POST`. You need to specify the `api_options` object and set `service_name` to the name of the service you want to call. Find all available services [here](https://community.workday.com/sites/default/files/file-hosting/productionapi/versions/v41.0/index.html). The string that you submit as `data` will be the content of the `soapenv:Body` tag in the request. You can set the `service_version` to any valid Workday service version (the default is `38.2`).| |workforce.com|`workforcecom/api`|Workforce.com [API](https://my.workforce.com/api/v2/documentation). We automatically authenticate all requests using the provided credentials and use `https://my.tanda.co` as the base URL.| @@ -620,14 +636,14 @@ def send_passthrough_request( body=models.PostPassthroughToolAPIRequestBody( method=method, path=path, - headers=headers, - params=params, + headers=utils.unmarshal(headers, Optional[Dict[str, str]]), + params=utils.unmarshal(params, Optional[Dict[str, str]]), data=data, response_as_base64=response_as_base64, multipart_form_data=utils.get_pydantic_model( multipart_form_data, Optional[List[models.MultipartFormDatum]] ), - api_options=api_options, + api_options=utils.unmarshal(api_options, Optional[Dict[str, str]]), ), ) @@ -673,6 +689,8 @@ def send_passthrough_request( operation_id="PostPassthroughToolApi", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["General"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -699,17 +717,17 @@ async def send_passthrough_request_async( api: str, method: models.Method, path: str, - headers: Optional[Dict[str, str]] = None, - params: Optional[Dict[str, str]] = None, + headers: Optional[Mapping[str, str]] = None, + params: Optional[Mapping[str, str]] = None, data: Optional[Any] = None, response_as_base64: Optional[bool] = None, multipart_form_data: Optional[ Union[ - List[models.MultipartFormDatum], - List[models.MultipartFormDatumTypedDict], + Iterable[models.MultipartFormDatum], + Iterable[models.MultipartFormDatumTypedDict], ] ] = None, - api_options: Optional[Dict[str, str]] = None, + api_options: Optional[Mapping[str, str]] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, @@ -732,6 +750,7 @@ async def send_passthrough_request_async( |Abacus Umantis|`abacusumantis/v1`|[Umantis API v1](https://recruitingapp-91005709.umantis.com/api/v1/swagger-ui). We automatically authenticate all requests and use `https://\{subdomain\}.umantis.com/api/v1` as the base URL.| |Abacus|`abacus/api`|Abacus [REST API](https://apihub.abacus.ch/). We automatically authenticate all requests and use `https://\{\{abacusUrl\}\}/api/entity/v1/mandants/\{\{mandantId\}\}` as the base URL.| |Absence.io|`absenceio/v2`|Absence.io [API](https://docs.absence.io/). We automatically authenticate all requests and use `https://app.absence.io/api/v2` as the base URL.| + |ADP Decidium|`adpdecidium/default`|[ADP Decidium API](https://developers.adp.com/apis/api-explorer/hcm-offrg-dge). We automatically authenticate all requests and use `https://api.eu.adp.com` as the base URL.| |ADP Workforce Now|`adpworkforcenow/default`|[ADP Workforce Now API v2](https://developers.adp.com/build/api-explorer/hcm-offrg-wfn). We automatically authenticate all requests and use the correct subdomain.| |AFAS Software|`afas/api`|AFAS' [API](https://connect.afas.nl/rest/get). We automatically authenticate all requests and use `https://\{domain\}/ProfitRestServices` as the base URL.| |AlexisHR|`alexishr/v1`|[AlexisHR's v1 API](https://docs.alexishr.com/) We automatically authenticate all requests and use `https://\{subdomain\}.alexishr.com` as base URL.| @@ -761,6 +780,7 @@ async def send_passthrough_request_async( |Cornerstone OnDemand|`cornerstoneondemand/recruiting`|Cornerstone's [Recruiting API](https://csod.dev/reference/recruiting/). We automatically authenticate all requests using the client ID and secret and use `https://\{your_domain\}.csod.com/services/api` as the base URL.| |Cornerstone TalentLink|`cornerstonetalentlink/apply`|Cornerstone TalentLink's Apply API. We automatically authenticate all requests using the provided credentials and API key, and use `https://apiproxy.shared.lumessetalentlink.com/apply` as the base URL.| |Cornerstone TalentLink|`cornerstonetalentlink/rest`|Cornerstone TalentLink's [REST API](https://developer.lumesse-talenthub.com/rest-api-developers-guide/1.21.33/index.html?page=rest-api&subpage=introduction). We automatically authenticate all requests using the provided credentials and API key, and use `https://apiproxy.shared.lumessetalentlink.com/tlk/rest` as the base URL.| + |Coursera|`coursera/v1`|We use `https://api.coursera.com/ent` as the base URL. Find the official docs [here](https://dev.coursera.com).| |Coveto (legacy SOAP API)|`coveto/public`|We automatically use `https://\{subdomain\}.coveto.de` as the base URL.| |Coveto (REST API)|`covetorest/v1`|We automatically use `https://\{subdomain\}.coveto.de/public/api/v1` as the base URL. https://demo.coveto.de/swagger-ui/index.html#/| |Crelate|`crelate/api`|Crelate [REST API](https://app.crelate.com/api3/docs/index.html). We automatically authenticate all requests and use `https://app.crelate.com/api3` as the base URL.| @@ -768,14 +788,16 @@ async def send_passthrough_request_async( |d.vinci admin|`dvinciadmin/rest-api`|[DVinci REST API](https://static.dvinci-easy.com/files/d.vinci%20rest-api.html).| |d.vinci|`dvinci/apply-api`|The [DVinci Apply API](https://static.dvinci-easy.com/files/d.vinci%20application-apply-api.html). All requests are authenticated by Kombo and use `https://\{dvinci_domain\}/p/\{portal_path\}/` as the base URL.| |d.vinci|`dvinci/rest-api`|The [DVinci REST API](https://static.dvinci-easy.com/files/d.vinci%20rest-api.html). All requests are authenticated by Kombo and use `https://\{dvinci_domain\}/restApi/` as the base URL.| - |DATEV LAUDS|`datevlauds/lauds`|DATEV's [hr-exchange](https://developer.datev.de/de/product-detail/hr-exchange/1.0.0/overview). We automatically authenticate all requests and use `https://hr-exchange.api.datev.de/\{platform|platform-sandbox\}/v1/clients/\{client-id\}` as the base URL.| + |Databites|`databites/v1`|We use `https://\{subdomain\}.databites.de` as the base URL. Find the official docs [here](https://\{subdomain\}.databites.de/api-dokumentationen/public-integrations/index).| |DATEV LODAS|`datev/eau`|DATEV's [eau](https://developer.datev.de/en/product-detail/eau-api/1.0.0/overview) API. We automatically authenticate all requests and use `https://eau.api.datev.de/\{platform|platform-sandbox\}/v1/clients/\{client-id\}/` as the base URL.| + |DATEV Lohnaustauschdatenservice|`datevlauds/lauds`|DATEV's [hr-exchange](https://developer.datev.de/de/product-detail/hr-exchange/1.0.0/overview). We automatically authenticate all requests and use `https://hr-exchange.api.datev.de/\{platform|platform-sandbox\}/v1/clients/\{client-id\}` as the base URL.| |DATEV|`datevhr/eau`|DATEV's [eau](https://developer.datev.de/en/product-detail/eau-api/1.0.0/overview) API. We automatically authenticate all requests and use `https://eau.api.datev.de/\{platform|platform-sandbox\}/v1/clients/\{client-id\}/` as the base URL.| |DATEV|`datevhr/hr-exports`|DATEV's [hr-exports](https://developer.datev.de/en/product-detail/hr-exports/1.0.0/overview). We automatically authenticate all requests and use `https://hr-exports.api.datev.de/\{platform|platform-sandbox\}/v1/clients/\{client-id\}` as the base URL.| |DATEV|`datevhr/hr:payrollreports`|DATEV's [hr:payrollreports](https://developer.datev.de/en/product-detail/hr-payrollreports/2.0.0/overview) API. We automatically authenticate all requests and use `https://hr-payrollreports.api.datev.de/\{platform|platform-sandbox\}/v1/clients/\{client-id\}/` as the base URL.| |Dayforce|`dayforce/V1`|[Dayforce's API](https://developers.dayforce.com/Build/Home.aspx). We automatically authenticate all requests and use `\{\{baseUrl\}\}/Api/\{\{clientNamespace\}\}/V1` as the base URL| |Deel|`deel/api`|Deel's [API](https://developer.deel.com/reference/). We automatically authenticate all requests using the provided credentials and use `https://\{api_domain\}/rest` as the base URL.| |Digital Recruiters|`digitalrecruiters/api`|Cegid Digital Recruiters [Talent Acquisition API](https://cegid-hr-developers.talentsoft.net/docs/tutorial-basics/Talent%20Acquisition/Getting%20Started). We automatically authenticate all requests by replacing `:token` in the request URL with your configured access token and use your configured Digital Recruiters domain as the base URL.| + |Docebo|`docebo/api`|Docebo [API](https://developer.docebo.com). We automatically handle authentication and use `https://\{subdomain\}.docebosaas.com` as the base URL.| |Eightfold|`eightfold/api`|Eightfold's [API](https://apidocs.eightfold.ai/). We automatically authenticate all requests and use `https://apiv2.\{region\}/api/v2/core/` as the base URL.| |Employment Hero|`employmenthero/default`|EmploymentHero [API](https://developer.employmenthero.com/api-references/#icon-book-open-introduction). We automatically authenticate all requests using the credentials supplied by the customer and use `https://api.employmenthero.com/api` as the base URL.| |Eploy|`eploy/api`|Eploy's [API](https://www.eploy.com/resources/developers/api-documentation/). We automatically authenticate all requests. The base URL is `https://\{hostname\}/api`, where `\{hostname\}` is either `\{subdomain\}.eploy.net` or your full custom hostname when applicable.| @@ -856,6 +878,8 @@ async def send_passthrough_request_async( |Oracle Recruiting Cloud|`oraclerecruiting/rest`|[Oracles's REST API](https://docs.oracle.com/en/cloud/saas/human-resources/24d/farws/rest-endpoints.html). We automatically authenticate all requests and use 'https://\{company_url\}' as the base url.| |Oracle Taleo|`taleo/soap`|[Taleo's API](https://docs.oracle.com/en/cloud/saas/taleo-enterprise/23b/otwsu/c-taleoapi.html). We automatically authenticate all requests and use 'https://\{your-subdomain\}.taleo.net/enterprise/soap' as base URL.| |OTYS|`otys/json-rpc`|[OTYS JSON-RPC API](https://ows.otys.nl/info/). We authenticate with your stored API key and inject the session token as the first element of the JSON-RPC `params` array on each request (except `loginByUid`, which uses `params` as sent). Requests use `https://ows.otys.nl` as the base URL (for example `POST /jservice.php` with the RPC method in the URL fragment, matching OTYS conventions).| + |PageUp People|`pageup/v1`|We use `https://assessment-mock-api.dc0.pageuppeople.com` as the base URL. Find the official docs [here](https://developers.pageuppeople.com/Api/Partners/Assessment).| + |PageUp People|`pageup/v3`|We use `https://\.\.pageuppeople.com/v3/\/recruitment` as the base URL. Find the official docs [here](https://developers.pageuppeople.com/Api/Recruitment).| |Paradox|`paradox/v1`|We use `\{api_url\}/api/v1` as the base URL. Find the official docs [here](https://paradox.readme.io/).| |Paradox|`paradox/v1public`|We use `\{api_url\}/api/v1/public` as the base URL. Find the official docs [here](https://paradox.readme.io/).| |Paychex|`paychex/api`|Paychex [REST API](https://developer.paychex.com/documentation). We automatically authenticate all requests and use `https://api.paychex.com` as the base URL.| @@ -901,6 +925,7 @@ async def send_passthrough_request_async( |TalentLMS|`talentlms/v2`|We use `https://\{subdomain\}.talentlms.com/api/v2` as the base URL.| |Teamtailor Job Boards|`teamtailorjobboards/direct-apply`|Teamtailor's [Job Board Direct Apply API](https://partner.teamtailor.com/job_boards/direct_apply/#direct-apply). We automatically authenticate all requests and use `https://5qbn6o9x4h.execute-api.eu-west-1.amazonaws.com/production` as the base URL. All requests are automatically signed with HMAC-SHA256 signature.| |Teamtailor|`teamtailor/v1`|We use `https://api.teamtailor.com/v1` as the base URL. Find the official docs [here](https://docs.teamtailor.com/).| + |TrackerRMS|`trackerrms/v1`|We use `https://evousapi.tracker-rms.com` as the base URL. Find the official docs [here](https://evousapi.tracker-rms.com/swagger/index.html).| |TRAFFIT|`traffit/v2`|Traffit's [v2 API](https://api.traffit.com). We authenticate all requests with the Traffit API key and use the base URL `https://yourdomain.traffit.com/api/integration/v2`.| |TriNet PEO|`trinetpeo/v1`|We use `https://api.trinet.com` as the base URL. Find the official docs [here](https://developers.trinet.com).| |Ubeeo|`ubeeo/api`|Ubeeo ATS API. We automatically authenticate all requests using OAuth client credentials and use `https://api.ats-platform.com` as the base URL (sandbox: `https://api.acc.ats-platform.com`).| @@ -914,6 +939,7 @@ async def send_passthrough_request_async( |Visma YouServe|`youserve/learning`|Visma YouServe [Learning API](https://youserve-domain-api.github.io/SwaggerUI/learning.html). We automatically authenticate all requests using OAuth 2.0 with the provided credentials and use `https://api.youserve.nl/learning/v1.0` as the base URL.| |Workable|`workable/v1`|**Deprecated: Use `v3` instead.** Workable's [API](https://workable.readme.io/reference/generate-an-access-token). We automatically authenticate all requests using the client ID and secret and use `https://\{subdomain\}.\{environment\}.com/spi/v3` as the base URL.| |Workable|`workable/v3`|Workable's [API](https://workable.readme.io/reference/generate-an-access-token). We automatically authenticate all requests using the client ID and secret and use `https://\{subdomain\}.\{environment\}.com/spi/v3` as the base URL.| + |Workday|`workday/custom-report`|[Workday's Custom Reports](https://community.workday.com/sites/default/files/file-hosting/productionapi/index.html). We automatically authenticate all requests and use `https://\{domain\}/ccx/service/customreport2/\{tenant\}/` as the base URL. Set your `method` to `GET`. The `path` should be the report path after the tenant, e.g., `/\{report_owner\}/\{report_name\}`. You can include query parameters in the `params` object (e.g., `format=json`).| |Workday|`workday/rest`|[Workday's REST API](https://community.workday.com/sites/default/files/file-hosting/restapi/index.html). We automatically authenticate all requests and use the correct Workday REST base URL for your tenant. The base URL follows the format: https://\{domain\}/api/\{service_name\}/\{version\}/\{tenant\}. You can specify any valid REST endpoint and method. See the Workday REST API documentation for available endpoints. You must specify the `api_options` object and set `service_name` to the name of the service you want to call. You can also specify the `version` (e.g., \"v1\", \"v2\"); if omitted, it defaults to \"v1\".| |Workday|`workday/soap`|[Workday's SOAP API](https://community.workday.com/sites/default/files/file-hosting/productionapi/index.html). We automatically authenticate all requests. Set `data` to your raw xml string. Use `/` as your `path`, as we will always send requests to `https://\{domain\}/ccx/service/\{tenant\}/\{service_name\}`. Set your `method` to `POST`. You need to specify the `api_options` object and set `service_name` to the name of the service you want to call. Find all available services [here](https://community.workday.com/sites/default/files/file-hosting/productionapi/versions/v41.0/index.html). The string that you submit as `data` will be the content of the `soapenv:Body` tag in the request. You can set the `service_version` to any valid Workday service version (the default is `38.2`).| |workforce.com|`workforcecom/api`|Workforce.com [API](https://my.workforce.com/api/v2/documentation). We automatically authenticate all requests using the provided credentials and use `https://my.tanda.co` as the base URL.| @@ -958,14 +984,14 @@ async def send_passthrough_request_async( body=models.PostPassthroughToolAPIRequestBody( method=method, path=path, - headers=headers, - params=params, + headers=utils.unmarshal(headers, Optional[Dict[str, str]]), + params=utils.unmarshal(params, Optional[Dict[str, str]]), data=data, response_as_base64=response_as_base64, multipart_form_data=utils.get_pydantic_model( multipart_form_data, Optional[List[models.MultipartFormDatum]] ), - api_options=api_options, + api_options=utils.unmarshal(api_options, Optional[Dict[str, str]]), ), ) @@ -1011,6 +1037,8 @@ async def send_passthrough_request_async( operation_id="PostPassthroughToolApi", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["General"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -1111,6 +1139,8 @@ def delete_integration( operation_id="DeleteIntegrationsIntegrationId", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["General"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -1211,6 +1241,8 @@ async def delete_integration_async( operation_id="DeleteIntegrationsIntegrationId", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["General"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -1295,6 +1327,8 @@ def get_integration_details( operation_id="GetIntegrationsIntegrationId", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["General"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -1379,6 +1413,8 @@ async def get_integration_details_async( operation_id="GetIntegrationsIntegrationId", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["General"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -1479,6 +1515,8 @@ def set_integration_enabled( operation_id="PutIntegrationsIntegrationIdEnabled", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["General"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -1579,6 +1617,8 @@ async def set_integration_enabled_async( operation_id="PutIntegrationsIntegrationIdEnabled", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["General"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -1704,6 +1744,8 @@ def create_reconnection_link( operation_id="PostIntegrationsIntegrationIdRelink", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["General"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -1829,6 +1871,8 @@ async def create_reconnection_link_async( operation_id="PostIntegrationsIntegrationIdRelink", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["General"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -1935,6 +1979,8 @@ def create_setup_link( operation_id="PostIntegrationsIntegrationIdSetupLink", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["General"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -2041,6 +2087,8 @@ async def create_setup_link_async( operation_id="PostIntegrationsIntegrationIdSetupLink", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["General"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -2132,6 +2180,8 @@ def get_integration_fields( operation_id="GetIntegrationsIntegrationIdIntegrationFields", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["General"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -2251,6 +2301,8 @@ async def get_integration_fields_async( operation_id="GetIntegrationsIntegrationIdIntegrationFields", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["General"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -2383,6 +2435,8 @@ def update_integration_field( operation_id="PatchIntegrationsIntegrationIdIntegrationFieldsIntegrationFieldId", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["General"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -2483,6 +2537,8 @@ async def update_integration_field_async( operation_id="PatchIntegrationsIntegrationIdIntegrationFieldsIntegrationFieldId", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["General"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -2575,6 +2631,8 @@ def get_custom_fields( operation_id="GetIntegrationsIntegrationIdCustomFields", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["General"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -2694,6 +2752,8 @@ async def get_custom_fields_async( operation_id="GetIntegrationsIntegrationIdCustomFields", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["General"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -2824,6 +2884,8 @@ def update_custom_field_mapping( operation_id="PutIntegrationsIntegrationIdCustomFieldsCustomFieldId", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["General"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -2924,6 +2986,8 @@ async def update_custom_field_mapping_async( operation_id="PutIntegrationsIntegrationIdCustomFieldsCustomFieldId", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["General"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -3010,6 +3074,8 @@ def get_tools( operation_id="GetToolsCategory", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["General"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -3095,6 +3161,8 @@ async def get_tools_async( operation_id="GetToolsCategory", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["General"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), diff --git a/src/kombo/hris.py b/src/kombo/hris.py index 8cd4b95..69084b4 100644 --- a/src/kombo/hris.py +++ b/src/kombo/hris.py @@ -7,7 +7,7 @@ from kombo._hooks import HookContext from kombo.types import Nullable, OptionalNullable, UNSET from kombo.utils.unmarshal_json_response import unmarshal_json_response -from typing import Any, Awaitable, Dict, List, Mapping, Optional, Union +from typing import Any, Awaitable, Dict, Iterable, List, Mapping, Optional, Union class Hris(BaseSDK): @@ -19,14 +19,14 @@ def get_employees( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, - employment_statuses: Optional[List[str]] = None, - group_ids: Optional[List[str]] = None, - legal_entity_ids: Optional[List[str]] = None, - work_location_ids: Optional[List[str]] = None, - work_emails: Optional[List[str]] = None, - personal_emails: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, + employment_statuses: Optional[Iterable[str]] = None, + group_ids: Optional[Iterable[str]] = None, + legal_entity_ids: Optional[Iterable[str]] = None, + work_location_ids: Optional[Iterable[str]] = None, + work_emails: Optional[Iterable[str]] = None, + personal_emails: Optional[Iterable[str]] = None, custom_fields: Optional[str] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, @@ -100,14 +100,16 @@ def get_employees( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, - employment_statuses=employment_statuses, - group_ids=group_ids, - legal_entity_ids=legal_entity_ids, - work_location_ids=work_location_ids, - work_emails=work_emails, - personal_emails=personal_emails, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), + employment_statuses=utils.unmarshal( + employment_statuses, Optional[List[str]] + ), + group_ids=utils.unmarshal(group_ids, Optional[List[str]]), + legal_entity_ids=utils.unmarshal(legal_entity_ids, Optional[List[str]]), + work_location_ids=utils.unmarshal(work_location_ids, Optional[List[str]]), + work_emails=utils.unmarshal(work_emails, Optional[List[str]]), + personal_emails=utils.unmarshal(personal_emails, Optional[List[str]]), custom_fields=custom_fields, ) @@ -146,6 +148,8 @@ def get_employees( operation_id="GetHrisEmployees", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -207,14 +211,14 @@ async def get_employees_async( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, - employment_statuses: Optional[List[str]] = None, - group_ids: Optional[List[str]] = None, - legal_entity_ids: Optional[List[str]] = None, - work_location_ids: Optional[List[str]] = None, - work_emails: Optional[List[str]] = None, - personal_emails: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, + employment_statuses: Optional[Iterable[str]] = None, + group_ids: Optional[Iterable[str]] = None, + legal_entity_ids: Optional[Iterable[str]] = None, + work_location_ids: Optional[Iterable[str]] = None, + work_emails: Optional[Iterable[str]] = None, + personal_emails: Optional[Iterable[str]] = None, custom_fields: Optional[str] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, @@ -288,14 +292,16 @@ async def get_employees_async( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, - employment_statuses=employment_statuses, - group_ids=group_ids, - legal_entity_ids=legal_entity_ids, - work_location_ids=work_location_ids, - work_emails=work_emails, - personal_emails=personal_emails, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), + employment_statuses=utils.unmarshal( + employment_statuses, Optional[List[str]] + ), + group_ids=utils.unmarshal(group_ids, Optional[List[str]]), + legal_entity_ids=utils.unmarshal(legal_entity_ids, Optional[List[str]]), + work_location_ids=utils.unmarshal(work_location_ids, Optional[List[str]]), + work_emails=utils.unmarshal(work_emails, Optional[List[str]]), + personal_emails=utils.unmarshal(personal_emails, Optional[List[str]]), custom_fields=custom_fields, ) @@ -334,6 +340,8 @@ async def get_employees_async( operation_id="GetHrisEmployees", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -536,6 +544,8 @@ def get_employee_form( operation_id="GetHrisEmployeesForm", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -699,6 +709,8 @@ async def get_employee_form_async( operation_id="GetHrisEmployeesForm", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -720,7 +732,7 @@ def create_employee_with_form( self, *, properties: Union[ - Dict[str, models.Schema4], Dict[str, models.Schema4TypedDict] + Mapping[str, models.Schema4], Mapping[str, models.Schema4TypedDict] ], staffing_entity_id: Optional[str] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, @@ -778,7 +790,7 @@ def create_employee_with_form( request = models.PostHrisEmployeesFormRequestBody( staffing_entity_id=staffing_entity_id, - properties=properties, + properties=utils.unmarshal(properties, Dict[str, models.Schema4]), ) req = self._build_request( @@ -819,6 +831,8 @@ def create_employee_with_form( operation_id="PostHrisEmployeesForm", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -840,7 +854,7 @@ async def create_employee_with_form_async( self, *, properties: Union[ - Dict[str, models.Schema4], Dict[str, models.Schema4TypedDict] + Mapping[str, models.Schema4], Mapping[str, models.Schema4TypedDict] ], staffing_entity_id: Optional[str] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, @@ -898,7 +912,7 @@ async def create_employee_with_form_async( request = models.PostHrisEmployeesFormRequestBody( staffing_entity_id=staffing_entity_id, - properties=properties, + properties=utils.unmarshal(properties, Dict[str, models.Schema4]), ) req = self._build_request_async( @@ -939,6 +953,8 @@ async def create_employee_with_form_async( operation_id="PostHrisEmployeesForm", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -1059,6 +1075,8 @@ def add_employee_document( operation_id="PostHrisEmployeesEmployeeIdDocuments", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -1179,6 +1197,8 @@ async def add_employee_document_async( operation_id="PostHrisEmployeesEmployeeIdDocuments", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -1204,8 +1224,8 @@ def get_employee_document_categories( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, @@ -1251,8 +1271,8 @@ def get_employee_document_categories( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), ) req = self._build_request( @@ -1290,6 +1310,8 @@ def get_employee_document_categories( operation_id="GetHrisEmployeeDocumentCategories", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -1344,8 +1366,8 @@ async def get_employee_document_categories_async( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, @@ -1391,8 +1413,8 @@ async def get_employee_document_categories_async( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), ) req = self._build_request_async( @@ -1430,6 +1452,8 @@ async def get_employee_document_categories_async( operation_id="GetHrisEmployeeDocumentCategories", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -1489,9 +1513,9 @@ def get_groups( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, - types: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, + types: Optional[Iterable[str]] = None, name_contains: Optional[str] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, @@ -1542,9 +1566,9 @@ def get_groups( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, - types=types, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), + types=utils.unmarshal(types, Optional[List[str]]), name_contains=name_contains, ) @@ -1583,6 +1607,8 @@ def get_groups( operation_id="GetHrisGroups", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -1639,9 +1665,9 @@ async def get_groups_async( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, - types: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, + types: Optional[Iterable[str]] = None, name_contains: Optional[str] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, @@ -1692,9 +1718,9 @@ async def get_groups_async( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, - types=types, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), + types=utils.unmarshal(types, Optional[List[str]]), name_contains=name_contains, ) @@ -1733,6 +1759,8 @@ async def get_groups_async( operation_id="GetHrisGroups", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -1792,8 +1820,8 @@ def get_employments( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, @@ -1839,8 +1867,8 @@ def get_employments( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), ) req = self._build_request( @@ -1878,6 +1906,8 @@ def get_employments( operation_id="GetHrisEmployments", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -1932,8 +1962,8 @@ async def get_employments_async( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, @@ -1979,8 +2009,8 @@ async def get_employments_async( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), ) req = self._build_request_async( @@ -2018,6 +2048,8 @@ async def get_employments_async( operation_id="GetHrisEmployments", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -2075,8 +2107,8 @@ def get_locations( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, name_contains: Optional[str] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, @@ -2124,8 +2156,8 @@ def get_locations( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), name_contains=name_contains, ) @@ -2164,6 +2196,8 @@ def get_locations( operation_id="GetHrisLocations", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -2219,8 +2253,8 @@ async def get_locations_async( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, name_contains: Optional[str] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, @@ -2268,8 +2302,8 @@ async def get_locations_async( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), name_contains=name_contains, ) @@ -2308,6 +2342,8 @@ async def get_locations_async( operation_id="GetHrisLocations", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -2366,8 +2402,8 @@ def get_absence_types( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, @@ -2413,8 +2449,8 @@ def get_absence_types( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), ) req = self._build_request( @@ -2452,6 +2488,8 @@ def get_absence_types( operation_id="GetHrisAbsenceTypes", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -2506,8 +2544,8 @@ async def get_absence_types_async( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, @@ -2553,8 +2591,8 @@ async def get_absence_types_async( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), ) req = self._build_request_async( @@ -2592,6 +2630,8 @@ async def get_absence_types_async( operation_id="GetHrisAbsenceTypes", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -2649,8 +2689,8 @@ def get_time_off_balances( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, employee_id: Optional[str] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, @@ -2704,8 +2744,8 @@ def get_time_off_balances( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), employee_id=employee_id, ) @@ -2744,6 +2784,8 @@ def get_time_off_balances( operation_id="GetHrisTimeOffBalances", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -2799,8 +2841,8 @@ async def get_time_off_balances_async( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, employee_id: Optional[str] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, @@ -2854,8 +2896,8 @@ async def get_time_off_balances_async( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), employee_id=employee_id, ) @@ -2894,6 +2936,8 @@ async def get_time_off_balances_async( operation_id="GetHrisTimeOffBalances", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -2952,11 +2996,11 @@ def get_absences( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, date_from: Optional[datetime] = None, date_until: Optional[datetime] = None, - type_ids: Optional[List[str]] = None, + type_ids: Optional[Iterable[str]] = None, employee_id: Optional[str] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, @@ -3013,11 +3057,11 @@ def get_absences( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), date_from=date_from, date_until=date_until, - type_ids=type_ids, + type_ids=utils.unmarshal(type_ids, Optional[List[str]]), employee_id=employee_id, ) @@ -3056,6 +3100,8 @@ def get_absences( operation_id="GetHrisAbsences", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -3114,11 +3160,11 @@ async def get_absences_async( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, date_from: Optional[datetime] = None, date_until: Optional[datetime] = None, - type_ids: Optional[List[str]] = None, + type_ids: Optional[Iterable[str]] = None, employee_id: Optional[str] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, @@ -3175,11 +3221,11 @@ async def get_absences_async( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), date_from=date_from, date_until=date_until, - type_ids=type_ids, + type_ids=utils.unmarshal(type_ids, Optional[List[str]]), employee_id=employee_id, ) @@ -3218,6 +3264,8 @@ async def get_absences_async( operation_id="GetHrisAbsences", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -3410,6 +3458,8 @@ def create_absence( operation_id="PostHrisAbsences", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -3566,6 +3616,8 @@ async def create_absence_async( operation_id="PostHrisAbsences", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -3683,6 +3735,8 @@ def delete_absence( operation_id="DeleteHrisAbsencesAbsenceId", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -3800,6 +3854,8 @@ async def delete_absence_async( operation_id="DeleteHrisAbsencesAbsenceId", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -3825,8 +3881,8 @@ def get_legal_entities( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, name_contains: Optional[str] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, @@ -3874,8 +3930,8 @@ def get_legal_entities( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), name_contains=name_contains, ) @@ -3914,6 +3970,8 @@ def get_legal_entities( operation_id="GetHrisLegalEntities", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -3969,8 +4027,8 @@ async def get_legal_entities_async( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, name_contains: Optional[str] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, @@ -4018,8 +4076,8 @@ async def get_legal_entities_async( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), name_contains=name_contains, ) @@ -4058,6 +4116,8 @@ async def get_legal_entities_async( operation_id="GetHrisLegalEntities", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -4116,8 +4176,8 @@ def get_timesheets( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, employee_id: Optional[str] = None, started_before: Optional[datetime] = None, started_after: Optional[datetime] = None, @@ -4179,8 +4239,8 @@ def get_timesheets( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), employee_id=employee_id, started_before=started_before, started_after=started_after, @@ -4223,6 +4283,8 @@ def get_timesheets( operation_id="GetHrisTimesheets", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -4282,8 +4344,8 @@ async def get_timesheets_async( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, employee_id: Optional[str] = None, started_before: Optional[datetime] = None, started_after: Optional[datetime] = None, @@ -4345,8 +4407,8 @@ async def get_timesheets_async( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), employee_id=employee_id, started_before=started_before, started_after=started_after, @@ -4389,6 +4451,8 @@ async def get_timesheets_async( operation_id="GetHrisTimesheets", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -4451,8 +4515,8 @@ def get_performance_review_cycles( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, @@ -4500,8 +4564,8 @@ def get_performance_review_cycles( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), ) req = self._build_request( @@ -4539,6 +4603,8 @@ def get_performance_review_cycles( operation_id="GetHrisPerformanceReviewCycles", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -4593,8 +4659,8 @@ async def get_performance_review_cycles_async( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, @@ -4642,8 +4708,8 @@ async def get_performance_review_cycles_async( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), ) req = self._build_request_async( @@ -4681,6 +4747,8 @@ async def get_performance_review_cycles_async( operation_id="GetHrisPerformanceReviewCycles", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -4740,11 +4808,11 @@ def get_performance_reviews( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, - types: Optional[List[str]] = None, - review_cycle_ids: Optional[List[str]] = None, - reviewee_ids: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, + types: Optional[Iterable[str]] = None, + review_cycle_ids: Optional[Iterable[str]] = None, + reviewee_ids: Optional[Iterable[str]] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, @@ -4805,11 +4873,11 @@ def get_performance_reviews( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, - types=types, - review_cycle_ids=review_cycle_ids, - reviewee_ids=reviewee_ids, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), + types=utils.unmarshal(types, Optional[List[str]]), + review_cycle_ids=utils.unmarshal(review_cycle_ids, Optional[List[str]]), + reviewee_ids=utils.unmarshal(reviewee_ids, Optional[List[str]]), ) req = self._build_request( @@ -4847,6 +4915,8 @@ def get_performance_reviews( operation_id="GetHrisPerformanceReviews", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -4904,11 +4974,11 @@ async def get_performance_reviews_async( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, - types: Optional[List[str]] = None, - review_cycle_ids: Optional[List[str]] = None, - reviewee_ids: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, + types: Optional[Iterable[str]] = None, + review_cycle_ids: Optional[Iterable[str]] = None, + reviewee_ids: Optional[Iterable[str]] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, @@ -4969,11 +5039,11 @@ async def get_performance_reviews_async( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, - types=types, - review_cycle_ids=review_cycle_ids, - reviewee_ids=reviewee_ids, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), + types=utils.unmarshal(types, Optional[List[str]]), + review_cycle_ids=utils.unmarshal(review_cycle_ids, Optional[List[str]]), + reviewee_ids=utils.unmarshal(reviewee_ids, Optional[List[str]]), ) req = self._build_request_async( @@ -5011,6 +5081,8 @@ async def get_performance_reviews_async( operation_id="GetHrisPerformanceReviews", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -5073,10 +5145,10 @@ def get_staffing_entities( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, - model_types: Optional[List[str]] = None, - statuses: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, + model_types: Optional[Iterable[str]] = None, + statuses: Optional[Iterable[str]] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, @@ -5146,10 +5218,10 @@ def get_staffing_entities( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, - model_types=model_types, - statuses=statuses, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), + model_types=utils.unmarshal(model_types, Optional[List[str]]), + statuses=utils.unmarshal(statuses, Optional[List[str]]), ) req = self._build_request( @@ -5187,6 +5259,8 @@ def get_staffing_entities( operation_id="GetHrisStaffingEntities", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), @@ -5243,10 +5317,10 @@ async def get_staffing_entities_async( updated_after: Optional[datetime] = None, include_deleted: Optional[bool] = False, ignore_unsupported_filters: Optional[bool] = False, - ids: Optional[List[str]] = None, - remote_ids: Optional[List[str]] = None, - model_types: Optional[List[str]] = None, - statuses: Optional[List[str]] = None, + ids: Optional[Iterable[str]] = None, + remote_ids: Optional[Iterable[str]] = None, + model_types: Optional[Iterable[str]] = None, + statuses: Optional[Iterable[str]] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, @@ -5316,10 +5390,10 @@ async def get_staffing_entities_async( updated_after=updated_after, include_deleted=include_deleted, ignore_unsupported_filters=ignore_unsupported_filters, - ids=ids, - remote_ids=remote_ids, - model_types=model_types, - statuses=statuses, + ids=utils.unmarshal(ids, Optional[List[str]]), + remote_ids=utils.unmarshal(remote_ids, Optional[List[str]]), + model_types=utils.unmarshal(model_types, Optional[List[str]]), + statuses=utils.unmarshal(statuses, Optional[List[str]]), ) req = self._build_request_async( @@ -5357,6 +5431,8 @@ async def get_staffing_entities_async( operation_id="GetHrisStaffingEntities", oauth2_scopes=None, security_source=self.sdk_configuration.security, + tags=["Unified HRIS API"], + extensions=None, ), request=req, is_error_status_code=lambda c: not utils.match_status_codes(["200"], c), diff --git a/src/kombo/models/__init__.py b/src/kombo/models/__init__.py index be1fd21..d25f8e8 100644 --- a/src/kombo/models/__init__.py +++ b/src/kombo/models/__init__.py @@ -1395,6 +1395,7 @@ PostAtsCandidatesRequestBodyAdditionalPhoneNumber, PostAtsCandidatesRequestBodyAdditionalPhoneNumberType, PostAtsCandidatesRequestBodyAdditionalPhoneNumberTypedDict, + PostAtsCandidatesRequestBodyAktiv, PostAtsCandidatesRequestBodyAnswer, PostAtsCandidatesRequestBodyAnswerTypedDict, PostAtsCandidatesRequestBodyAnswerUnion, @@ -1703,6 +1704,7 @@ PostAtsJobsJobIDApplicationsRequestBodyAdditionalPhoneNumber, PostAtsJobsJobIDApplicationsRequestBodyAdditionalPhoneNumberType, PostAtsJobsJobIDApplicationsRequestBodyAdditionalPhoneNumberTypedDict, + PostAtsJobsJobIDApplicationsRequestBodyAktiv, PostAtsJobsJobIDApplicationsRequestBodyAnswer, PostAtsJobsJobIDApplicationsRequestBodyAnswerTypedDict, PostAtsJobsJobIDApplicationsRequestBodyAnswerUnion, @@ -3300,6 +3302,7 @@ "PostAtsCandidatesRequestBodyAdditionalPhoneNumber", "PostAtsCandidatesRequestBodyAdditionalPhoneNumberType", "PostAtsCandidatesRequestBodyAdditionalPhoneNumberTypedDict", + "PostAtsCandidatesRequestBodyAktiv", "PostAtsCandidatesRequestBodyAnswer", "PostAtsCandidatesRequestBodyAnswerTypedDict", "PostAtsCandidatesRequestBodyAnswerUnion", @@ -3593,6 +3596,7 @@ "PostAtsJobsJobIDApplicationsRequestBodyAdditionalPhoneNumber", "PostAtsJobsJobIDApplicationsRequestBodyAdditionalPhoneNumberType", "PostAtsJobsJobIDApplicationsRequestBodyAdditionalPhoneNumberTypedDict", + "PostAtsJobsJobIDApplicationsRequestBodyAktiv", "PostAtsJobsJobIDApplicationsRequestBodyAnswer", "PostAtsJobsJobIDApplicationsRequestBodyAnswerTypedDict", "PostAtsJobsJobIDApplicationsRequestBodyAnswerUnion", @@ -5213,6 +5217,7 @@ "PostAtsCandidatesRequestBodyAdditionalPhoneNumber": ".postatscandidatesrequestbody", "PostAtsCandidatesRequestBodyAdditionalPhoneNumberType": ".postatscandidatesrequestbody", "PostAtsCandidatesRequestBodyAdditionalPhoneNumberTypedDict": ".postatscandidatesrequestbody", + "PostAtsCandidatesRequestBodyAktiv": ".postatscandidatesrequestbody", "PostAtsCandidatesRequestBodyAnswer": ".postatscandidatesrequestbody", "PostAtsCandidatesRequestBodyAnswerTypedDict": ".postatscandidatesrequestbody", "PostAtsCandidatesRequestBodyAnswerUnion": ".postatscandidatesrequestbody", @@ -5509,6 +5514,7 @@ "PostAtsJobsJobIDApplicationsRequestBodyAdditionalPhoneNumber": ".postatsjobsjobidapplicationsrequestbody", "PostAtsJobsJobIDApplicationsRequestBodyAdditionalPhoneNumberType": ".postatsjobsjobidapplicationsrequestbody", "PostAtsJobsJobIDApplicationsRequestBodyAdditionalPhoneNumberTypedDict": ".postatsjobsjobidapplicationsrequestbody", + "PostAtsJobsJobIDApplicationsRequestBodyAktiv": ".postatsjobsjobidapplicationsrequestbody", "PostAtsJobsJobIDApplicationsRequestBodyAnswer": ".postatsjobsjobidapplicationsrequestbody", "PostAtsJobsJobIDApplicationsRequestBodyAnswerTypedDict": ".postatsjobsjobidapplicationsrequestbody", "PostAtsJobsJobIDApplicationsRequestBodyAnswerUnion": ".postatsjobsjobidapplicationsrequestbody", diff --git a/src/kombo/models/datachangedwebhookpayload.py b/src/kombo/models/datachangedwebhookpayload.py index 5b09624..2572b04 100644 --- a/src/kombo/models/datachangedwebhookpayload.py +++ b/src/kombo/models/datachangedwebhookpayload.py @@ -33,6 +33,10 @@ "hris_performance_reviews", "hris_performance_review_cycles", "hris_staffing_entities", + "hris_skill_proficiency_scales", + "hris_skills", + "hris_skill_rating_providers", + "hris_employee_skill_proficiency_ratings", "ats_users", "ats_jobs", "ats_job_postings", diff --git a/src/kombo/models/postatscandidatesrequestbody.py b/src/kombo/models/postatscandidatesrequestbody.py index 8b75b53..10c979a 100644 --- a/src/kombo/models/postatscandidatesrequestbody.py +++ b/src/kombo/models/postatscandidatesrequestbody.py @@ -2400,6 +2400,13 @@ def serialize_model(self, handler): return m +PostAtsCandidatesRequestBodyAktiv = Literal[ + "Ja", + "Nein", +] +r"""Whether the candidate is created as active (`Ja`) or inactive (`Nein`) in Coveto. If omitted, Coveto applies its default (active).""" + + class PostAtsCandidatesRequestBodyCovetorestCandidateTypedDict(TypedDict): r"""Additional candidate fields that will be passed to the Coveto candidate creation.""" @@ -2407,6 +2414,8 @@ class PostAtsCandidatesRequestBodyCovetorestCandidateTypedDict(TypedDict): r"""The mandant field for the candidate in Coveto.""" status: NotRequired[int] r"""The numeric status ID to assign to the candidate on creation in Coveto. Refer to your Coveto `/bewerber-status` endpoint for available IDs.""" + aktiv: NotRequired[PostAtsCandidatesRequestBodyAktiv] + r"""Whether the candidate is created as active (`Ja`) or inactive (`Nein`) in Coveto. If omitted, Coveto applies its default (active).""" class PostAtsCandidatesRequestBodyCovetorestCandidate(BaseModel): @@ -2418,9 +2427,12 @@ class PostAtsCandidatesRequestBodyCovetorestCandidate(BaseModel): status: Optional[int] = None r"""The numeric status ID to assign to the candidate on creation in Coveto. Refer to your Coveto `/bewerber-status` endpoint for available IDs.""" + aktiv: Optional[PostAtsCandidatesRequestBodyAktiv] = None + r"""Whether the candidate is created as active (`Ja`) or inactive (`Nein`) in Coveto. If omitted, Coveto applies its default (active).""" + @model_serializer(mode="wrap") def serialize_model(self, handler): - optional_fields = set(["mandant", "status"]) + optional_fields = set(["mandant", "status", "aktiv"]) serialized = handler(self) m = {} diff --git a/src/kombo/models/postatsjobsjobidapplicationsrequestbody.py b/src/kombo/models/postatsjobsjobidapplicationsrequestbody.py index 21542d5..09113ee 100644 --- a/src/kombo/models/postatsjobsjobidapplicationsrequestbody.py +++ b/src/kombo/models/postatsjobsjobidapplicationsrequestbody.py @@ -2249,6 +2249,13 @@ def serialize_model(self, handler): return m +PostAtsJobsJobIDApplicationsRequestBodyAktiv = Literal[ + "Ja", + "Nein", +] +r"""Whether the candidate is created as active (`Ja`) or inactive (`Nein`) in Coveto. If omitted, Coveto applies its default (active).""" + + class PostAtsJobsJobIDApplicationsRequestBodyCovetorestCandidateTypedDict(TypedDict): r"""Additional candidate fields that will be passed to the Coveto candidate creation.""" @@ -2256,6 +2263,8 @@ class PostAtsJobsJobIDApplicationsRequestBodyCovetorestCandidateTypedDict(TypedD r"""The mandant field for the candidate in Coveto.""" status: NotRequired[int] r"""The numeric status ID to assign to the candidate on creation in Coveto. Refer to your Coveto `/bewerber-status` endpoint for available IDs.""" + aktiv: NotRequired[PostAtsJobsJobIDApplicationsRequestBodyAktiv] + r"""Whether the candidate is created as active (`Ja`) or inactive (`Nein`) in Coveto. If omitted, Coveto applies its default (active).""" class PostAtsJobsJobIDApplicationsRequestBodyCovetorestCandidate(BaseModel): @@ -2267,9 +2276,12 @@ class PostAtsJobsJobIDApplicationsRequestBodyCovetorestCandidate(BaseModel): status: Optional[int] = None r"""The numeric status ID to assign to the candidate on creation in Coveto. Refer to your Coveto `/bewerber-status` endpoint for available IDs.""" + aktiv: Optional[PostAtsJobsJobIDApplicationsRequestBodyAktiv] = None + r"""Whether the candidate is created as active (`Ja`) or inactive (`Nein`) in Coveto. If omitted, Coveto applies its default (active).""" + @model_serializer(mode="wrap") def serialize_model(self, handler): - optional_fields = set(["mandant", "status"]) + optional_fields = set(["mandant", "status", "aktiv"]) serialized = handler(self) m = {} diff --git a/src/kombo/models/postconnectcreatelinkrequestbody.py b/src/kombo/models/postconnectcreatelinkrequestbody.py index c0cd102..51ad9fb 100644 --- a/src/kombo/models/postconnectcreatelinkrequestbody.py +++ b/src/kombo/models/postconnectcreatelinkrequestbody.py @@ -128,9 +128,13 @@ "logicmelon", "loxo", "kula", + "trackerrms", + "databites", + "pageup", "workdaycustomreport", "workdaycustomreportsftp", "ukgprowfm", + "adpdecidium", "payfitcustomer", "payfitpartner", "payfit", @@ -209,6 +213,8 @@ "sftpfetch", "360learning", "talentlms", + "docebo", + "coursera", "udemy", "linkedinlearning", "moodle", diff --git a/src/kombo/types/base64fileinput.py b/src/kombo/types/base64fileinput.py index 25fc539..862566f 100644 --- a/src/kombo/types/base64fileinput.py +++ b/src/kombo/types/base64fileinput.py @@ -23,7 +23,11 @@ def encode_base64_file_input(value: Any) -> Any: with open(value, "rb") as fh: binary = fh.read() else: + # Restore position after reading: pydantic may validate the same stream more than once. + position = value.tell() if value.seekable() else None binary = value.read() + if position is not None: + value.seek(position) if isinstance(binary, str): binary = binary.encode() if not isinstance(binary, (bytes, bytearray)): diff --git a/src/kombo/utils/eventstreaming.py b/src/kombo/utils/eventstreaming.py index 3bdcd6d..a8d4fe5 100644 --- a/src/kombo/utils/eventstreaming.py +++ b/src/kombo/utils/eventstreaming.py @@ -7,6 +7,7 @@ Any, Callable, Generic, + List, TypeVar, Optional, Generator, @@ -53,6 +54,9 @@ def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): + self.close() + + def close(self): self._closed = True self.response.close() @@ -92,6 +96,9 @@ async def __aenter__(self): return self async def __aexit__(self, exc_type, exc_val, exc_tb): + await self.close() + + async def close(self): self._closed = True await self.response.aclose() @@ -114,6 +121,7 @@ class ServerEvent: b"\n\r", b"\n\n", ] +MAX_BOUNDARY_LEN = max(len(b) for b in MESSAGE_BOUNDARIES) UTF8_BOM = b"\xef\xbb\xbf" @@ -124,52 +132,56 @@ async def stream_events_async( sentinel: Optional[str] = None, data_required: bool = True, ) -> AsyncGenerator[T, None]: - buffer = bytearray() - position = 0 - event_id: Optional[str] = None - async for chunk in response.aiter_bytes(): - if len(buffer) == 0 and chunk.startswith(UTF8_BOM): - chunk = chunk[len(UTF8_BOM) :] - buffer += chunk - for i in range(position, len(buffer)): - char = buffer[i : i + 1] - seq: Optional[bytes] = None - if char in [b"\r", b"\n"]: - for boundary in MESSAGE_BOUNDARIES: - seq = _peek_sequence(i, buffer, boundary) - if seq is not None: - break - if seq is None: - continue - - block = buffer[position:i] - position = i + len(seq) - event, discard, event_id = _parse_event( - raw=block, - decoder=decoder, - sentinel=sentinel, - event_id=event_id, - data_required=data_required, - ) - if event is not None: - yield event - if discard: - await response.aclose() - return - - if position > 0: - buffer = buffer[position:] - position = 0 - - event, discard, _ = _parse_event( - raw=buffer, - decoder=decoder, - sentinel=sentinel, - event_id=event_id, - data_required=data_required, - ) - if event is not None: - yield event + try: + buffer = bytearray() + position = 0 + event_id: Optional[str] = None + async for chunk in response.aiter_bytes(): + if len(buffer) == 0 and chunk.startswith(UTF8_BOM): + chunk = chunk[len(UTF8_BOM) :] + old_len = len(buffer) + buffer += chunk + search_start = max(position, old_len - MAX_BOUNDARY_LEN + 1) + for i in range(search_start, len(buffer)): + char = buffer[i : i + 1] + seq: Optional[bytes] = None + if char in [b"\r", b"\n"]: + for boundary in MESSAGE_BOUNDARIES: + seq = _peek_sequence(i, buffer, boundary) + if seq is not None: + break + if seq is None: + continue + + block = buffer[position:i] + position = i + len(seq) + event, discard, event_id = _parse_event( + raw=block, + decoder=decoder, + sentinel=sentinel, + event_id=event_id, + data_required=data_required, + ) + if event is not None: + yield event + if discard: + return + + if position > 0: + buffer = buffer[position:] + position = 0 + + event, discard, _ = _parse_event( + raw=buffer, + decoder=decoder, + sentinel=sentinel, + event_id=event_id, + data_required=data_required, + ) + if event is not None: + yield event + finally: + await response.aclose() def stream_events( @@ -178,52 +190,56 @@ def stream_events( sentinel: Optional[str] = None, data_required: bool = True, ) -> Generator[T, None, None]: - buffer = bytearray() - position = 0 - event_id: Optional[str] = None - for chunk in response.iter_bytes(): - if len(buffer) == 0 and chunk.startswith(UTF8_BOM): - chunk = chunk[len(UTF8_BOM) :] - buffer += chunk - for i in range(position, len(buffer)): - char = buffer[i : i + 1] - seq: Optional[bytes] = None - if char in [b"\r", b"\n"]: - for boundary in MESSAGE_BOUNDARIES: - seq = _peek_sequence(i, buffer, boundary) - if seq is not None: - break - if seq is None: - continue - - block = buffer[position:i] - position = i + len(seq) - event, discard, event_id = _parse_event( - raw=block, - decoder=decoder, - sentinel=sentinel, - event_id=event_id, - data_required=data_required, - ) - if event is not None: - yield event - if discard: - response.close() - return - - if position > 0: - buffer = buffer[position:] - position = 0 - - event, discard, _ = _parse_event( - raw=buffer, - decoder=decoder, - sentinel=sentinel, - event_id=event_id, - data_required=data_required, - ) - if event is not None: - yield event + try: + buffer = bytearray() + position = 0 + event_id: Optional[str] = None + for chunk in response.iter_bytes(): + if len(buffer) == 0 and chunk.startswith(UTF8_BOM): + chunk = chunk[len(UTF8_BOM) :] + old_len = len(buffer) + buffer += chunk + search_start = max(position, old_len - MAX_BOUNDARY_LEN + 1) + for i in range(search_start, len(buffer)): + char = buffer[i : i + 1] + seq: Optional[bytes] = None + if char in [b"\r", b"\n"]: + for boundary in MESSAGE_BOUNDARIES: + seq = _peek_sequence(i, buffer, boundary) + if seq is not None: + break + if seq is None: + continue + + block = buffer[position:i] + position = i + len(seq) + event, discard, event_id = _parse_event( + raw=block, + decoder=decoder, + sentinel=sentinel, + event_id=event_id, + data_required=data_required, + ) + if event is not None: + yield event + if discard: + return + + if position > 0: + buffer = buffer[position:] + position = 0 + + event, discard, _ = _parse_event( + raw=buffer, + decoder=decoder, + sentinel=sentinel, + event_id=event_id, + data_required=data_required, + ) + if event is not None: + yield event + finally: + response.close() def _parse_event( @@ -238,7 +254,7 @@ def _parse_event( lines = re.split(r"\r?\n|\r", block) publish = False event = ServerEvent() - data = "" + data_parts: List[str] = [] for line in lines: if not line: continue @@ -259,7 +275,7 @@ def _parse_event( event.event = value publish = True elif field == "data": - data += value + "\n" + data_parts.append(value) publish = True elif field == "id": publish = True @@ -271,16 +287,17 @@ def _parse_event( publish = True event.id = event_id + has_data = bool(data_parts) + data = "\n".join(data_parts) - if sentinel and data == f"{sentinel}\n": + if sentinel and has_data and data == sentinel: return None, True, event_id # Skip data-less events when data is required - if not data and publish and data_required: + if not has_data and publish and data_required: return None, False, event_id - if data: - data = data[:-1] + if has_data: try: event.data = json.loads(data) except json.JSONDecodeError: @@ -291,7 +308,7 @@ def _parse_event( out_dict = { k: v for k, v in asdict(event).items() - if v is not None or (k == "data" and data) + if v is not None or (k == "data" and has_data) } out = decoder(json.dumps(out_dict)) diff --git a/src/kombo/utils/forms.py b/src/kombo/utils/forms.py index f961e76..fdf0dc9 100644 --- a/src/kombo/utils/forms.py +++ b/src/kombo/utils/forms.py @@ -1,5 +1,6 @@ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" +import io from typing import ( Any, Dict, @@ -103,6 +104,10 @@ def _extract_file_properties(file_obj: Any) -> Tuple[str, Any, Any]: if file_metadata.content: content = getattr(file_obj, file_field_name, None) + if isinstance(content, io.TextIOBase): + content = content.read().encode( + getattr(content, "encoding", None) or "utf-8" + ) elif file_field_name == "content_type": content_type = getattr(file_obj, file_field_name, None) else: diff --git a/src/kombo/utils/retries.py b/src/kombo/utils/retries.py index af07d4e..ca7b59e 100644 --- a/src/kombo/utils/retries.py +++ b/src/kombo/utils/retries.py @@ -11,10 +11,13 @@ class BackoffStrategy: + """Exponential backoff strategy configuration.""" + initial_interval: int max_interval: int exponent: float max_elapsed_time: int + jitter_ms: Optional[int] def __init__( self, @@ -22,24 +25,63 @@ def __init__( max_interval: int, exponent: float, max_elapsed_time: int, + jitter_ms: Optional[int] = None, ): + """Initialize a backoff strategy. + + Args: + initial_interval: Initial retry interval in milliseconds. + max_interval: Maximum retry interval in milliseconds. + exponent: Base of the exponential backoff; the interval grows as + ``initial_interval * exponent ** retries``. + max_elapsed_time: Maximum total elapsed time in milliseconds. + jitter_ms: Additive jitter bound in milliseconds. When set, adds a random + value in ``[0, jitter_ms]`` to each computed backoff interval (default + ``+[0, 1s]``). + + Note: + When a response carries a ``Retry-After`` or ``retry-after-ms`` header, + that delay is used as-is and the sleep-shaping parameters + (``initial_interval``, ``max_interval``, ``exponent``, ``jitter_ms``) are + ignored for that attempt. + """ + if jitter_ms is not None and jitter_ms < 0: + raise ValueError("jitter_ms must be >= 0") self.initial_interval = initial_interval self.max_interval = max_interval self.exponent = exponent self.max_elapsed_time = max_elapsed_time + self.jitter_ms = jitter_ms class RetryConfig: + """Runtime retry configuration.""" + strategy: str backoff: BackoffStrategy retry_connection_errors: bool + status_codes_override: Optional[List[str]] def __init__( - self, strategy: str, backoff: BackoffStrategy, retry_connection_errors: bool + self, + strategy: str, + backoff: BackoffStrategy, + retry_connection_errors: bool, + status_codes_override: Optional[List[str]] = None, ): + """Initialize a retry configuration. + + Args: + strategy: Retry strategy: ``"none"`` or ``"backoff"``. + backoff: Backoff parameters. + retry_connection_errors: Whether to also retry transport-level connection errors. + status_codes_override: Retryable HTTP status codes that take precedence over the + per-operation defaults when non-empty. + """ self.strategy = strategy self.backoff = backoff self.retry_connection_errors = retry_connection_errors + self.status_codes_override = status_codes_override class Retries: @@ -48,7 +90,7 @@ class Retries: def __init__(self, config: RetryConfig, status_codes: List[str]): self.config = config - self.status_codes = status_codes + self.status_codes = config.status_codes_override or status_codes class TemporaryError(Exception): @@ -93,12 +135,28 @@ def _parse_retry_after_header(response: httpx.Response) -> Optional[int]: return None +def _parse_retry_after_ms_header(response: httpx.Response) -> Optional[int]: + retry_after_ms_header = response.headers.get("retry-after-ms") + if not retry_after_ms_header: + return None + + try: + milliseconds = float(retry_after_ms_header) + if milliseconds >= 0: + return round(milliseconds) + except (OverflowError, ValueError): + pass + + return None + + def _get_sleep_interval( exception: Exception, initial_interval: int, max_interval: int, exponent: float, retries: int, + jitter_ms: Optional[int] = None, ) -> float: """Get sleep interval for retry with exponential backoff. @@ -108,6 +166,7 @@ def _get_sleep_interval( max_interval: Maximum retry interval in milliseconds. exponent: Base for exponential backoff calculation. retries: Current retry attempt count. + jitter_ms: Additive jitter bound in ms; see ``BackoffStrategy.jitter_ms``. Returns: Sleep interval in seconds. @@ -119,7 +178,11 @@ def _get_sleep_interval( ): return exception.retry_after / 1000 - sleep = (initial_interval / 1000) * exponent**retries + random.uniform(0, 1) + sleep = (initial_interval / 1000) * exponent**retries + if jitter_ms is not None: + sleep += random.uniform(0, jitter_ms / 1000) + else: + sleep += random.uniform(0, 1) return min(sleep, max_interval / 1000) @@ -162,6 +225,7 @@ def do_request() -> httpx.Response: retries.config.backoff.max_interval, retries.config.backoff.exponent, retries.config.backoff.max_elapsed_time, + retries.config.backoff.jitter_ms, ) return func() @@ -206,6 +270,7 @@ async def do_request() -> httpx.Response: retries.config.backoff.max_interval, retries.config.backoff.exponent, retries.config.backoff.max_elapsed_time, + retries.config.backoff.jitter_ms, ) return await func() @@ -217,6 +282,7 @@ def retry_with_backoff( max_interval=60000, exponent=1.5, max_elapsed_time=3600000, + jitter_ms=None, ): start = round(time.time() * 1000) retries = 0 @@ -234,8 +300,17 @@ def retry_with_backoff( raise + if isinstance(exception, TemporaryError): + retry_after_ms = _parse_retry_after_ms_header(exception.response) + if retry_after_ms is not None: + exception.retry_after = retry_after_ms sleep = _get_sleep_interval( - exception, initial_interval, max_interval, exponent, retries + exception, + initial_interval, + max_interval, + exponent, + retries, + jitter_ms=jitter_ms, ) time.sleep(sleep) retries += 1 @@ -247,6 +322,7 @@ async def retry_with_backoff_async( max_interval=60000, exponent=1.5, max_elapsed_time=3600000, + jitter_ms=None, ): start = round(time.time() * 1000) retries = 0 @@ -264,8 +340,17 @@ async def retry_with_backoff_async( raise + if isinstance(exception, TemporaryError): + retry_after_ms = _parse_retry_after_ms_header(exception.response) + if retry_after_ms is not None: + exception.retry_after = retry_after_ms sleep = _get_sleep_interval( - exception, initial_interval, max_interval, exponent, retries + exception, + initial_interval, + max_interval, + exponent, + retries, + jitter_ms=jitter_ms, ) await asyncio.sleep(sleep) retries += 1 diff --git a/src/kombo/utils/serializers.py b/src/kombo/utils/serializers.py index d2149f8..1031ed9 100644 --- a/src/kombo/utils/serializers.py +++ b/src/kombo/utils/serializers.py @@ -4,7 +4,7 @@ import functools import json import typing -from typing import Any, Dict, List, Tuple, Union, get_args +from typing import Any, Dict, Iterable, List, Mapping, Tuple, Union, get_args import typing_extensions from typing_extensions import get_origin @@ -113,10 +113,12 @@ def validate(c): def unmarshal_json(raw, typ: Any) -> Any: - return unmarshal(from_json(raw), typ) + return unmarshal(from_json(raw), typ, coerce_iterables=False) -def unmarshal(val, typ: Any) -> Any: +def unmarshal(val, typ: Any, coerce_iterables: bool = True) -> Any: + if coerce_iterables: + val = _coerce_iterables_for_type(val, typ) unmarshaller = create_model( "Unmarshaller", body=(typ, ...), @@ -193,9 +195,88 @@ def get_pydantic_model(data: Any, typ: Any) -> Any: if not _contains_pydantic_model(data): return unmarshal(data, typ) + return _coerce_iterables_for_type(data, typ) + + +def _coerce_iterables_for_type(data: Any, typ: Any) -> Any: + if data is None or isinstance(data, (BaseModel, Unset)): + return data + + typ = _resolve_type_alias(typ) + origin = get_origin(typ) + + if _is_annotated_type(origin): + args = get_args(typ) + return _coerce_iterables_for_type(data, args[0]) if args else data + + if is_union(origin): + for arg in (arg for arg in get_args(typ) if arg is not type(None)): + coerced = _coerce_iterables_for_type(data, arg) + if coerced is not data: + return coerced + return data + + if _is_list_type(typ): + item_type = get_args(typ)[0] if get_args(typ) else Any + if isinstance(data, (str, bytes, bytearray, Mapping)): + return data + if isinstance(data, Iterable): + return [_coerce_iterables_for_type(item, item_type) for item in data] + return data + + if _is_mapping_type(typ): + value_type = get_args(typ)[1] if len(get_args(typ)) > 1 else Any + if isinstance(data, Mapping): + return { + key: _coerce_iterables_for_type(value, value_type) + for key, value in data.items() + } + return data + + if _is_pydantic_model_type(typ) and isinstance(data, Mapping): + coerced = None + for field_name, field in typ.model_fields.items(): + field_type = field.annotation + for key in (field_name, field.alias): + if key is not None and key in data: + value = data[key] if coerced is None else coerced[key] + coerced_value = _coerce_iterables_for_type(value, field_type) + if coerced_value is not value: + if coerced is None: + coerced = dict(data) + coerced[key] = coerced_value + return coerced if coerced is not None else data + return data +def _resolve_type_alias(typ: Any) -> Any: + return getattr(typ, "__value__", typ) + + +def _is_annotated_type(origin: Any) -> bool: + return any( + origin is typing_obj + for typing_obj in _get_typing_objects_by_name_of("Annotated") + ) + + +def _is_list_type(typ: Any) -> bool: + typ = _resolve_type_alias(typ) + return typ is list or get_origin(typ) is list + + +def _is_mapping_type(typ: Any) -> bool: + typ = _resolve_type_alias(typ) + origin = get_origin(typ) + mapping_origin = get_origin(Mapping[Any, Any]) + return typ in (dict, Dict, Mapping) or origin in (dict, Mapping, mapping_origin) + + +def _is_pydantic_model_type(typ: Any) -> bool: + return isinstance(typ, type) and issubclass(typ, BaseModel) + + def _contains_pydantic_model(data: Any) -> bool: if isinstance(data, BaseModel): return True diff --git a/uv.lock b/uv.lock index 2f5a745..b33186b 100644 --- a/uv.lock +++ b/uv.lock @@ -84,7 +84,7 @@ name = "exceptiongroup" version = "1.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" } wheels = [ @@ -191,7 +191,7 @@ wheels = [ [[package]] name = "kombo" -version = "1.2.0" +version = "1.3.0" source = { editable = "." } dependencies = [ { name = "httpcore" }, @@ -215,7 +215,7 @@ requires-dist = [ { name = "httpcore", specifier = ">=1.0.9" }, { name = "httpx", specifier = ">=0.28.1" }, { name = "jsonpath-python", specifier = ">=1.0.6" }, - { name = "pydantic", specifier = ">=2.11.2" }, + { name = "pydantic", specifier = ">=2.11.2,<2.13" }, ] [package.metadata.requires-dev]