├── .devcontainer ├── Dockerfile └── devcontainer.json ├── .github └── workflows │ ├── ci.yml │ ├── publish-pypi.yml │ └── release-doctor.yml ├── .gitignore ├── .python-version ├── .release-please-manifest.json ├── .stats.yml ├── Brewfile ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── SECURITY.md ├── api.md ├── bin ├── check-release-environment └── publish-pypi ├── examples └── .keep ├── mypy.ini ├── noxfile.py ├── pyproject.toml ├── release-please-config.json ├── requirements-dev.lock ├── requirements.lock ├── scripts ├── bootstrap ├── format ├── lint ├── mock ├── test └── utils │ ├── ruffen-docs.py │ └── upload-artifact.sh ├── src ├── knock │ └── lib │ │ └── .keep └── knockapi │ ├── __init__.py │ ├── _base_client.py │ ├── _client.py │ ├── _compat.py │ ├── _constants.py │ ├── _exceptions.py │ ├── _files.py │ ├── _models.py │ ├── _qs.py │ ├── _resource.py │ ├── _response.py │ ├── _streaming.py │ ├── _types.py │ ├── _utils │ ├── __init__.py │ ├── _logs.py │ ├── _proxy.py │ ├── _reflection.py │ ├── _resources_proxy.py │ ├── _streams.py │ ├── _sync.py │ ├── _transform.py │ ├── _typing.py │ └── _utils.py │ ├── _version.py │ ├── lib │ └── .keep │ ├── pagination.py │ ├── py.typed │ ├── resources │ ├── __init__.py │ ├── audiences.py │ ├── bulk_operations.py │ ├── channels │ │ ├── __init__.py │ │ ├── bulk.py │ │ └── channels.py │ ├── integrations │ │ ├── __init__.py │ │ ├── census.py │ │ ├── hightouch.py │ │ └── integrations.py │ ├── messages │ │ ├── __init__.py │ │ ├── batch.py │ │ └── messages.py │ ├── objects │ │ ├── __init__.py │ │ ├── bulk.py │ │ └── objects.py │ ├── providers │ │ ├── __init__.py │ │ ├── ms_teams.py │ │ ├── providers.py │ │ └── slack.py │ ├── schedules │ │ ├── __init__.py │ │ ├── bulk.py │ │ └── schedules.py │ ├── tenants │ │ ├── __init__.py │ │ ├── bulk.py │ │ └── tenants.py │ ├── users │ │ ├── __init__.py │ │ ├── bulk.py │ │ ├── feeds.py │ │ ├── guides.py │ │ └── users.py │ └── workflows.py │ └── types │ ├── __init__.py │ ├── activity.py │ ├── audience_add_members_params.py │ ├── audience_add_members_response.py │ ├── audience_list_members_response.py │ ├── audience_member.py │ ├── audience_remove_members_params.py │ ├── audience_remove_members_response.py │ ├── bulk_operation.py │ ├── channels │ ├── __init__.py │ └── bulk_update_message_status_params.py │ ├── condition.py │ ├── condition_param.py │ ├── inline_identify_user_request_param.py │ ├── inline_object_request_param.py │ ├── inline_tenant_request_param.py │ ├── integrations │ ├── __init__.py │ ├── census_custom_destination_params.py │ ├── census_custom_destination_response.py │ ├── hightouch_embedded_destination_params.py │ └── hightouch_embedded_destination_response.py │ ├── message.py │ ├── message_delivery_log.py │ ├── message_event.py │ ├── message_get_content_response.py │ ├── message_list_activities_params.py │ ├── message_list_delivery_logs_params.py │ ├── message_list_events_params.py │ ├── message_list_params.py │ ├── message_mark_as_interacted_params.py │ ├── messages │ ├── __init__.py │ ├── batch_archive_params.py │ ├── batch_archive_response.py │ ├── batch_get_content_params.py │ ├── batch_get_content_response.py │ ├── batch_mark_as_interacted_params.py │ ├── batch_mark_as_interacted_response.py │ ├── batch_mark_as_read_params.py │ ├── batch_mark_as_read_response.py │ ├── batch_mark_as_seen_params.py │ ├── batch_mark_as_seen_response.py │ ├── batch_mark_as_unread_params.py │ ├── batch_mark_as_unread_response.py │ ├── batch_mark_as_unseen_params.py │ ├── batch_mark_as_unseen_response.py │ ├── batch_unarchive_params.py │ └── batch_unarchive_response.py │ ├── object.py │ ├── object_add_subscriptions_params.py │ ├── object_add_subscriptions_response.py │ ├── object_delete_response.py │ ├── object_delete_subscriptions_params.py │ ├── object_delete_subscriptions_response.py │ ├── object_list_messages_params.py │ ├── object_list_params.py │ ├── object_list_preferences_response.py │ ├── object_list_schedules_params.py │ ├── object_list_subscriptions_params.py │ ├── object_set_channel_data_params.py │ ├── object_set_params.py │ ├── object_set_preferences_params.py │ ├── object_unset_channel_data_response.py │ ├── objects │ ├── __init__.py │ ├── bulk_add_subscriptions_params.py │ ├── bulk_delete_params.py │ └── bulk_set_params.py │ ├── page_info.py │ ├── providers │ ├── __init__.py │ ├── ms_team_check_auth_params.py │ ├── ms_team_check_auth_response.py │ ├── ms_team_list_channels_params.py │ ├── ms_team_list_channels_response.py │ ├── ms_team_list_teams_params.py │ ├── ms_team_list_teams_response.py │ ├── ms_team_revoke_access_params.py │ ├── ms_team_revoke_access_response.py │ ├── slack_check_auth_params.py │ ├── slack_check_auth_response.py │ ├── slack_list_channels_params.py │ ├── slack_list_channels_response.py │ ├── slack_revoke_access_params.py │ └── slack_revoke_access_response.py │ ├── recipient.py │ ├── recipient_reference.py │ ├── recipient_reference_param.py │ ├── recipient_request_param.py │ ├── recipients │ ├── __init__.py │ ├── channel_data.py │ ├── discord_channel_data.py │ ├── discord_channel_data_param.py │ ├── inline_channel_data_request_param.py │ ├── inline_preference_set_request_param.py │ ├── ms_teams_channel_data.py │ ├── ms_teams_channel_data_param.py │ ├── one_signal_channel_data.py │ ├── one_signal_channel_data_param.py │ ├── preference_set.py │ ├── preference_set_channel_type_setting.py │ ├── preference_set_channel_type_setting_param.py │ ├── preference_set_channel_types.py │ ├── preference_set_channel_types_param.py │ ├── preference_set_request_param.py │ ├── push_channel_data.py │ ├── push_channel_data_param.py │ ├── slack_channel_data.py │ ├── slack_channel_data_param.py │ └── subscription.py │ ├── schedule.py │ ├── schedule_create_params.py │ ├── schedule_create_response.py │ ├── schedule_delete_params.py │ ├── schedule_delete_response.py │ ├── schedule_list_params.py │ ├── schedule_repeat_rule.py │ ├── schedule_repeat_rule_param.py │ ├── schedule_update_params.py │ ├── schedule_update_response.py │ ├── schedules │ ├── __init__.py │ └── bulk_create_params.py │ ├── tenant.py │ ├── tenant_delete_response.py │ ├── tenant_list_params.py │ ├── tenant_request_param.py │ ├── tenant_set_params.py │ ├── tenants │ ├── __init__.py │ ├── bulk_delete_params.py │ └── bulk_set_params.py │ ├── user.py │ ├── user_delete_response.py │ ├── user_get_preferences_params.py │ ├── user_list_messages_params.py │ ├── user_list_params.py │ ├── user_list_preferences_response.py │ ├── user_list_schedules_params.py │ ├── user_list_subscriptions_params.py │ ├── user_merge_params.py │ ├── user_set_channel_data_params.py │ ├── user_set_preferences_params.py │ ├── user_unset_channel_data_response.py │ ├── user_update_params.py │ ├── users │ ├── __init__.py │ ├── bulk_delete_params.py │ ├── bulk_identify_params.py │ ├── bulk_set_preferences_params.py │ ├── feed_get_settings_response.py │ ├── feed_list_items_params.py │ ├── feed_list_items_response.py │ ├── guide_get_channel_params.py │ ├── guide_get_channel_response.py │ ├── guide_mark_message_as_archived_params.py │ ├── guide_mark_message_as_archived_response.py │ ├── guide_mark_message_as_interacted_params.py │ ├── guide_mark_message_as_interacted_response.py │ ├── guide_mark_message_as_seen_params.py │ └── guide_mark_message_as_seen_response.py │ ├── workflow_cancel_params.py │ ├── workflow_cancel_response.py │ ├── workflow_trigger_params.py │ └── workflow_trigger_response.py └── tests ├── __init__.py ├── api_resources ├── __init__.py ├── channels │ ├── __init__.py │ └── test_bulk.py ├── integrations │ ├── __init__.py │ ├── test_census.py │ └── test_hightouch.py ├── messages │ ├── __init__.py │ └── test_batch.py ├── objects │ ├── __init__.py │ └── test_bulk.py ├── providers │ ├── __init__.py │ ├── test_ms_teams.py │ └── test_slack.py ├── schedules │ ├── __init__.py │ └── test_bulk.py ├── tenants │ ├── __init__.py │ └── test_bulk.py ├── test_audiences.py ├── test_bulk_operations.py ├── test_messages.py ├── test_objects.py ├── test_schedules.py ├── test_tenants.py ├── test_users.py ├── test_workflows.py └── users │ ├── __init__.py │ ├── test_bulk.py │ ├── test_feeds.py │ └── test_guides.py ├── conftest.py ├── sample_file.txt ├── test_client.py ├── test_deepcopy.py ├── test_extract_files.py ├── test_files.py ├── test_models.py ├── test_qs.py ├── test_required_args.py ├── test_response.py ├── test_streaming.py ├── test_transform.py ├── test_utils ├── test_proxy.py └── test_typing.py └── utils.py /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG VARIANT="3.9" 2 | FROM mcr.microsoft.com/vscode/devcontainers/python:0-${VARIANT} 3 | 4 | USER vscode 5 | 6 | RUN curl -sSf https://rye.astral.sh/get | RYE_VERSION="0.44.0" RYE_INSTALL_OPTION="--yes" bash 7 | ENV PATH=/home/vscode/.rye/shims:$PATH 8 | 9 | RUN echo "[[ -d .venv ]] && source .venv/bin/activate || export PATH=\$PATH" >> /home/vscode/.bashrc 10 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the 2 | // README at: https://github.com/devcontainers/templates/tree/main/src/debian 3 | { 4 | "name": "Debian", 5 | "build": { 6 | "dockerfile": "Dockerfile", 7 | "context": ".." 8 | }, 9 | 10 | "postStartCommand": "rye sync --all-features", 11 | 12 | "customizations": { 13 | "vscode": { 14 | "extensions": [ 15 | "ms-python.python" 16 | ], 17 | "settings": { 18 | "terminal.integrated.shell.linux": "/bin/bash", 19 | "python.pythonPath": ".venv/bin/python", 20 | "python.defaultInterpreterPath": ".venv/bin/python", 21 | "python.typeChecking": "basic", 22 | "terminal.integrated.env.linux": { 23 | "PATH": "/home/vscode/.rye/shims:${env:PATH}" 24 | } 25 | } 26 | } 27 | }, 28 | "features": { 29 | "ghcr.io/devcontainers/features/node:1": {} 30 | } 31 | 32 | // Features to add to the dev container. More info: https://containers.dev/features. 33 | // "features": {}, 34 | 35 | // Use 'forwardPorts' to make a list of ports inside the container available locally. 36 | // "forwardPorts": [], 37 | 38 | // Configure tool-specific properties. 39 | // "customizations": {}, 40 | 41 | // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. 42 | // "remoteUser": "root" 43 | } 44 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | push: 4 | branches-ignore: 5 | - 'generated' 6 | - 'codegen/**' 7 | - 'integrated/**' 8 | - 'stl-preview-head/**' 9 | - 'stl-preview-base/**' 10 | 11 | jobs: 12 | lint: 13 | timeout-minutes: 10 14 | name: lint 15 | runs-on: ${{ github.repository == 'stainless-sdks/knock-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} 16 | steps: 17 | - uses: actions/checkout@v4 18 | 19 | - name: Install Rye 20 | run: | 21 | curl -sSf https://rye.astral.sh/get | bash 22 | echo "$HOME/.rye/shims" >> $GITHUB_PATH 23 | env: 24 | RYE_VERSION: '0.44.0' 25 | RYE_INSTALL_OPTION: '--yes' 26 | 27 | - name: Install dependencies 28 | run: rye sync --all-features 29 | 30 | - name: Run lints 31 | run: ./scripts/lint 32 | 33 | upload: 34 | if: github.repository == 'stainless-sdks/knock-python' 35 | timeout-minutes: 10 36 | name: upload 37 | permissions: 38 | contents: read 39 | id-token: write 40 | runs-on: depot-ubuntu-24.04 41 | steps: 42 | - uses: actions/checkout@v4 43 | 44 | - name: Get GitHub OIDC Token 45 | id: github-oidc 46 | uses: actions/github-script@v6 47 | with: 48 | script: core.setOutput('github_token', await core.getIDToken()); 49 | 50 | - name: Upload tarball 51 | env: 52 | URL: https://pkg.stainless.com/s 53 | AUTH: ${{ steps.github-oidc.outputs.github_token }} 54 | SHA: ${{ github.sha }} 55 | run: ./scripts/utils/upload-artifact.sh 56 | 57 | test: 58 | timeout-minutes: 10 59 | name: test 60 | runs-on: ${{ github.repository == 'stainless-sdks/knock-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} 61 | steps: 62 | - uses: actions/checkout@v4 63 | 64 | - name: Install Rye 65 | run: | 66 | curl -sSf https://rye.astral.sh/get | bash 67 | echo "$HOME/.rye/shims" >> $GITHUB_PATH 68 | env: 69 | RYE_VERSION: '0.44.0' 70 | RYE_INSTALL_OPTION: '--yes' 71 | 72 | - name: Bootstrap 73 | run: ./scripts/bootstrap 74 | 75 | - name: Run tests 76 | run: ./scripts/test 77 | -------------------------------------------------------------------------------- /.github/workflows/publish-pypi.yml: -------------------------------------------------------------------------------- 1 | # This workflow is triggered when a GitHub release is created. 2 | # It can also be run manually to re-publish to PyPI in case it failed for some reason. 3 | # You can run this workflow by navigating to https://www.github.com/knocklabs/knock-python/actions/workflows/publish-pypi.yml 4 | name: Publish PyPI 5 | on: 6 | workflow_dispatch: 7 | 8 | release: 9 | types: [published] 10 | 11 | jobs: 12 | publish: 13 | name: publish 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v4 18 | 19 | - name: Install Rye 20 | run: | 21 | curl -sSf https://rye.astral.sh/get | bash 22 | echo "$HOME/.rye/shims" >> $GITHUB_PATH 23 | env: 24 | RYE_VERSION: '0.44.0' 25 | RYE_INSTALL_OPTION: '--yes' 26 | 27 | - name: Publish to PyPI 28 | run: | 29 | bash ./bin/publish-pypi 30 | env: 31 | PYPI_TOKEN: ${{ secrets.KNOCK_PYPI_TOKEN || secrets.PYPI_TOKEN }} 32 | -------------------------------------------------------------------------------- /.github/workflows/release-doctor.yml: -------------------------------------------------------------------------------- 1 | name: Release Doctor 2 | on: 3 | pull_request: 4 | branches: 5 | - main 6 | workflow_dispatch: 7 | 8 | jobs: 9 | release_doctor: 10 | name: release doctor 11 | runs-on: ubuntu-latest 12 | if: github.repository == 'knocklabs/knock-python' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'release-please') || github.head_ref == 'next') 13 | 14 | steps: 15 | - uses: actions/checkout@v4 16 | 17 | - name: Check release environment 18 | run: | 19 | bash ./bin/check-release-environment 20 | env: 21 | PYPI_TOKEN: ${{ secrets.KNOCK_PYPI_TOKEN || secrets.PYPI_TOKEN }} 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .prism.log 2 | .vscode 3 | _dev 4 | 5 | __pycache__ 6 | .mypy_cache 7 | 8 | dist 9 | 10 | .venv 11 | .idea 12 | 13 | .env 14 | .envrc 15 | codegen.log 16 | Brewfile.lock.json 17 | -------------------------------------------------------------------------------- /.python-version: -------------------------------------------------------------------------------- 1 | 3.9.18 2 | -------------------------------------------------------------------------------- /.release-please-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | ".": "1.6.0" 3 | } -------------------------------------------------------------------------------- /.stats.yml: -------------------------------------------------------------------------------- 1 | configured_endpoints: 89 2 | openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/knock%2Fknock-e5a7933b414d403d082b34db140fc5b8dca9a5ea3ae322f640b0f9f055c47288.yml 3 | openapi_spec_hash: 3740dc4d5c1f5a0c9ee6de9e40931fd4 4 | config_hash: 2ae8965d371a03bd30c6a56819c04cf2 5 | -------------------------------------------------------------------------------- /Brewfile: -------------------------------------------------------------------------------- 1 | brew "rye" 2 | 3 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Reporting Security Issues 4 | 5 | This SDK is generated by [Stainless Software Inc](http://stainless.com). Stainless takes security seriously, and encourages you to report any security vulnerability promptly so that appropriate action can be taken. 6 | 7 | To report a security issue, please contact the Stainless team at security@stainless.com. 8 | 9 | ## Responsible Disclosure 10 | 11 | We appreciate the efforts of security researchers and individuals who help us maintain the security of 12 | SDKs we generate. If you believe you have found a security vulnerability, please adhere to responsible 13 | disclosure practices by allowing us a reasonable amount of time to investigate and address the issue 14 | before making any information public. 15 | 16 | ## Reporting Non-SDK Related Security Issues 17 | 18 | If you encounter security issues that are not directly related to SDKs but pertain to the services 19 | or products provided by Knock, please follow the respective company's security reporting guidelines. 20 | 21 | ### Knock Terms and Policies 22 | 23 | Please contact security@knock.app for any questions or concerns regarding the security of our services. 24 | 25 | --- 26 | 27 | Thank you for helping us keep the SDKs and systems they interact with secure. 28 | -------------------------------------------------------------------------------- /bin/check-release-environment: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | errors=() 4 | 5 | if [ -z "${PYPI_TOKEN}" ]; then 6 | errors+=("The KNOCK_PYPI_TOKEN secret has not been set. Please set it in either this repository's secrets or your organization secrets.") 7 | fi 8 | 9 | lenErrors=${#errors[@]} 10 | 11 | if [[ lenErrors -gt 0 ]]; then 12 | echo -e "Found the following errors in the release environment:\n" 13 | 14 | for error in "${errors[@]}"; do 15 | echo -e "- $error\n" 16 | done 17 | 18 | exit 1 19 | fi 20 | 21 | echo "The environment is ready to push releases!" 22 | -------------------------------------------------------------------------------- /bin/publish-pypi: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eux 4 | mkdir -p dist 5 | rye build --clean 6 | rye publish --yes --token=$PYPI_TOKEN 7 | -------------------------------------------------------------------------------- /examples/.keep: -------------------------------------------------------------------------------- 1 | File generated from our OpenAPI spec by Stainless. 2 | 3 | This directory can be used to store example files demonstrating usage of this SDK. 4 | It is ignored by Stainless code generation and its content (other than this keep file) won't be touched. -------------------------------------------------------------------------------- /mypy.ini: -------------------------------------------------------------------------------- 1 | [mypy] 2 | pretty = True 3 | show_error_codes = True 4 | 5 | # Exclude _files.py because mypy isn't smart enough to apply 6 | # the correct type narrowing and as this is an internal module 7 | # it's fine to just use Pyright. 8 | # 9 | # We also exclude our `tests` as mypy doesn't always infer 10 | # types correctly and Pyright will still catch any type errors. 11 | exclude = ^(src/knockapi/_files\.py|_dev/.*\.py|tests/.*)$ 12 | 13 | strict_equality = True 14 | implicit_reexport = True 15 | check_untyped_defs = True 16 | no_implicit_optional = True 17 | 18 | warn_return_any = True 19 | warn_unreachable = True 20 | warn_unused_configs = True 21 | 22 | # Turn these options off as it could cause conflicts 23 | # with the Pyright options. 24 | warn_unused_ignores = False 25 | warn_redundant_casts = False 26 | 27 | disallow_any_generics = True 28 | disallow_untyped_defs = True 29 | disallow_untyped_calls = True 30 | disallow_subclassing_any = True 31 | disallow_incomplete_defs = True 32 | disallow_untyped_decorators = True 33 | cache_fine_grained = True 34 | 35 | # By default, mypy reports an error if you assign a value to the result 36 | # of a function call that doesn't return anything. We do this in our test 37 | # cases: 38 | # ``` 39 | # result = ... 40 | # assert result is None 41 | # ``` 42 | # Changing this codegen to make mypy happy would increase complexity 43 | # and would not be worth it. 44 | disable_error_code = func-returns-value,overload-cannot-match 45 | 46 | # https://github.com/python/mypy/issues/12162 47 | [mypy.overrides] 48 | module = "black.files.*" 49 | ignore_errors = true 50 | ignore_missing_imports = true 51 | -------------------------------------------------------------------------------- /noxfile.py: -------------------------------------------------------------------------------- 1 | import nox 2 | 3 | 4 | @nox.session(reuse_venv=True, name="test-pydantic-v1") 5 | def test_pydantic_v1(session: nox.Session) -> None: 6 | session.install("-r", "requirements-dev.lock") 7 | session.install("pydantic<2") 8 | 9 | session.run("pytest", "--showlocals", "--ignore=tests/functional", *session.posargs) 10 | -------------------------------------------------------------------------------- /release-please-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": { 3 | ".": {} 4 | }, 5 | "$schema": "https://raw.githubusercontent.com/stainless-api/release-please/main/schemas/config.json", 6 | "include-v-in-tag": true, 7 | "include-component-in-tag": false, 8 | "versioning": "prerelease", 9 | "prerelease": true, 10 | "bump-minor-pre-major": true, 11 | "bump-patch-for-minor-pre-major": false, 12 | "pull-request-header": "Automated Release PR", 13 | "pull-request-title-pattern": "release: ${version}", 14 | "changelog-sections": [ 15 | { 16 | "type": "feat", 17 | "section": "Features" 18 | }, 19 | { 20 | "type": "fix", 21 | "section": "Bug Fixes" 22 | }, 23 | { 24 | "type": "perf", 25 | "section": "Performance Improvements" 26 | }, 27 | { 28 | "type": "revert", 29 | "section": "Reverts" 30 | }, 31 | { 32 | "type": "chore", 33 | "section": "Chores" 34 | }, 35 | { 36 | "type": "docs", 37 | "section": "Documentation" 38 | }, 39 | { 40 | "type": "style", 41 | "section": "Styles" 42 | }, 43 | { 44 | "type": "refactor", 45 | "section": "Refactors" 46 | }, 47 | { 48 | "type": "test", 49 | "section": "Tests", 50 | "hidden": true 51 | }, 52 | { 53 | "type": "build", 54 | "section": "Build System" 55 | }, 56 | { 57 | "type": "ci", 58 | "section": "Continuous Integration", 59 | "hidden": true 60 | } 61 | ], 62 | "release-type": "python", 63 | "extra-files": [ 64 | "src/knockapi/_version.py" 65 | ] 66 | } -------------------------------------------------------------------------------- /requirements-dev.lock: -------------------------------------------------------------------------------- 1 | # generated by rye 2 | # use `rye lock` or `rye sync` to update this lockfile 3 | # 4 | # last locked with the following flags: 5 | # pre: false 6 | # features: [] 7 | # all-features: true 8 | # with-sources: false 9 | # generate-hashes: false 10 | # universal: false 11 | 12 | -e file:. 13 | annotated-types==0.6.0 14 | # via pydantic 15 | anyio==4.4.0 16 | # via httpx 17 | # via knockapi 18 | argcomplete==3.1.2 19 | # via nox 20 | certifi==2023.7.22 21 | # via httpcore 22 | # via httpx 23 | colorlog==6.7.0 24 | # via nox 25 | dirty-equals==0.6.0 26 | distlib==0.3.7 27 | # via virtualenv 28 | distro==1.8.0 29 | # via knockapi 30 | exceptiongroup==1.2.2 31 | # via anyio 32 | # via pytest 33 | filelock==3.12.4 34 | # via virtualenv 35 | h11==0.14.0 36 | # via httpcore 37 | httpcore==1.0.2 38 | # via httpx 39 | httpx==0.28.1 40 | # via knockapi 41 | # via respx 42 | idna==3.4 43 | # via anyio 44 | # via httpx 45 | importlib-metadata==7.0.0 46 | iniconfig==2.0.0 47 | # via pytest 48 | markdown-it-py==3.0.0 49 | # via rich 50 | mdurl==0.1.2 51 | # via markdown-it-py 52 | mypy==1.14.1 53 | mypy-extensions==1.0.0 54 | # via mypy 55 | nest-asyncio==1.6.0 56 | nodeenv==1.8.0 57 | # via pyright 58 | nox==2023.4.22 59 | packaging==23.2 60 | # via nox 61 | # via pytest 62 | platformdirs==3.11.0 63 | # via virtualenv 64 | pluggy==1.5.0 65 | # via pytest 66 | pydantic==2.10.3 67 | # via knockapi 68 | pydantic-core==2.27.1 69 | # via pydantic 70 | pygments==2.18.0 71 | # via rich 72 | pyright==1.1.399 73 | pytest==8.3.3 74 | # via pytest-asyncio 75 | pytest-asyncio==0.24.0 76 | python-dateutil==2.8.2 77 | # via time-machine 78 | pytz==2023.3.post1 79 | # via dirty-equals 80 | respx==0.22.0 81 | rich==13.7.1 82 | ruff==0.9.4 83 | setuptools==68.2.2 84 | # via nodeenv 85 | six==1.16.0 86 | # via python-dateutil 87 | sniffio==1.3.0 88 | # via anyio 89 | # via knockapi 90 | time-machine==2.9.0 91 | tomli==2.0.2 92 | # via mypy 93 | # via pytest 94 | typing-extensions==4.12.2 95 | # via anyio 96 | # via knockapi 97 | # via mypy 98 | # via pydantic 99 | # via pydantic-core 100 | # via pyright 101 | virtualenv==20.24.5 102 | # via nox 103 | zipp==3.17.0 104 | # via importlib-metadata 105 | -------------------------------------------------------------------------------- /requirements.lock: -------------------------------------------------------------------------------- 1 | # generated by rye 2 | # use `rye lock` or `rye sync` to update this lockfile 3 | # 4 | # last locked with the following flags: 5 | # pre: false 6 | # features: [] 7 | # all-features: true 8 | # with-sources: false 9 | # generate-hashes: false 10 | # universal: false 11 | 12 | -e file:. 13 | annotated-types==0.6.0 14 | # via pydantic 15 | anyio==4.4.0 16 | # via httpx 17 | # via knockapi 18 | certifi==2023.7.22 19 | # via httpcore 20 | # via httpx 21 | distro==1.8.0 22 | # via knockapi 23 | exceptiongroup==1.2.2 24 | # via anyio 25 | h11==0.14.0 26 | # via httpcore 27 | httpcore==1.0.2 28 | # via httpx 29 | httpx==0.28.1 30 | # via knockapi 31 | idna==3.4 32 | # via anyio 33 | # via httpx 34 | pydantic==2.10.3 35 | # via knockapi 36 | pydantic-core==2.27.1 37 | # via pydantic 38 | sniffio==1.3.0 39 | # via anyio 40 | # via knockapi 41 | typing-extensions==4.12.2 42 | # via anyio 43 | # via knockapi 44 | # via pydantic 45 | # via pydantic-core 46 | -------------------------------------------------------------------------------- /scripts/bootstrap: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | cd "$(dirname "$0")/.." 6 | 7 | if ! command -v rye >/dev/null 2>&1 && [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ]; then 8 | brew bundle check >/dev/null 2>&1 || { 9 | echo "==> Installing Homebrew dependencies…" 10 | brew bundle 11 | } 12 | fi 13 | 14 | echo "==> Installing Python dependencies…" 15 | 16 | # experimental uv support makes installations significantly faster 17 | rye config --set-bool behavior.use-uv=true 18 | 19 | rye sync --all-features 20 | -------------------------------------------------------------------------------- /scripts/format: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | cd "$(dirname "$0")/.." 6 | 7 | echo "==> Running formatters" 8 | rye run format 9 | -------------------------------------------------------------------------------- /scripts/lint: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | cd "$(dirname "$0")/.." 6 | 7 | echo "==> Running lints" 8 | rye run lint 9 | 10 | echo "==> Making sure it imports" 11 | rye run python -c 'import knockapi' 12 | -------------------------------------------------------------------------------- /scripts/mock: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | cd "$(dirname "$0")/.." 6 | 7 | if [[ -n "$1" && "$1" != '--'* ]]; then 8 | URL="$1" 9 | shift 10 | else 11 | URL="$(grep 'openapi_spec_url' .stats.yml | cut -d' ' -f2)" 12 | fi 13 | 14 | # Check if the URL is empty 15 | if [ -z "$URL" ]; then 16 | echo "Error: No OpenAPI spec path/url provided or found in .stats.yml" 17 | exit 1 18 | fi 19 | 20 | echo "==> Starting mock server with URL ${URL}" 21 | 22 | # Run prism mock on the given spec 23 | if [ "$1" == "--daemon" ]; then 24 | npm exec --package=@stainless-api/prism-cli@5.8.5 -- prism mock "$URL" &> .prism.log & 25 | 26 | # Wait for server to come online 27 | echo -n "Waiting for server" 28 | while ! grep -q "✖ fatal\|Prism is listening" ".prism.log" ; do 29 | echo -n "." 30 | sleep 0.1 31 | done 32 | 33 | if grep -q "✖ fatal" ".prism.log"; then 34 | cat .prism.log 35 | exit 1 36 | fi 37 | 38 | echo 39 | else 40 | npm exec --package=@stainless-api/prism-cli@5.8.5 -- prism mock "$URL" 41 | fi 42 | -------------------------------------------------------------------------------- /scripts/test: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | cd "$(dirname "$0")/.." 6 | 7 | RED='\033[0;31m' 8 | GREEN='\033[0;32m' 9 | YELLOW='\033[0;33m' 10 | NC='\033[0m' # No Color 11 | 12 | function prism_is_running() { 13 | curl --silent "http://localhost:4010" >/dev/null 2>&1 14 | } 15 | 16 | kill_server_on_port() { 17 | pids=$(lsof -t -i tcp:"$1" || echo "") 18 | if [ "$pids" != "" ]; then 19 | kill "$pids" 20 | echo "Stopped $pids." 21 | fi 22 | } 23 | 24 | function is_overriding_api_base_url() { 25 | [ -n "$TEST_API_BASE_URL" ] 26 | } 27 | 28 | if ! is_overriding_api_base_url && ! prism_is_running ; then 29 | # When we exit this script, make sure to kill the background mock server process 30 | trap 'kill_server_on_port 4010' EXIT 31 | 32 | # Start the dev server 33 | ./scripts/mock --daemon 34 | fi 35 | 36 | if is_overriding_api_base_url ; then 37 | echo -e "${GREEN}✔ Running tests against ${TEST_API_BASE_URL}${NC}" 38 | echo 39 | elif ! prism_is_running ; then 40 | echo -e "${RED}ERROR:${NC} The test suite will not run without a mock Prism server" 41 | echo -e "running against your OpenAPI spec." 42 | echo 43 | echo -e "To run the server, pass in the path or url of your OpenAPI" 44 | echo -e "spec to the prism command:" 45 | echo 46 | echo -e " \$ ${YELLOW}npm exec --package=@stoplight/prism-cli@~5.3.2 -- prism mock path/to/your.openapi.yml${NC}" 47 | echo 48 | 49 | exit 1 50 | else 51 | echo -e "${GREEN}✔ Mock prism server is running with your OpenAPI spec${NC}" 52 | echo 53 | fi 54 | 55 | export DEFER_PYDANTIC_BUILD=false 56 | 57 | echo "==> Running tests" 58 | rye run pytest "$@" 59 | 60 | echo "==> Running Pydantic v1 tests" 61 | rye run nox -s test-pydantic-v1 -- "$@" 62 | -------------------------------------------------------------------------------- /scripts/utils/upload-artifact.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -exuo pipefail 3 | 4 | RESPONSE=$(curl -X POST "$URL" \ 5 | -H "Authorization: Bearer $AUTH" \ 6 | -H "Content-Type: application/json") 7 | 8 | SIGNED_URL=$(echo "$RESPONSE" | jq -r '.url') 9 | 10 | if [[ "$SIGNED_URL" == "null" ]]; then 11 | echo -e "\033[31mFailed to get signed URL.\033[0m" 12 | exit 1 13 | fi 14 | 15 | UPLOAD_RESPONSE=$(tar -cz . | curl -v -X PUT \ 16 | -H "Content-Type: application/gzip" \ 17 | --data-binary @- "$SIGNED_URL" 2>&1) 18 | 19 | if echo "$UPLOAD_RESPONSE" | grep -q "HTTP/[0-9.]* 200"; then 20 | echo -e "\033[32mUploaded build to Stainless storage.\033[0m" 21 | echo -e "\033[32mInstallation: pip install 'https://pkg.stainless.com/s/knock-python/$SHA'\033[0m" 22 | else 23 | echo -e "\033[31mFailed to upload artifact.\033[0m" 24 | exit 1 25 | fi 26 | -------------------------------------------------------------------------------- /src/knock/lib/.keep: -------------------------------------------------------------------------------- 1 | File generated from our OpenAPI spec by Stainless. 2 | 3 | This directory can be used to store custom files to expand the SDK. 4 | It is ignored by Stainless code generation and its content (other than this keep file) won't be touched. -------------------------------------------------------------------------------- /src/knockapi/__init__.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | import typing as _t 4 | 5 | from . import types 6 | from ._types import NOT_GIVEN, Omit, NoneType, NotGiven, Transport, ProxiesTypes 7 | from ._utils import file_from_path 8 | from ._client import Knock, Client, Stream, Timeout, Transport, AsyncKnock, AsyncClient, AsyncStream, RequestOptions 9 | from ._models import BaseModel 10 | from ._version import __title__, __version__ 11 | from ._response import APIResponse as APIResponse, AsyncAPIResponse as AsyncAPIResponse 12 | from ._constants import DEFAULT_TIMEOUT, DEFAULT_MAX_RETRIES, DEFAULT_CONNECTION_LIMITS 13 | from ._exceptions import ( 14 | APIError, 15 | KnockError, 16 | ConflictError, 17 | NotFoundError, 18 | APIStatusError, 19 | RateLimitError, 20 | APITimeoutError, 21 | BadRequestError, 22 | APIConnectionError, 23 | AuthenticationError, 24 | InternalServerError, 25 | PermissionDeniedError, 26 | UnprocessableEntityError, 27 | APIResponseValidationError, 28 | ) 29 | from ._base_client import DefaultHttpxClient, DefaultAsyncHttpxClient 30 | from ._utils._logs import setup_logging as _setup_logging 31 | 32 | __all__ = [ 33 | "types", 34 | "__version__", 35 | "__title__", 36 | "NoneType", 37 | "Transport", 38 | "ProxiesTypes", 39 | "NotGiven", 40 | "NOT_GIVEN", 41 | "Omit", 42 | "KnockError", 43 | "APIError", 44 | "APIStatusError", 45 | "APITimeoutError", 46 | "APIConnectionError", 47 | "APIResponseValidationError", 48 | "BadRequestError", 49 | "AuthenticationError", 50 | "PermissionDeniedError", 51 | "NotFoundError", 52 | "ConflictError", 53 | "UnprocessableEntityError", 54 | "RateLimitError", 55 | "InternalServerError", 56 | "Timeout", 57 | "RequestOptions", 58 | "Client", 59 | "AsyncClient", 60 | "Stream", 61 | "AsyncStream", 62 | "Knock", 63 | "AsyncKnock", 64 | "file_from_path", 65 | "BaseModel", 66 | "DEFAULT_TIMEOUT", 67 | "DEFAULT_MAX_RETRIES", 68 | "DEFAULT_CONNECTION_LIMITS", 69 | "DefaultHttpxClient", 70 | "DefaultAsyncHttpxClient", 71 | ] 72 | 73 | if not _t.TYPE_CHECKING: 74 | from ._utils._resources_proxy import resources as resources 75 | 76 | _setup_logging() 77 | 78 | # Update the __module__ attribute for exported symbols so that 79 | # error messages point to this module instead of the module 80 | # it was originally defined in, e.g. 81 | # knockapi._exceptions.NotFoundError -> knockapi.NotFoundError 82 | __locals = locals() 83 | for __name in __all__: 84 | if not __name.startswith("__"): 85 | try: 86 | __locals[__name].__module__ = "knockapi" 87 | except (TypeError, AttributeError): 88 | # Some of our exported symbols are builtins which we can't set attributes for. 89 | pass 90 | -------------------------------------------------------------------------------- /src/knockapi/_constants.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | import httpx 4 | 5 | RAW_RESPONSE_HEADER = "X-Stainless-Raw-Response" 6 | OVERRIDE_CAST_TO_HEADER = "____stainless_override_cast_to" 7 | 8 | # default timeout is 1 minute 9 | DEFAULT_TIMEOUT = httpx.Timeout(timeout=60, connect=5.0) 10 | DEFAULT_MAX_RETRIES = 2 11 | DEFAULT_CONNECTION_LIMITS = httpx.Limits(max_connections=100, max_keepalive_connections=20) 12 | 13 | INITIAL_RETRY_DELAY = 0.5 14 | MAX_RETRY_DELAY = 8.0 15 | -------------------------------------------------------------------------------- /src/knockapi/_resource.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | import time 6 | from typing import TYPE_CHECKING 7 | 8 | import anyio 9 | 10 | if TYPE_CHECKING: 11 | from ._client import Knock, AsyncKnock 12 | 13 | 14 | class SyncAPIResource: 15 | _client: Knock 16 | 17 | def __init__(self, client: Knock) -> None: 18 | self._client = client 19 | self._get = client.get 20 | self._post = client.post 21 | self._patch = client.patch 22 | self._put = client.put 23 | self._delete = client.delete 24 | self._get_api_list = client.get_api_list 25 | 26 | def _sleep(self, seconds: float) -> None: 27 | time.sleep(seconds) 28 | 29 | 30 | class AsyncAPIResource: 31 | _client: AsyncKnock 32 | 33 | def __init__(self, client: AsyncKnock) -> None: 34 | self._client = client 35 | self._get = client.get 36 | self._post = client.post 37 | self._patch = client.patch 38 | self._put = client.put 39 | self._delete = client.delete 40 | self._get_api_list = client.get_api_list 41 | 42 | async def _sleep(self, seconds: float) -> None: 43 | await anyio.sleep(seconds) 44 | -------------------------------------------------------------------------------- /src/knockapi/_utils/__init__.py: -------------------------------------------------------------------------------- 1 | from ._sync import asyncify as asyncify 2 | from ._proxy import LazyProxy as LazyProxy 3 | from ._utils import ( 4 | flatten as flatten, 5 | is_dict as is_dict, 6 | is_list as is_list, 7 | is_given as is_given, 8 | is_tuple as is_tuple, 9 | json_safe as json_safe, 10 | lru_cache as lru_cache, 11 | is_mapping as is_mapping, 12 | is_tuple_t as is_tuple_t, 13 | parse_date as parse_date, 14 | is_iterable as is_iterable, 15 | is_sequence as is_sequence, 16 | coerce_float as coerce_float, 17 | is_mapping_t as is_mapping_t, 18 | removeprefix as removeprefix, 19 | removesuffix as removesuffix, 20 | extract_files as extract_files, 21 | is_sequence_t as is_sequence_t, 22 | required_args as required_args, 23 | coerce_boolean as coerce_boolean, 24 | coerce_integer as coerce_integer, 25 | file_from_path as file_from_path, 26 | parse_datetime as parse_datetime, 27 | strip_not_given as strip_not_given, 28 | deepcopy_minimal as deepcopy_minimal, 29 | get_async_library as get_async_library, 30 | maybe_coerce_float as maybe_coerce_float, 31 | get_required_header as get_required_header, 32 | maybe_coerce_boolean as maybe_coerce_boolean, 33 | maybe_coerce_integer as maybe_coerce_integer, 34 | ) 35 | from ._typing import ( 36 | is_list_type as is_list_type, 37 | is_union_type as is_union_type, 38 | extract_type_arg as extract_type_arg, 39 | is_iterable_type as is_iterable_type, 40 | is_required_type as is_required_type, 41 | is_annotated_type as is_annotated_type, 42 | is_type_alias_type as is_type_alias_type, 43 | strip_annotated_type as strip_annotated_type, 44 | extract_type_var_from_base as extract_type_var_from_base, 45 | ) 46 | from ._streams import consume_sync_iterator as consume_sync_iterator, consume_async_iterator as consume_async_iterator 47 | from ._transform import ( 48 | PropertyInfo as PropertyInfo, 49 | transform as transform, 50 | async_transform as async_transform, 51 | maybe_transform as maybe_transform, 52 | async_maybe_transform as async_maybe_transform, 53 | ) 54 | from ._reflection import ( 55 | function_has_argument as function_has_argument, 56 | assert_signatures_in_sync as assert_signatures_in_sync, 57 | ) 58 | -------------------------------------------------------------------------------- /src/knockapi/_utils/_logs.py: -------------------------------------------------------------------------------- 1 | import os 2 | import logging 3 | 4 | logger: logging.Logger = logging.getLogger("knockapi") 5 | httpx_logger: logging.Logger = logging.getLogger("httpx") 6 | 7 | 8 | def _basic_config() -> None: 9 | # e.g. [2023-10-05 14:12:26 - knockapi._base_client:818 - DEBUG] HTTP Request: POST http://127.0.0.1:4010/foo/bar "200 OK" 10 | logging.basicConfig( 11 | format="[%(asctime)s - %(name)s:%(lineno)d - %(levelname)s] %(message)s", 12 | datefmt="%Y-%m-%d %H:%M:%S", 13 | ) 14 | 15 | 16 | def setup_logging() -> None: 17 | env = os.environ.get("KNOCK_LOG") 18 | if env == "debug": 19 | _basic_config() 20 | logger.setLevel(logging.DEBUG) 21 | httpx_logger.setLevel(logging.DEBUG) 22 | elif env == "info": 23 | _basic_config() 24 | logger.setLevel(logging.INFO) 25 | httpx_logger.setLevel(logging.INFO) 26 | -------------------------------------------------------------------------------- /src/knockapi/_utils/_proxy.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from abc import ABC, abstractmethod 4 | from typing import Generic, TypeVar, Iterable, cast 5 | from typing_extensions import override 6 | 7 | T = TypeVar("T") 8 | 9 | 10 | class LazyProxy(Generic[T], ABC): 11 | """Implements data methods to pretend that an instance is another instance. 12 | 13 | This includes forwarding attribute access and other methods. 14 | """ 15 | 16 | # Note: we have to special case proxies that themselves return proxies 17 | # to support using a proxy as a catch-all for any random access, e.g. `proxy.foo.bar.baz` 18 | 19 | def __getattr__(self, attr: str) -> object: 20 | proxied = self.__get_proxied__() 21 | if isinstance(proxied, LazyProxy): 22 | return proxied # pyright: ignore 23 | return getattr(proxied, attr) 24 | 25 | @override 26 | def __repr__(self) -> str: 27 | proxied = self.__get_proxied__() 28 | if isinstance(proxied, LazyProxy): 29 | return proxied.__class__.__name__ 30 | return repr(self.__get_proxied__()) 31 | 32 | @override 33 | def __str__(self) -> str: 34 | proxied = self.__get_proxied__() 35 | if isinstance(proxied, LazyProxy): 36 | return proxied.__class__.__name__ 37 | return str(proxied) 38 | 39 | @override 40 | def __dir__(self) -> Iterable[str]: 41 | proxied = self.__get_proxied__() 42 | if isinstance(proxied, LazyProxy): 43 | return [] 44 | return proxied.__dir__() 45 | 46 | @property # type: ignore 47 | @override 48 | def __class__(self) -> type: # pyright: ignore 49 | try: 50 | proxied = self.__get_proxied__() 51 | except Exception: 52 | return type(self) 53 | if issubclass(type(proxied), LazyProxy): 54 | return type(proxied) 55 | return proxied.__class__ 56 | 57 | def __get_proxied__(self) -> T: 58 | return self.__load__() 59 | 60 | def __as_proxied__(self) -> T: 61 | """Helper method that returns the current proxy, typed as the loaded object""" 62 | return cast(T, self) 63 | 64 | @abstractmethod 65 | def __load__(self) -> T: ... 66 | -------------------------------------------------------------------------------- /src/knockapi/_utils/_reflection.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import inspect 4 | from typing import Any, Callable 5 | 6 | 7 | def function_has_argument(func: Callable[..., Any], arg_name: str) -> bool: 8 | """Returns whether or not the given function has a specific parameter""" 9 | sig = inspect.signature(func) 10 | return arg_name in sig.parameters 11 | 12 | 13 | def assert_signatures_in_sync( 14 | source_func: Callable[..., Any], 15 | check_func: Callable[..., Any], 16 | *, 17 | exclude_params: set[str] = set(), 18 | ) -> None: 19 | """Ensure that the signature of the second function matches the first.""" 20 | 21 | check_sig = inspect.signature(check_func) 22 | source_sig = inspect.signature(source_func) 23 | 24 | errors: list[str] = [] 25 | 26 | for name, source_param in source_sig.parameters.items(): 27 | if name in exclude_params: 28 | continue 29 | 30 | custom_param = check_sig.parameters.get(name) 31 | if not custom_param: 32 | errors.append(f"the `{name}` param is missing") 33 | continue 34 | 35 | if custom_param.annotation != source_param.annotation: 36 | errors.append( 37 | f"types for the `{name}` param are do not match; source={repr(source_param.annotation)} checking={repr(custom_param.annotation)}" 38 | ) 39 | continue 40 | 41 | if errors: 42 | raise AssertionError(f"{len(errors)} errors encountered when comparing signatures:\n\n" + "\n\n".join(errors)) 43 | -------------------------------------------------------------------------------- /src/knockapi/_utils/_resources_proxy.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import Any 4 | from typing_extensions import override 5 | 6 | from ._proxy import LazyProxy 7 | 8 | 9 | class ResourcesProxy(LazyProxy[Any]): 10 | """A proxy for the `knockapi.resources` module. 11 | 12 | This is used so that we can lazily import `knockapi.resources` only when 13 | needed *and* so that users can just import `knockapi` and reference `knockapi.resources` 14 | """ 15 | 16 | @override 17 | def __load__(self) -> Any: 18 | import importlib 19 | 20 | mod = importlib.import_module("knockapi.resources") 21 | return mod 22 | 23 | 24 | resources = ResourcesProxy().__as_proxied__() 25 | -------------------------------------------------------------------------------- /src/knockapi/_utils/_streams.py: -------------------------------------------------------------------------------- 1 | from typing import Any 2 | from typing_extensions import Iterator, AsyncIterator 3 | 4 | 5 | def consume_sync_iterator(iterator: Iterator[Any]) -> None: 6 | for _ in iterator: 7 | ... 8 | 9 | 10 | async def consume_async_iterator(iterator: AsyncIterator[Any]) -> None: 11 | async for _ in iterator: 12 | ... 13 | -------------------------------------------------------------------------------- /src/knockapi/_version.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | __title__ = "knockapi" 4 | __version__ = "1.6.0" # x-release-please-version 5 | -------------------------------------------------------------------------------- /src/knockapi/lib/.keep: -------------------------------------------------------------------------------- 1 | File generated from our OpenAPI spec by Stainless. 2 | 3 | This directory can be used to store custom files to expand the SDK. 4 | It is ignored by Stainless code generation and its content (other than this keep file) won't be touched. -------------------------------------------------------------------------------- /src/knockapi/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knocklabs/knock-python/248fa874915e543427ed44b899bf9151de726400/src/knockapi/py.typed -------------------------------------------------------------------------------- /src/knockapi/resources/channels/__init__.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from .bulk import ( 4 | BulkResource, 5 | AsyncBulkResource, 6 | BulkResourceWithRawResponse, 7 | AsyncBulkResourceWithRawResponse, 8 | BulkResourceWithStreamingResponse, 9 | AsyncBulkResourceWithStreamingResponse, 10 | ) 11 | from .channels import ( 12 | ChannelsResource, 13 | AsyncChannelsResource, 14 | ChannelsResourceWithRawResponse, 15 | AsyncChannelsResourceWithRawResponse, 16 | ChannelsResourceWithStreamingResponse, 17 | AsyncChannelsResourceWithStreamingResponse, 18 | ) 19 | 20 | __all__ = [ 21 | "BulkResource", 22 | "AsyncBulkResource", 23 | "BulkResourceWithRawResponse", 24 | "AsyncBulkResourceWithRawResponse", 25 | "BulkResourceWithStreamingResponse", 26 | "AsyncBulkResourceWithStreamingResponse", 27 | "ChannelsResource", 28 | "AsyncChannelsResource", 29 | "ChannelsResourceWithRawResponse", 30 | "AsyncChannelsResourceWithRawResponse", 31 | "ChannelsResourceWithStreamingResponse", 32 | "AsyncChannelsResourceWithStreamingResponse", 33 | ] 34 | -------------------------------------------------------------------------------- /src/knockapi/resources/integrations/__init__.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from .census import ( 4 | CensusResource, 5 | AsyncCensusResource, 6 | CensusResourceWithRawResponse, 7 | AsyncCensusResourceWithRawResponse, 8 | CensusResourceWithStreamingResponse, 9 | AsyncCensusResourceWithStreamingResponse, 10 | ) 11 | from .hightouch import ( 12 | HightouchResource, 13 | AsyncHightouchResource, 14 | HightouchResourceWithRawResponse, 15 | AsyncHightouchResourceWithRawResponse, 16 | HightouchResourceWithStreamingResponse, 17 | AsyncHightouchResourceWithStreamingResponse, 18 | ) 19 | from .integrations import ( 20 | IntegrationsResource, 21 | AsyncIntegrationsResource, 22 | IntegrationsResourceWithRawResponse, 23 | AsyncIntegrationsResourceWithRawResponse, 24 | IntegrationsResourceWithStreamingResponse, 25 | AsyncIntegrationsResourceWithStreamingResponse, 26 | ) 27 | 28 | __all__ = [ 29 | "CensusResource", 30 | "AsyncCensusResource", 31 | "CensusResourceWithRawResponse", 32 | "AsyncCensusResourceWithRawResponse", 33 | "CensusResourceWithStreamingResponse", 34 | "AsyncCensusResourceWithStreamingResponse", 35 | "HightouchResource", 36 | "AsyncHightouchResource", 37 | "HightouchResourceWithRawResponse", 38 | "AsyncHightouchResourceWithRawResponse", 39 | "HightouchResourceWithStreamingResponse", 40 | "AsyncHightouchResourceWithStreamingResponse", 41 | "IntegrationsResource", 42 | "AsyncIntegrationsResource", 43 | "IntegrationsResourceWithRawResponse", 44 | "AsyncIntegrationsResourceWithRawResponse", 45 | "IntegrationsResourceWithStreamingResponse", 46 | "AsyncIntegrationsResourceWithStreamingResponse", 47 | ] 48 | -------------------------------------------------------------------------------- /src/knockapi/resources/messages/__init__.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from .batch import ( 4 | BatchResource, 5 | AsyncBatchResource, 6 | BatchResourceWithRawResponse, 7 | AsyncBatchResourceWithRawResponse, 8 | BatchResourceWithStreamingResponse, 9 | AsyncBatchResourceWithStreamingResponse, 10 | ) 11 | from .messages import ( 12 | MessagesResource, 13 | AsyncMessagesResource, 14 | MessagesResourceWithRawResponse, 15 | AsyncMessagesResourceWithRawResponse, 16 | MessagesResourceWithStreamingResponse, 17 | AsyncMessagesResourceWithStreamingResponse, 18 | ) 19 | 20 | __all__ = [ 21 | "BatchResource", 22 | "AsyncBatchResource", 23 | "BatchResourceWithRawResponse", 24 | "AsyncBatchResourceWithRawResponse", 25 | "BatchResourceWithStreamingResponse", 26 | "AsyncBatchResourceWithStreamingResponse", 27 | "MessagesResource", 28 | "AsyncMessagesResource", 29 | "MessagesResourceWithRawResponse", 30 | "AsyncMessagesResourceWithRawResponse", 31 | "MessagesResourceWithStreamingResponse", 32 | "AsyncMessagesResourceWithStreamingResponse", 33 | ] 34 | -------------------------------------------------------------------------------- /src/knockapi/resources/objects/__init__.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from .bulk import ( 4 | BulkResource, 5 | AsyncBulkResource, 6 | BulkResourceWithRawResponse, 7 | AsyncBulkResourceWithRawResponse, 8 | BulkResourceWithStreamingResponse, 9 | AsyncBulkResourceWithStreamingResponse, 10 | ) 11 | from .objects import ( 12 | ObjectsResource, 13 | AsyncObjectsResource, 14 | ObjectsResourceWithRawResponse, 15 | AsyncObjectsResourceWithRawResponse, 16 | ObjectsResourceWithStreamingResponse, 17 | AsyncObjectsResourceWithStreamingResponse, 18 | ) 19 | 20 | __all__ = [ 21 | "BulkResource", 22 | "AsyncBulkResource", 23 | "BulkResourceWithRawResponse", 24 | "AsyncBulkResourceWithRawResponse", 25 | "BulkResourceWithStreamingResponse", 26 | "AsyncBulkResourceWithStreamingResponse", 27 | "ObjectsResource", 28 | "AsyncObjectsResource", 29 | "ObjectsResourceWithRawResponse", 30 | "AsyncObjectsResourceWithRawResponse", 31 | "ObjectsResourceWithStreamingResponse", 32 | "AsyncObjectsResourceWithStreamingResponse", 33 | ] 34 | -------------------------------------------------------------------------------- /src/knockapi/resources/providers/__init__.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from .slack import ( 4 | SlackResource, 5 | AsyncSlackResource, 6 | SlackResourceWithRawResponse, 7 | AsyncSlackResourceWithRawResponse, 8 | SlackResourceWithStreamingResponse, 9 | AsyncSlackResourceWithStreamingResponse, 10 | ) 11 | from .ms_teams import ( 12 | MsTeamsResource, 13 | AsyncMsTeamsResource, 14 | MsTeamsResourceWithRawResponse, 15 | AsyncMsTeamsResourceWithRawResponse, 16 | MsTeamsResourceWithStreamingResponse, 17 | AsyncMsTeamsResourceWithStreamingResponse, 18 | ) 19 | from .providers import ( 20 | ProvidersResource, 21 | AsyncProvidersResource, 22 | ProvidersResourceWithRawResponse, 23 | AsyncProvidersResourceWithRawResponse, 24 | ProvidersResourceWithStreamingResponse, 25 | AsyncProvidersResourceWithStreamingResponse, 26 | ) 27 | 28 | __all__ = [ 29 | "SlackResource", 30 | "AsyncSlackResource", 31 | "SlackResourceWithRawResponse", 32 | "AsyncSlackResourceWithRawResponse", 33 | "SlackResourceWithStreamingResponse", 34 | "AsyncSlackResourceWithStreamingResponse", 35 | "MsTeamsResource", 36 | "AsyncMsTeamsResource", 37 | "MsTeamsResourceWithRawResponse", 38 | "AsyncMsTeamsResourceWithRawResponse", 39 | "MsTeamsResourceWithStreamingResponse", 40 | "AsyncMsTeamsResourceWithStreamingResponse", 41 | "ProvidersResource", 42 | "AsyncProvidersResource", 43 | "ProvidersResourceWithRawResponse", 44 | "AsyncProvidersResourceWithRawResponse", 45 | "ProvidersResourceWithStreamingResponse", 46 | "AsyncProvidersResourceWithStreamingResponse", 47 | ] 48 | -------------------------------------------------------------------------------- /src/knockapi/resources/schedules/__init__.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from .bulk import ( 4 | BulkResource, 5 | AsyncBulkResource, 6 | BulkResourceWithRawResponse, 7 | AsyncBulkResourceWithRawResponse, 8 | BulkResourceWithStreamingResponse, 9 | AsyncBulkResourceWithStreamingResponse, 10 | ) 11 | from .schedules import ( 12 | SchedulesResource, 13 | AsyncSchedulesResource, 14 | SchedulesResourceWithRawResponse, 15 | AsyncSchedulesResourceWithRawResponse, 16 | SchedulesResourceWithStreamingResponse, 17 | AsyncSchedulesResourceWithStreamingResponse, 18 | ) 19 | 20 | __all__ = [ 21 | "BulkResource", 22 | "AsyncBulkResource", 23 | "BulkResourceWithRawResponse", 24 | "AsyncBulkResourceWithRawResponse", 25 | "BulkResourceWithStreamingResponse", 26 | "AsyncBulkResourceWithStreamingResponse", 27 | "SchedulesResource", 28 | "AsyncSchedulesResource", 29 | "SchedulesResourceWithRawResponse", 30 | "AsyncSchedulesResourceWithRawResponse", 31 | "SchedulesResourceWithStreamingResponse", 32 | "AsyncSchedulesResourceWithStreamingResponse", 33 | ] 34 | -------------------------------------------------------------------------------- /src/knockapi/resources/tenants/__init__.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from .bulk import ( 4 | BulkResource, 5 | AsyncBulkResource, 6 | BulkResourceWithRawResponse, 7 | AsyncBulkResourceWithRawResponse, 8 | BulkResourceWithStreamingResponse, 9 | AsyncBulkResourceWithStreamingResponse, 10 | ) 11 | from .tenants import ( 12 | TenantsResource, 13 | AsyncTenantsResource, 14 | TenantsResourceWithRawResponse, 15 | AsyncTenantsResourceWithRawResponse, 16 | TenantsResourceWithStreamingResponse, 17 | AsyncTenantsResourceWithStreamingResponse, 18 | ) 19 | 20 | __all__ = [ 21 | "BulkResource", 22 | "AsyncBulkResource", 23 | "BulkResourceWithRawResponse", 24 | "AsyncBulkResourceWithRawResponse", 25 | "BulkResourceWithStreamingResponse", 26 | "AsyncBulkResourceWithStreamingResponse", 27 | "TenantsResource", 28 | "AsyncTenantsResource", 29 | "TenantsResourceWithRawResponse", 30 | "AsyncTenantsResourceWithRawResponse", 31 | "TenantsResourceWithStreamingResponse", 32 | "AsyncTenantsResourceWithStreamingResponse", 33 | ] 34 | -------------------------------------------------------------------------------- /src/knockapi/resources/users/__init__.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from .bulk import ( 4 | BulkResource, 5 | AsyncBulkResource, 6 | BulkResourceWithRawResponse, 7 | AsyncBulkResourceWithRawResponse, 8 | BulkResourceWithStreamingResponse, 9 | AsyncBulkResourceWithStreamingResponse, 10 | ) 11 | from .feeds import ( 12 | FeedsResource, 13 | AsyncFeedsResource, 14 | FeedsResourceWithRawResponse, 15 | AsyncFeedsResourceWithRawResponse, 16 | FeedsResourceWithStreamingResponse, 17 | AsyncFeedsResourceWithStreamingResponse, 18 | ) 19 | from .users import ( 20 | UsersResource, 21 | AsyncUsersResource, 22 | UsersResourceWithRawResponse, 23 | AsyncUsersResourceWithRawResponse, 24 | UsersResourceWithStreamingResponse, 25 | AsyncUsersResourceWithStreamingResponse, 26 | ) 27 | from .guides import ( 28 | GuidesResource, 29 | AsyncGuidesResource, 30 | GuidesResourceWithRawResponse, 31 | AsyncGuidesResourceWithRawResponse, 32 | GuidesResourceWithStreamingResponse, 33 | AsyncGuidesResourceWithStreamingResponse, 34 | ) 35 | 36 | __all__ = [ 37 | "FeedsResource", 38 | "AsyncFeedsResource", 39 | "FeedsResourceWithRawResponse", 40 | "AsyncFeedsResourceWithRawResponse", 41 | "FeedsResourceWithStreamingResponse", 42 | "AsyncFeedsResourceWithStreamingResponse", 43 | "GuidesResource", 44 | "AsyncGuidesResource", 45 | "GuidesResourceWithRawResponse", 46 | "AsyncGuidesResourceWithRawResponse", 47 | "GuidesResourceWithStreamingResponse", 48 | "AsyncGuidesResourceWithStreamingResponse", 49 | "BulkResource", 50 | "AsyncBulkResource", 51 | "BulkResourceWithRawResponse", 52 | "AsyncBulkResourceWithRawResponse", 53 | "BulkResourceWithStreamingResponse", 54 | "AsyncBulkResourceWithStreamingResponse", 55 | "UsersResource", 56 | "AsyncUsersResource", 57 | "UsersResourceWithRawResponse", 58 | "AsyncUsersResourceWithRawResponse", 59 | "UsersResourceWithStreamingResponse", 60 | "AsyncUsersResourceWithStreamingResponse", 61 | ] 62 | -------------------------------------------------------------------------------- /src/knockapi/types/activity.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import Dict, Optional 4 | from datetime import datetime 5 | 6 | from pydantic import Field as FieldInfo 7 | 8 | from .._models import BaseModel 9 | from .recipient import Recipient 10 | 11 | __all__ = ["Activity"] 12 | 13 | 14 | class Activity(BaseModel): 15 | id: Optional[str] = None 16 | """Unique identifier for the activity.""" 17 | 18 | api_typename: Optional[str] = FieldInfo(alias="__typename", default=None) 19 | """The typename of the schema.""" 20 | 21 | actor: Optional[Recipient] = None 22 | """A recipient of a notification, which is either a user or an object.""" 23 | 24 | data: Optional[Dict[str, object]] = None 25 | """The workflow trigger `data` payload associated with the activity.""" 26 | 27 | inserted_at: Optional[datetime] = None 28 | """Timestamp when the activity was created.""" 29 | 30 | recipient: Optional[Recipient] = None 31 | """A recipient of a notification, which is either a user or an object.""" 32 | 33 | updated_at: Optional[datetime] = None 34 | """Timestamp when the activity was last updated.""" 35 | -------------------------------------------------------------------------------- /src/knockapi/types/audience_add_members_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Iterable, Optional 6 | from typing_extensions import Required, TypedDict 7 | 8 | __all__ = ["AudienceAddMembersParams", "Member", "MemberUser"] 9 | 10 | 11 | class AudienceAddMembersParams(TypedDict, total=False): 12 | members: Required[Iterable[Member]] 13 | """A list of audience members to add.""" 14 | 15 | 16 | class MemberUser(TypedDict, total=False): 17 | id: str 18 | """The ID for the user that you set when identifying them in Knock.""" 19 | 20 | 21 | class Member(TypedDict, total=False): 22 | user: Required[MemberUser] 23 | """An object containing the user's ID.""" 24 | 25 | tenant: Optional[str] 26 | """The unique identifier for the tenant.""" 27 | -------------------------------------------------------------------------------- /src/knockapi/types/audience_add_members_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing_extensions import TypeAlias 4 | 5 | __all__ = ["AudienceAddMembersResponse"] 6 | 7 | AudienceAddMembersResponse: TypeAlias = str 8 | -------------------------------------------------------------------------------- /src/knockapi/types/audience_list_members_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import List 4 | 5 | from .._models import BaseModel 6 | from .page_info import PageInfo 7 | from .audience_member import AudienceMember 8 | 9 | __all__ = ["AudienceListMembersResponse"] 10 | 11 | 12 | class AudienceListMembersResponse(BaseModel): 13 | entries: List[AudienceMember] 14 | """A list of audience members.""" 15 | 16 | page_info: PageInfo 17 | """Pagination information for a list of resources.""" 18 | -------------------------------------------------------------------------------- /src/knockapi/types/audience_member.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import Optional 4 | from datetime import datetime 5 | 6 | from pydantic import Field as FieldInfo 7 | 8 | from .user import User 9 | from .._models import BaseModel 10 | 11 | __all__ = ["AudienceMember"] 12 | 13 | 14 | class AudienceMember(BaseModel): 15 | api_typename: str = FieldInfo(alias="__typename") 16 | """The typename of the schema.""" 17 | 18 | added_at: datetime 19 | """Timestamp when the resource was created.""" 20 | 21 | user: User 22 | """ 23 | A [User](/concepts/users) represents an individual in your system who can 24 | receive notifications through Knock. Users are the most common recipients of 25 | notifications and are always referenced by your internal identifier. 26 | """ 27 | 28 | user_id: str 29 | """The ID for the user that you set when identifying them in Knock.""" 30 | 31 | tenant: Optional[str] = None 32 | """The unique identifier for the tenant.""" 33 | -------------------------------------------------------------------------------- /src/knockapi/types/audience_remove_members_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Iterable, Optional 6 | from typing_extensions import Required, TypedDict 7 | 8 | __all__ = ["AudienceRemoveMembersParams", "Member", "MemberUser"] 9 | 10 | 11 | class AudienceRemoveMembersParams(TypedDict, total=False): 12 | members: Required[Iterable[Member]] 13 | """A list of audience members to remove.""" 14 | 15 | 16 | class MemberUser(TypedDict, total=False): 17 | id: str 18 | """The ID for the user that you set when identifying them in Knock.""" 19 | 20 | 21 | class Member(TypedDict, total=False): 22 | user: Required[MemberUser] 23 | """An object containing the user's ID.""" 24 | 25 | tenant: Optional[str] 26 | """The unique identifier for the tenant.""" 27 | -------------------------------------------------------------------------------- /src/knockapi/types/audience_remove_members_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing_extensions import TypeAlias 4 | 5 | __all__ = ["AudienceRemoveMembersResponse"] 6 | 7 | AudienceRemoveMembersResponse: TypeAlias = str 8 | -------------------------------------------------------------------------------- /src/knockapi/types/bulk_operation.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import List, Optional 4 | from datetime import datetime 5 | from typing_extensions import Literal 6 | 7 | from pydantic import Field as FieldInfo 8 | 9 | from .._models import BaseModel 10 | 11 | __all__ = ["BulkOperation", "ErrorItem"] 12 | 13 | 14 | class ErrorItem(BaseModel): 15 | id: str 16 | """Unique identifier for the object.""" 17 | 18 | collection: Optional[str] = None 19 | """The collection this object belongs to.""" 20 | 21 | 22 | class BulkOperation(BaseModel): 23 | id: str 24 | """Unique identifier for the bulk operation.""" 25 | 26 | api_typename: str = FieldInfo(alias="__typename") 27 | """The typename of the schema.""" 28 | 29 | estimated_total_rows: int 30 | """The estimated total number of rows to process.""" 31 | 32 | inserted_at: datetime 33 | """Timestamp when the resource was created.""" 34 | 35 | name: str 36 | """The name of the bulk operation.""" 37 | 38 | processed_rows: int 39 | """The number of rows processed so far.""" 40 | 41 | status: Literal["queued", "processing", "completed", "failed"] 42 | """The status of the bulk operation.""" 43 | 44 | success_count: int 45 | """The number of successful operations.""" 46 | 47 | updated_at: datetime 48 | """The timestamp when the resource was last updated.""" 49 | 50 | completed_at: Optional[datetime] = None 51 | """Timestamp when the bulk operation was completed.""" 52 | 53 | error_count: Optional[int] = None 54 | """The number of failed operations.""" 55 | 56 | error_items: Optional[List[ErrorItem]] = None 57 | """A list of items that failed to be processed.""" 58 | 59 | failed_at: Optional[datetime] = None 60 | """Timestamp when the bulk operation failed.""" 61 | 62 | progress_path: Optional[str] = None 63 | """The URI to the bulk operation's progress.""" 64 | 65 | started_at: Optional[datetime] = None 66 | """Timestamp when the bulk operation was started.""" 67 | -------------------------------------------------------------------------------- /src/knockapi/types/channels/__init__.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from .bulk_update_message_status_params import BulkUpdateMessageStatusParams as BulkUpdateMessageStatusParams 6 | -------------------------------------------------------------------------------- /src/knockapi/types/channels/bulk_update_message_status_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import List, Union 6 | from datetime import datetime 7 | from typing_extensions import Literal, Annotated, TypedDict 8 | 9 | from ..._utils import PropertyInfo 10 | 11 | __all__ = ["BulkUpdateMessageStatusParams"] 12 | 13 | 14 | class BulkUpdateMessageStatusParams(TypedDict, total=False): 15 | archived: Literal["exclude", "include", "only"] 16 | """Limits the results to messages with the given archived status.""" 17 | 18 | delivery_status: Literal["queued", "sent", "delivered", "delivery_attempted", "undelivered", "not_sent", "bounced"] 19 | """Limits the results to messages with the given delivery status.""" 20 | 21 | engagement_status: Literal[ 22 | "seen", "unseen", "read", "unread", "archived", "unarchived", "link_clicked", "interacted" 23 | ] 24 | """Limits the results to messages with the given engagement status.""" 25 | 26 | has_tenant: bool 27 | """Limits the results to messages that have a tenant or not.""" 28 | 29 | newer_than: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] 30 | """Limits the results to messages inserted after the given date.""" 31 | 32 | older_than: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] 33 | """Limits the results to messages inserted before the given date.""" 34 | 35 | recipient_ids: List[str] 36 | """Limits the results to messages with the given recipient IDs.""" 37 | 38 | tenants: List[str] 39 | """Limits the results to messages with the given tenant IDs.""" 40 | 41 | trigger_data: str 42 | """Limits the results to only messages that were generated with the given data. 43 | 44 | See [trigger data filtering](/api-reference/overview/trigger-data-filtering) for 45 | more information. 46 | """ 47 | 48 | workflows: List[str] 49 | """Limits the results to messages with the given workflow keys.""" 50 | -------------------------------------------------------------------------------- /src/knockapi/types/condition.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import Optional 4 | from typing_extensions import Literal 5 | 6 | from .._models import BaseModel 7 | 8 | __all__ = ["Condition"] 9 | 10 | 11 | class Condition(BaseModel): 12 | argument: Optional[str] = None 13 | """The argument value to compare against in the condition.""" 14 | 15 | operator: Literal[ 16 | "equal_to", 17 | "not_equal_to", 18 | "greater_than", 19 | "less_than", 20 | "greater_than_or_equal_to", 21 | "less_than_or_equal_to", 22 | "contains", 23 | "not_contains", 24 | "empty", 25 | "not_empty", 26 | "contains_all", 27 | "is_timestamp", 28 | "is_not_timestamp", 29 | "is_timestamp_after", 30 | "is_timestamp_before", 31 | "is_timestamp_between", 32 | "is_audience_member", 33 | "is_not_audience_member", 34 | ] 35 | """The operator to use in the condition evaluation.""" 36 | 37 | variable: str 38 | """The variable to be evaluated in the condition.""" 39 | -------------------------------------------------------------------------------- /src/knockapi/types/condition_param.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Optional 6 | from typing_extensions import Literal, Required, TypedDict 7 | 8 | __all__ = ["ConditionParam"] 9 | 10 | 11 | class ConditionParam(TypedDict, total=False): 12 | argument: Required[Optional[str]] 13 | """The argument value to compare against in the condition.""" 14 | 15 | operator: Required[ 16 | Literal[ 17 | "equal_to", 18 | "not_equal_to", 19 | "greater_than", 20 | "less_than", 21 | "greater_than_or_equal_to", 22 | "less_than_or_equal_to", 23 | "contains", 24 | "not_contains", 25 | "empty", 26 | "not_empty", 27 | "contains_all", 28 | "is_timestamp", 29 | "is_not_timestamp", 30 | "is_timestamp_after", 31 | "is_timestamp_before", 32 | "is_timestamp_between", 33 | "is_audience_member", 34 | "is_not_audience_member", 35 | ] 36 | ] 37 | """The operator to use in the condition evaluation.""" 38 | 39 | variable: Required[str] 40 | """The variable to be evaluated in the condition.""" 41 | -------------------------------------------------------------------------------- /src/knockapi/types/inline_identify_user_request_param.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Dict, Union, Optional 6 | from datetime import datetime 7 | from typing_extensions import Required, Annotated, TypeAlias, TypedDict 8 | 9 | from .._utils import PropertyInfo 10 | from .recipients.inline_channel_data_request_param import InlineChannelDataRequestParam 11 | from .recipients.inline_preference_set_request_param import InlinePreferenceSetRequestParam 12 | 13 | __all__ = ["InlineIdentifyUserRequestParam"] 14 | 15 | 16 | class InlineIdentifyUserRequestParamTyped(TypedDict, total=False): 17 | id: Required[str] 18 | """The ID for the user that you set when identifying them in Knock.""" 19 | 20 | avatar: Optional[str] 21 | """URL to the user's avatar image.""" 22 | 23 | channel_data: Optional[InlineChannelDataRequestParam] 24 | """A request to set channel data for a type of channel inline.""" 25 | 26 | created_at: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")] 27 | """The creation date of the user from your system.""" 28 | 29 | email: Optional[str] 30 | """The primary email address for the user.""" 31 | 32 | locale: Optional[str] 33 | """The locale of the user. 34 | 35 | Used for [message localization](/concepts/translations). 36 | """ 37 | 38 | name: Optional[str] 39 | """Display name of the user.""" 40 | 41 | phone_number: Optional[str] 42 | """ 43 | The [E.164](https://www.twilio.com/docs/glossary/what-e164) phone number of the 44 | user (required for SMS channels). 45 | """ 46 | 47 | preferences: Optional[InlinePreferenceSetRequestParam] 48 | """Inline set preferences for a recipient, where the key is the preference set id.""" 49 | 50 | timezone: Optional[str] 51 | """The timezone of the user. 52 | 53 | Must be a 54 | valid [tz database time zone string](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). 55 | Used 56 | for [recurring schedules](/concepts/schedules#scheduling-workflows-with-recurring-schedules-for-recipients). 57 | """ 58 | 59 | 60 | InlineIdentifyUserRequestParam: TypeAlias = Union[InlineIdentifyUserRequestParamTyped, Dict[str, object]] 61 | -------------------------------------------------------------------------------- /src/knockapi/types/inline_object_request_param.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Dict, Union, Optional 6 | from datetime import datetime 7 | from typing_extensions import Required, Annotated, TypeAlias, TypedDict 8 | 9 | from .._utils import PropertyInfo 10 | from .recipients.inline_channel_data_request_param import InlineChannelDataRequestParam 11 | from .recipients.inline_preference_set_request_param import InlinePreferenceSetRequestParam 12 | 13 | __all__ = ["InlineObjectRequestParam"] 14 | 15 | 16 | class InlineObjectRequestParamTyped(TypedDict, total=False): 17 | id: Required[str] 18 | """Unique identifier for the object.""" 19 | 20 | collection: Required[str] 21 | """The collection this object belongs to.""" 22 | 23 | channel_data: Optional[InlineChannelDataRequestParam] 24 | """A request to set channel data for a type of channel inline.""" 25 | 26 | created_at: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")] 27 | """Timestamp when the resource was created.""" 28 | 29 | preferences: Optional[InlinePreferenceSetRequestParam] 30 | """Inline set preferences for a recipient, where the key is the preference set id.""" 31 | 32 | 33 | InlineObjectRequestParam: TypeAlias = Union[InlineObjectRequestParamTyped, Dict[str, object]] 34 | -------------------------------------------------------------------------------- /src/knockapi/types/inline_tenant_request_param.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Union 6 | from typing_extensions import TypeAlias 7 | 8 | from .tenant_request_param import TenantRequestParam 9 | 10 | __all__ = ["InlineTenantRequestParam"] 11 | 12 | InlineTenantRequestParam: TypeAlias = Union[str, TenantRequestParam] 13 | -------------------------------------------------------------------------------- /src/knockapi/types/integrations/__init__.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from .census_custom_destination_params import CensusCustomDestinationParams as CensusCustomDestinationParams 6 | from .census_custom_destination_response import CensusCustomDestinationResponse as CensusCustomDestinationResponse 7 | from .hightouch_embedded_destination_params import ( 8 | HightouchEmbeddedDestinationParams as HightouchEmbeddedDestinationParams, 9 | ) 10 | from .hightouch_embedded_destination_response import ( 11 | HightouchEmbeddedDestinationResponse as HightouchEmbeddedDestinationResponse, 12 | ) 13 | -------------------------------------------------------------------------------- /src/knockapi/types/integrations/census_custom_destination_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Dict 6 | from typing_extensions import Required, TypedDict 7 | 8 | __all__ = ["CensusCustomDestinationParams"] 9 | 10 | 11 | class CensusCustomDestinationParams(TypedDict, total=False): 12 | id: Required[str] 13 | """The unique identifier for the RPC request.""" 14 | 15 | jsonrpc: Required[str] 16 | """The JSON-RPC version.""" 17 | 18 | method: Required[str] 19 | """The method name to execute.""" 20 | 21 | params: Dict[str, object] 22 | """The parameters for the method.""" 23 | -------------------------------------------------------------------------------- /src/knockapi/types/integrations/census_custom_destination_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import Dict, Optional 4 | 5 | from ..._models import BaseModel 6 | 7 | __all__ = ["CensusCustomDestinationResponse"] 8 | 9 | 10 | class CensusCustomDestinationResponse(BaseModel): 11 | id: Optional[str] = None 12 | """The request ID.""" 13 | 14 | result: Optional[Dict[str, object]] = None 15 | """The result of the RPC call.""" 16 | -------------------------------------------------------------------------------- /src/knockapi/types/integrations/hightouch_embedded_destination_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Dict 6 | from typing_extensions import Required, TypedDict 7 | 8 | __all__ = ["HightouchEmbeddedDestinationParams"] 9 | 10 | 11 | class HightouchEmbeddedDestinationParams(TypedDict, total=False): 12 | id: Required[str] 13 | """The unique identifier for the RPC request.""" 14 | 15 | jsonrpc: Required[str] 16 | """The JSON-RPC version.""" 17 | 18 | method: Required[str] 19 | """The method name to execute.""" 20 | 21 | params: Dict[str, object] 22 | """The parameters for the method.""" 23 | -------------------------------------------------------------------------------- /src/knockapi/types/integrations/hightouch_embedded_destination_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import Dict, Optional 4 | 5 | from ..._models import BaseModel 6 | 7 | __all__ = ["HightouchEmbeddedDestinationResponse"] 8 | 9 | 10 | class HightouchEmbeddedDestinationResponse(BaseModel): 11 | id: Optional[str] = None 12 | """The request ID.""" 13 | 14 | result: Optional[Dict[str, object]] = None 15 | """The result of the RPC call.""" 16 | -------------------------------------------------------------------------------- /src/knockapi/types/message_delivery_log.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import Dict, Union, Optional 4 | from typing_extensions import Literal 5 | 6 | from pydantic import Field as FieldInfo 7 | 8 | from .._models import BaseModel 9 | 10 | __all__ = ["MessageDeliveryLog", "Request", "Response"] 11 | 12 | 13 | class Request(BaseModel): 14 | body: Union[str, Dict[str, object], None] = None 15 | """The body content that was sent with the request.""" 16 | 17 | headers: Optional[Dict[str, object]] = None 18 | """The headers that were sent with the request.""" 19 | 20 | host: Optional[str] = None 21 | """The host to which the request was sent.""" 22 | 23 | method: Optional[Literal["GET", "POST", "PUT", "DELETE", "PATCH"]] = None 24 | """The HTTP method used for the request.""" 25 | 26 | path: Optional[str] = None 27 | """The path of the URL that was requested.""" 28 | 29 | query: Optional[str] = None 30 | """The query string of the URL that was requested.""" 31 | 32 | 33 | class Response(BaseModel): 34 | body: Union[str, Dict[str, object], None] = None 35 | """The body content that was received with the response.""" 36 | 37 | headers: Optional[Dict[str, object]] = None 38 | """The headers that were received with the response.""" 39 | 40 | status: Optional[int] = None 41 | """The HTTP status code of the response.""" 42 | 43 | 44 | class MessageDeliveryLog(BaseModel): 45 | id: str 46 | """The unique identifier for the message delivery log.""" 47 | 48 | api_typename: str = FieldInfo(alias="__typename") 49 | """The typename of the schema.""" 50 | 51 | environment_id: str 52 | """The ID of the environment in which the message delivery occurred.""" 53 | 54 | inserted_at: str 55 | """Timestamp when the message delivery log was created.""" 56 | 57 | request: Request 58 | """A message delivery log request.""" 59 | 60 | response: Response 61 | """A message delivery log response.""" 62 | 63 | service_name: str 64 | """The name of the service that processed the delivery.""" 65 | -------------------------------------------------------------------------------- /src/knockapi/types/message_event.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import Dict, Optional 4 | from datetime import datetime 5 | from typing_extensions import Literal 6 | 7 | from pydantic import Field as FieldInfo 8 | 9 | from .._models import BaseModel 10 | from .recipient_reference import RecipientReference 11 | 12 | __all__ = ["MessageEvent"] 13 | 14 | 15 | class MessageEvent(BaseModel): 16 | id: str 17 | """The unique identifier for the message event.""" 18 | 19 | api_typename: str = FieldInfo(alias="__typename") 20 | """The typename of the schema.""" 21 | 22 | inserted_at: datetime 23 | """Timestamp when the event was created.""" 24 | 25 | recipient: RecipientReference 26 | """ 27 | A reference to a recipient, either a user identifier (string) or an object 28 | reference (ID, collection). 29 | """ 30 | 31 | type: Literal[ 32 | "message.archived", 33 | "message.bounced", 34 | "message.delivered", 35 | "message.delivery_attempted", 36 | "message.interacted", 37 | "message.link_clicked", 38 | "message.not_sent", 39 | "message.queued", 40 | "message.read", 41 | "message.seen", 42 | "message.sent", 43 | "message.unarchived", 44 | "message.undelivered", 45 | "message.unread", 46 | "message.unseen", 47 | ] 48 | """The type of event that occurred.""" 49 | 50 | data: Optional[Dict[str, object]] = None 51 | """The data associated with the message event. Only present for some event types.""" 52 | -------------------------------------------------------------------------------- /src/knockapi/types/message_list_activities_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing_extensions import TypedDict 6 | 7 | __all__ = ["MessageListActivitiesParams"] 8 | 9 | 10 | class MessageListActivitiesParams(TypedDict, total=False): 11 | after: str 12 | """The cursor to fetch entries after.""" 13 | 14 | before: str 15 | """The cursor to fetch entries before.""" 16 | 17 | page_size: int 18 | """The number of items per page.""" 19 | 20 | trigger_data: str 21 | """The trigger data to filter activities by.""" 22 | -------------------------------------------------------------------------------- /src/knockapi/types/message_list_delivery_logs_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing_extensions import TypedDict 6 | 7 | __all__ = ["MessageListDeliveryLogsParams"] 8 | 9 | 10 | class MessageListDeliveryLogsParams(TypedDict, total=False): 11 | after: str 12 | """The cursor to fetch entries after.""" 13 | 14 | before: str 15 | """The cursor to fetch entries before.""" 16 | 17 | page_size: int 18 | """The number of items per page.""" 19 | -------------------------------------------------------------------------------- /src/knockapi/types/message_list_events_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing_extensions import TypedDict 6 | 7 | __all__ = ["MessageListEventsParams"] 8 | 9 | 10 | class MessageListEventsParams(TypedDict, total=False): 11 | after: str 12 | """The cursor to fetch entries after.""" 13 | 14 | before: str 15 | """The cursor to fetch entries before.""" 16 | 17 | page_size: int 18 | """The number of items per page.""" 19 | -------------------------------------------------------------------------------- /src/knockapi/types/message_list_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import List 6 | from typing_extensions import Literal, TypedDict 7 | 8 | __all__ = ["MessageListParams", "InsertedAt"] 9 | 10 | 11 | class MessageListParams(TypedDict, total=False): 12 | after: str 13 | """The cursor to fetch entries after.""" 14 | 15 | before: str 16 | """The cursor to fetch entries before.""" 17 | 18 | channel_id: str 19 | """Limits the results to items with the corresponding channel ID.""" 20 | 21 | engagement_status: List[ 22 | Literal["seen", "unseen", "read", "unread", "archived", "unarchived", "link_clicked", "interacted"] 23 | ] 24 | """Limits the results to messages with the given engagement status.""" 25 | 26 | inserted_at: InsertedAt 27 | 28 | message_ids: List[str] 29 | """Limits the results to only the message IDs given (max 50). 30 | 31 | Note: when using this option, the results will be subject to any other filters 32 | applied to the query. 33 | """ 34 | 35 | page_size: int 36 | """The number of items per page.""" 37 | 38 | source: str 39 | """Limits the results to messages triggered by the given workflow key.""" 40 | 41 | status: List[Literal["queued", "sent", "delivered", "delivery_attempted", "undelivered", "not_sent", "bounced"]] 42 | """Limits the results to messages with the given delivery status.""" 43 | 44 | tenant: str 45 | """Limits the results to items with the corresponding tenant.""" 46 | 47 | trigger_data: str 48 | """Limits the results to only messages that were generated with the given data. 49 | 50 | See [trigger data filtering](/api-reference/overview/trigger-data-filtering) for 51 | more information. 52 | """ 53 | 54 | workflow_categories: List[str] 55 | """Limits the results to messages related to any of the provided categories.""" 56 | 57 | workflow_recipient_run_id: str 58 | """Limits the results to messages for a specific recipient's workflow run.""" 59 | 60 | workflow_run_id: str 61 | """ 62 | Limits the results to messages associated with the top-level workflow run ID 63 | returned by the workflow trigger request. 64 | """ 65 | 66 | 67 | class InsertedAt(TypedDict, total=False): 68 | gt: str 69 | """Limits the results to messages inserted after the given date.""" 70 | 71 | gte: str 72 | """Limits the results to messages inserted after or on the given date.""" 73 | 74 | lt: str 75 | """Limits the results to messages inserted before the given date.""" 76 | 77 | lte: str 78 | """Limits the results to messages inserted before or on the given date.""" 79 | -------------------------------------------------------------------------------- /src/knockapi/types/message_mark_as_interacted_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Dict 6 | from typing_extensions import TypedDict 7 | 8 | __all__ = ["MessageMarkAsInteractedParams"] 9 | 10 | 11 | class MessageMarkAsInteractedParams(TypedDict, total=False): 12 | metadata: Dict[str, object] 13 | """Metadata about the interaction.""" 14 | -------------------------------------------------------------------------------- /src/knockapi/types/messages/__init__.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from .batch_archive_params import BatchArchiveParams as BatchArchiveParams 6 | from .batch_archive_response import BatchArchiveResponse as BatchArchiveResponse 7 | from .batch_unarchive_params import BatchUnarchiveParams as BatchUnarchiveParams 8 | from .batch_get_content_params import BatchGetContentParams as BatchGetContentParams 9 | from .batch_unarchive_response import BatchUnarchiveResponse as BatchUnarchiveResponse 10 | from .batch_mark_as_read_params import BatchMarkAsReadParams as BatchMarkAsReadParams 11 | from .batch_mark_as_seen_params import BatchMarkAsSeenParams as BatchMarkAsSeenParams 12 | from .batch_get_content_response import BatchGetContentResponse as BatchGetContentResponse 13 | from .batch_mark_as_read_response import BatchMarkAsReadResponse as BatchMarkAsReadResponse 14 | from .batch_mark_as_seen_response import BatchMarkAsSeenResponse as BatchMarkAsSeenResponse 15 | from .batch_mark_as_unread_params import BatchMarkAsUnreadParams as BatchMarkAsUnreadParams 16 | from .batch_mark_as_unseen_params import BatchMarkAsUnseenParams as BatchMarkAsUnseenParams 17 | from .batch_mark_as_unread_response import BatchMarkAsUnreadResponse as BatchMarkAsUnreadResponse 18 | from .batch_mark_as_unseen_response import BatchMarkAsUnseenResponse as BatchMarkAsUnseenResponse 19 | from .batch_mark_as_interacted_params import BatchMarkAsInteractedParams as BatchMarkAsInteractedParams 20 | from .batch_mark_as_interacted_response import BatchMarkAsInteractedResponse as BatchMarkAsInteractedResponse 21 | -------------------------------------------------------------------------------- /src/knockapi/types/messages/batch_archive_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import List 6 | from typing_extensions import Required, TypedDict 7 | 8 | __all__ = ["BatchArchiveParams"] 9 | 10 | 11 | class BatchArchiveParams(TypedDict, total=False): 12 | message_ids: Required[List[str]] 13 | """The message IDs to update the status of.""" 14 | -------------------------------------------------------------------------------- /src/knockapi/types/messages/batch_archive_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import List 4 | from typing_extensions import TypeAlias 5 | 6 | from ..message import Message 7 | 8 | __all__ = ["BatchArchiveResponse"] 9 | 10 | BatchArchiveResponse: TypeAlias = List[Message] 11 | -------------------------------------------------------------------------------- /src/knockapi/types/messages/batch_get_content_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import List 6 | from typing_extensions import Required, TypedDict 7 | 8 | __all__ = ["BatchGetContentParams"] 9 | 10 | 11 | class BatchGetContentParams(TypedDict, total=False): 12 | message_ids: Required[List[str]] 13 | """The IDs of the messages to fetch contents of.""" 14 | -------------------------------------------------------------------------------- /src/knockapi/types/messages/batch_mark_as_interacted_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Dict, List, Optional 6 | from typing_extensions import Required, TypedDict 7 | 8 | __all__ = ["BatchMarkAsInteractedParams"] 9 | 10 | 11 | class BatchMarkAsInteractedParams(TypedDict, total=False): 12 | message_ids: Required[List[str]] 13 | """The message IDs to batch mark as interacted with.""" 14 | 15 | metadata: Optional[Dict[str, object]] 16 | """Metadata about the interaction.""" 17 | -------------------------------------------------------------------------------- /src/knockapi/types/messages/batch_mark_as_interacted_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import List 4 | from typing_extensions import TypeAlias 5 | 6 | from ..message import Message 7 | 8 | __all__ = ["BatchMarkAsInteractedResponse"] 9 | 10 | BatchMarkAsInteractedResponse: TypeAlias = List[Message] 11 | -------------------------------------------------------------------------------- /src/knockapi/types/messages/batch_mark_as_read_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import List 6 | from typing_extensions import Required, TypedDict 7 | 8 | __all__ = ["BatchMarkAsReadParams"] 9 | 10 | 11 | class BatchMarkAsReadParams(TypedDict, total=False): 12 | message_ids: Required[List[str]] 13 | """The message IDs to update the status of.""" 14 | -------------------------------------------------------------------------------- /src/knockapi/types/messages/batch_mark_as_read_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import List 4 | from typing_extensions import TypeAlias 5 | 6 | from ..message import Message 7 | 8 | __all__ = ["BatchMarkAsReadResponse"] 9 | 10 | BatchMarkAsReadResponse: TypeAlias = List[Message] 11 | -------------------------------------------------------------------------------- /src/knockapi/types/messages/batch_mark_as_seen_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import List 6 | from typing_extensions import Required, TypedDict 7 | 8 | __all__ = ["BatchMarkAsSeenParams"] 9 | 10 | 11 | class BatchMarkAsSeenParams(TypedDict, total=False): 12 | message_ids: Required[List[str]] 13 | """The message IDs to update the status of.""" 14 | -------------------------------------------------------------------------------- /src/knockapi/types/messages/batch_mark_as_seen_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import List 4 | from typing_extensions import TypeAlias 5 | 6 | from ..message import Message 7 | 8 | __all__ = ["BatchMarkAsSeenResponse"] 9 | 10 | BatchMarkAsSeenResponse: TypeAlias = List[Message] 11 | -------------------------------------------------------------------------------- /src/knockapi/types/messages/batch_mark_as_unread_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import List 6 | from typing_extensions import Required, TypedDict 7 | 8 | __all__ = ["BatchMarkAsUnreadParams"] 9 | 10 | 11 | class BatchMarkAsUnreadParams(TypedDict, total=False): 12 | message_ids: Required[List[str]] 13 | """The message IDs to update the status of.""" 14 | -------------------------------------------------------------------------------- /src/knockapi/types/messages/batch_mark_as_unread_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import List 4 | from typing_extensions import TypeAlias 5 | 6 | from ..message import Message 7 | 8 | __all__ = ["BatchMarkAsUnreadResponse"] 9 | 10 | BatchMarkAsUnreadResponse: TypeAlias = List[Message] 11 | -------------------------------------------------------------------------------- /src/knockapi/types/messages/batch_mark_as_unseen_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import List 6 | from typing_extensions import Required, TypedDict 7 | 8 | __all__ = ["BatchMarkAsUnseenParams"] 9 | 10 | 11 | class BatchMarkAsUnseenParams(TypedDict, total=False): 12 | message_ids: Required[List[str]] 13 | """The message IDs to update the status of.""" 14 | -------------------------------------------------------------------------------- /src/knockapi/types/messages/batch_mark_as_unseen_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import List 4 | from typing_extensions import TypeAlias 5 | 6 | from ..message import Message 7 | 8 | __all__ = ["BatchMarkAsUnseenResponse"] 9 | 10 | BatchMarkAsUnseenResponse: TypeAlias = List[Message] 11 | -------------------------------------------------------------------------------- /src/knockapi/types/messages/batch_unarchive_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import List 6 | from typing_extensions import Required, TypedDict 7 | 8 | __all__ = ["BatchUnarchiveParams"] 9 | 10 | 11 | class BatchUnarchiveParams(TypedDict, total=False): 12 | message_ids: Required[List[str]] 13 | """The message IDs to update the status of.""" 14 | -------------------------------------------------------------------------------- /src/knockapi/types/messages/batch_unarchive_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import List 4 | from typing_extensions import TypeAlias 5 | 6 | from ..message import Message 7 | 8 | __all__ = ["BatchUnarchiveResponse"] 9 | 10 | BatchUnarchiveResponse: TypeAlias = List[Message] 11 | -------------------------------------------------------------------------------- /src/knockapi/types/object.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import Dict, Optional 4 | from datetime import datetime 5 | 6 | from pydantic import Field as FieldInfo 7 | 8 | from .._models import BaseModel 9 | 10 | __all__ = ["Object"] 11 | 12 | 13 | class Object(BaseModel): 14 | id: str 15 | """Unique identifier for the object.""" 16 | 17 | api_typename: str = FieldInfo(alias="__typename") 18 | """The typename of the schema.""" 19 | 20 | collection: str 21 | """The collection this object belongs to.""" 22 | 23 | updated_at: datetime 24 | """The timestamp when the resource was last updated.""" 25 | 26 | created_at: Optional[datetime] = None 27 | """Timestamp when the resource was created.""" 28 | 29 | properties: Optional[Dict[str, object]] = None 30 | """The custom properties associated with the object.""" 31 | -------------------------------------------------------------------------------- /src/knockapi/types/object_add_subscriptions_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Dict, List, Optional 6 | from typing_extensions import Required, TypedDict 7 | 8 | from .recipient_request_param import RecipientRequestParam 9 | 10 | __all__ = ["ObjectAddSubscriptionsParams"] 11 | 12 | 13 | class ObjectAddSubscriptionsParams(TypedDict, total=False): 14 | recipients: Required[List[RecipientRequestParam]] 15 | """The recipients of the subscription. 16 | 17 | You can subscribe up to 100 recipients to an object at a time. 18 | """ 19 | 20 | properties: Optional[Dict[str, object]] 21 | """The custom properties associated with the subscription relationship.""" 22 | -------------------------------------------------------------------------------- /src/knockapi/types/object_add_subscriptions_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import List 4 | from typing_extensions import TypeAlias 5 | 6 | from .recipients.subscription import Subscription 7 | 8 | __all__ = ["ObjectAddSubscriptionsResponse"] 9 | 10 | ObjectAddSubscriptionsResponse: TypeAlias = List[Subscription] 11 | -------------------------------------------------------------------------------- /src/knockapi/types/object_delete_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing_extensions import TypeAlias 4 | 5 | __all__ = ["ObjectDeleteResponse"] 6 | 7 | ObjectDeleteResponse: TypeAlias = str 8 | -------------------------------------------------------------------------------- /src/knockapi/types/object_delete_subscriptions_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import List 6 | from typing_extensions import Required, TypedDict 7 | 8 | from .recipient_reference_param import RecipientReferenceParam 9 | 10 | __all__ = ["ObjectDeleteSubscriptionsParams"] 11 | 12 | 13 | class ObjectDeleteSubscriptionsParams(TypedDict, total=False): 14 | recipients: Required[List[RecipientReferenceParam]] 15 | """The recipients of the subscription. 16 | 17 | You can subscribe up to 100 recipients to an object at a time. 18 | """ 19 | -------------------------------------------------------------------------------- /src/knockapi/types/object_delete_subscriptions_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import List 4 | from typing_extensions import TypeAlias 5 | 6 | from .recipients.subscription import Subscription 7 | 8 | __all__ = ["ObjectDeleteSubscriptionsResponse"] 9 | 10 | ObjectDeleteSubscriptionsResponse: TypeAlias = List[Subscription] 11 | -------------------------------------------------------------------------------- /src/knockapi/types/object_list_messages_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import List 6 | from typing_extensions import Literal, TypedDict 7 | 8 | __all__ = ["ObjectListMessagesParams", "InsertedAt"] 9 | 10 | 11 | class ObjectListMessagesParams(TypedDict, total=False): 12 | after: str 13 | """The cursor to fetch entries after.""" 14 | 15 | before: str 16 | """The cursor to fetch entries before.""" 17 | 18 | channel_id: str 19 | """Limits the results to items with the corresponding channel ID.""" 20 | 21 | engagement_status: List[ 22 | Literal["seen", "unseen", "read", "unread", "archived", "unarchived", "link_clicked", "interacted"] 23 | ] 24 | """Limits the results to messages with the given engagement status.""" 25 | 26 | inserted_at: InsertedAt 27 | 28 | message_ids: List[str] 29 | """Limits the results to only the message IDs given (max 50). 30 | 31 | Note: when using this option, the results will be subject to any other filters 32 | applied to the query. 33 | """ 34 | 35 | page_size: int 36 | """The number of items per page.""" 37 | 38 | source: str 39 | """Limits the results to messages triggered by the given workflow key.""" 40 | 41 | status: List[Literal["queued", "sent", "delivered", "delivery_attempted", "undelivered", "not_sent", "bounced"]] 42 | """Limits the results to messages with the given delivery status.""" 43 | 44 | tenant: str 45 | """Limits the results to items with the corresponding tenant.""" 46 | 47 | trigger_data: str 48 | """Limits the results to only messages that were generated with the given data. 49 | 50 | See [trigger data filtering](/api-reference/overview/trigger-data-filtering) for 51 | more information. 52 | """ 53 | 54 | workflow_categories: List[str] 55 | """Limits the results to messages related to any of the provided categories.""" 56 | 57 | workflow_recipient_run_id: str 58 | """Limits the results to messages for a specific recipient's workflow run.""" 59 | 60 | workflow_run_id: str 61 | """ 62 | Limits the results to messages associated with the top-level workflow run ID 63 | returned by the workflow trigger request. 64 | """ 65 | 66 | 67 | class InsertedAt(TypedDict, total=False): 68 | gt: str 69 | """Limits the results to messages inserted after the given date.""" 70 | 71 | gte: str 72 | """Limits the results to messages inserted after or on the given date.""" 73 | 74 | lt: str 75 | """Limits the results to messages inserted before the given date.""" 76 | 77 | lte: str 78 | """Limits the results to messages inserted before or on the given date.""" 79 | -------------------------------------------------------------------------------- /src/knockapi/types/object_list_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import List 6 | from typing_extensions import Literal, TypedDict 7 | 8 | __all__ = ["ObjectListParams"] 9 | 10 | 11 | class ObjectListParams(TypedDict, total=False): 12 | after: str 13 | """The cursor to fetch entries after.""" 14 | 15 | before: str 16 | """The cursor to fetch entries before.""" 17 | 18 | include: List[Literal["preferences"]] 19 | """Includes preferences of the objects in the response.""" 20 | 21 | page_size: int 22 | """The number of items per page.""" 23 | -------------------------------------------------------------------------------- /src/knockapi/types/object_list_preferences_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import List 4 | from typing_extensions import TypeAlias 5 | 6 | from .recipients.preference_set import PreferenceSet 7 | 8 | __all__ = ["ObjectListPreferencesResponse"] 9 | 10 | ObjectListPreferencesResponse: TypeAlias = List[PreferenceSet] 11 | -------------------------------------------------------------------------------- /src/knockapi/types/object_list_schedules_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing_extensions import TypedDict 6 | 7 | __all__ = ["ObjectListSchedulesParams"] 8 | 9 | 10 | class ObjectListSchedulesParams(TypedDict, total=False): 11 | after: str 12 | """The cursor to fetch entries after.""" 13 | 14 | before: str 15 | """The cursor to fetch entries before.""" 16 | 17 | page_size: int 18 | """The number of items per page.""" 19 | 20 | tenant: str 21 | """Filter schedules by tenant id.""" 22 | 23 | workflow: str 24 | """Filter schedules by workflow id.""" 25 | -------------------------------------------------------------------------------- /src/knockapi/types/object_list_subscriptions_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import List, Iterable 6 | from typing_extensions import Literal, TypedDict 7 | 8 | from .recipient_reference_param import RecipientReferenceParam 9 | 10 | __all__ = ["ObjectListSubscriptionsParams", "Object"] 11 | 12 | 13 | class ObjectListSubscriptionsParams(TypedDict, total=False): 14 | after: str 15 | """The cursor to fetch entries after.""" 16 | 17 | before: str 18 | """The cursor to fetch entries before.""" 19 | 20 | include: List[Literal["preferences"]] 21 | """Additional fields to include in the response.""" 22 | 23 | mode: Literal["recipient", "object"] 24 | """Mode of the request. 25 | 26 | `recipient` to list the objects that the provided object is subscribed to, 27 | `object` to list the recipients that subscribe to the provided object. 28 | """ 29 | 30 | objects: Iterable[Object] 31 | """Objects to filter by (only used if mode is `recipient`).""" 32 | 33 | page_size: int 34 | """The number of items per page.""" 35 | 36 | recipients: List[RecipientReferenceParam] 37 | """Recipients to filter by (only used if mode is `object`).""" 38 | 39 | 40 | class Object(TypedDict, total=False): 41 | id: str 42 | """An identifier for the recipient object.""" 43 | 44 | collection: str 45 | """The collection the recipient object belongs to.""" 46 | -------------------------------------------------------------------------------- /src/knockapi/types/object_set_channel_data_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Union 6 | from typing_extensions import Required, TypeAlias, TypedDict 7 | 8 | from .recipients.push_channel_data_param import PushChannelDataParam 9 | from .recipients.slack_channel_data_param import SlackChannelDataParam 10 | from .recipients.discord_channel_data_param import DiscordChannelDataParam 11 | from .recipients.ms_teams_channel_data_param import MsTeamsChannelDataParam 12 | from .recipients.one_signal_channel_data_param import OneSignalChannelDataParam 13 | 14 | __all__ = ["ObjectSetChannelDataParams", "Data"] 15 | 16 | 17 | class ObjectSetChannelDataParams(TypedDict, total=False): 18 | data: Required[Data] 19 | """Channel data for a given channel type.""" 20 | 21 | 22 | Data: TypeAlias = Union[ 23 | PushChannelDataParam, 24 | OneSignalChannelDataParam, 25 | SlackChannelDataParam, 26 | MsTeamsChannelDataParam, 27 | DiscordChannelDataParam, 28 | ] 29 | -------------------------------------------------------------------------------- /src/knockapi/types/object_set_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Optional 6 | from typing_extensions import TypedDict 7 | 8 | from .recipients.inline_channel_data_request_param import InlineChannelDataRequestParam 9 | from .recipients.inline_preference_set_request_param import InlinePreferenceSetRequestParam 10 | 11 | __all__ = ["ObjectSetParams"] 12 | 13 | 14 | class ObjectSetParams(TypedDict, total=False): 15 | channel_data: InlineChannelDataRequestParam 16 | """A request to set channel data for a type of channel inline.""" 17 | 18 | locale: Optional[str] 19 | """The locale of the object. 20 | 21 | Used for [message localization](/concepts/translations). 22 | """ 23 | 24 | preferences: InlinePreferenceSetRequestParam 25 | """Inline set preferences for a recipient, where the key is the preference set id.""" 26 | 27 | timezone: Optional[str] 28 | """The timezone of the object. 29 | 30 | Must be a 31 | valid [tz database time zone string](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). 32 | Used 33 | for [recurring schedules](/concepts/schedules#scheduling-workflows-with-recurring-schedules-for-recipients). 34 | """ 35 | -------------------------------------------------------------------------------- /src/knockapi/types/object_set_preferences_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Dict, Union, Iterable, Optional 6 | from typing_extensions import TypeAlias, TypedDict 7 | 8 | from .condition_param import ConditionParam 9 | from .recipients.preference_set_channel_types_param import PreferenceSetChannelTypesParam 10 | 11 | __all__ = [ 12 | "ObjectSetPreferencesParams", 13 | "Categories", 14 | "CategoriesPreferenceSetWorkflowCategorySettingObject", 15 | "Workflows", 16 | "WorkflowsPreferenceSetWorkflowCategorySettingObject", 17 | ] 18 | 19 | 20 | class ObjectSetPreferencesParams(TypedDict, total=False): 21 | categories: Optional[Dict[str, Categories]] 22 | """ 23 | An object where the key is the category and the values are the preference 24 | settings for that category. 25 | """ 26 | 27 | channel_types: Optional[PreferenceSetChannelTypesParam] 28 | """Channel type preferences.""" 29 | 30 | workflows: Optional[Dict[str, Workflows]] 31 | """ 32 | An object where the key is the workflow key and the values are the preference 33 | settings for that workflow. 34 | """ 35 | 36 | 37 | class CategoriesPreferenceSetWorkflowCategorySettingObject(TypedDict, total=False): 38 | channel_types: Optional[PreferenceSetChannelTypesParam] 39 | """Channel type preferences.""" 40 | 41 | conditions: Optional[Iterable[ConditionParam]] 42 | """A list of conditions to apply to a channel type.""" 43 | 44 | 45 | Categories: TypeAlias = Union[bool, CategoriesPreferenceSetWorkflowCategorySettingObject] 46 | 47 | 48 | class WorkflowsPreferenceSetWorkflowCategorySettingObject(TypedDict, total=False): 49 | channel_types: Optional[PreferenceSetChannelTypesParam] 50 | """Channel type preferences.""" 51 | 52 | conditions: Optional[Iterable[ConditionParam]] 53 | """A list of conditions to apply to a channel type.""" 54 | 55 | 56 | Workflows: TypeAlias = Union[bool, WorkflowsPreferenceSetWorkflowCategorySettingObject] 57 | -------------------------------------------------------------------------------- /src/knockapi/types/object_unset_channel_data_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing_extensions import TypeAlias 4 | 5 | __all__ = ["ObjectUnsetChannelDataResponse"] 6 | 7 | ObjectUnsetChannelDataResponse: TypeAlias = str 8 | -------------------------------------------------------------------------------- /src/knockapi/types/objects/__init__.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from .bulk_set_params import BulkSetParams as BulkSetParams 6 | from .bulk_delete_params import BulkDeleteParams as BulkDeleteParams 7 | from .bulk_add_subscriptions_params import BulkAddSubscriptionsParams as BulkAddSubscriptionsParams 8 | -------------------------------------------------------------------------------- /src/knockapi/types/objects/bulk_add_subscriptions_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Dict, List, Iterable, Optional 6 | from typing_extensions import Required, TypedDict 7 | 8 | from ..recipient_request_param import RecipientRequestParam 9 | 10 | __all__ = ["BulkAddSubscriptionsParams", "Subscription"] 11 | 12 | 13 | class BulkAddSubscriptionsParams(TypedDict, total=False): 14 | subscriptions: Required[Iterable[Subscription]] 15 | """A list of subscriptions.""" 16 | 17 | 18 | class Subscription(TypedDict, total=False): 19 | recipients: Required[List[RecipientRequestParam]] 20 | """The recipients of the subscription. 21 | 22 | You can subscribe up to 100 recipients to an object at a time. 23 | """ 24 | 25 | properties: Optional[Dict[str, object]] 26 | """The custom properties associated with the subscription relationship.""" 27 | -------------------------------------------------------------------------------- /src/knockapi/types/objects/bulk_delete_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import List 6 | from typing_extensions import Required, TypedDict 7 | 8 | __all__ = ["BulkDeleteParams"] 9 | 10 | 11 | class BulkDeleteParams(TypedDict, total=False): 12 | object_ids: Required[List[str]] 13 | """List of object IDs to delete.""" 14 | -------------------------------------------------------------------------------- /src/knockapi/types/objects/bulk_set_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Dict, Union, Iterable, Optional 6 | from datetime import datetime 7 | from typing_extensions import Required, Annotated, TypeAlias, TypedDict 8 | 9 | from ..._utils import PropertyInfo 10 | from ..recipients.inline_channel_data_request_param import InlineChannelDataRequestParam 11 | from ..recipients.inline_preference_set_request_param import InlinePreferenceSetRequestParam 12 | 13 | __all__ = ["BulkSetParams", "Object"] 14 | 15 | 16 | class BulkSetParams(TypedDict, total=False): 17 | objects: Required[Iterable[Object]] 18 | """A list of objects.""" 19 | 20 | 21 | class ObjectTyped(TypedDict, total=False): 22 | id: Required[str] 23 | """Unique identifier for the object.""" 24 | 25 | channel_data: Optional[InlineChannelDataRequestParam] 26 | """A request to set channel data for a type of channel inline.""" 27 | 28 | created_at: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")] 29 | """Timestamp when the resource was created.""" 30 | 31 | preferences: Optional[InlinePreferenceSetRequestParam] 32 | """Inline set preferences for a recipient, where the key is the preference set id.""" 33 | 34 | 35 | Object: TypeAlias = Union[ObjectTyped, Dict[str, object]] 36 | -------------------------------------------------------------------------------- /src/knockapi/types/page_info.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import Optional 4 | 5 | from pydantic import Field as FieldInfo 6 | 7 | from .._models import BaseModel 8 | 9 | __all__ = ["PageInfo"] 10 | 11 | 12 | class PageInfo(BaseModel): 13 | api_typename: str = FieldInfo(alias="__typename") 14 | """The typename of the schema.""" 15 | 16 | page_size: int 17 | """The number of items per page.""" 18 | 19 | after: Optional[str] = None 20 | """The cursor to fetch entries after.""" 21 | 22 | before: Optional[str] = None 23 | """The cursor to fetch entries before.""" 24 | -------------------------------------------------------------------------------- /src/knockapi/types/providers/__init__.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from .slack_check_auth_params import SlackCheckAuthParams as SlackCheckAuthParams 6 | from .ms_team_check_auth_params import MsTeamCheckAuthParams as MsTeamCheckAuthParams 7 | from .ms_team_list_teams_params import MsTeamListTeamsParams as MsTeamListTeamsParams 8 | from .slack_check_auth_response import SlackCheckAuthResponse as SlackCheckAuthResponse 9 | from .slack_list_channels_params import SlackListChannelsParams as SlackListChannelsParams 10 | from .slack_revoke_access_params import SlackRevokeAccessParams as SlackRevokeAccessParams 11 | from .ms_team_check_auth_response import MsTeamCheckAuthResponse as MsTeamCheckAuthResponse 12 | from .ms_team_list_teams_response import MsTeamListTeamsResponse as MsTeamListTeamsResponse 13 | from .ms_team_list_channels_params import MsTeamListChannelsParams as MsTeamListChannelsParams 14 | from .ms_team_revoke_access_params import MsTeamRevokeAccessParams as MsTeamRevokeAccessParams 15 | from .slack_list_channels_response import SlackListChannelsResponse as SlackListChannelsResponse 16 | from .slack_revoke_access_response import SlackRevokeAccessResponse as SlackRevokeAccessResponse 17 | from .ms_team_list_channels_response import MsTeamListChannelsResponse as MsTeamListChannelsResponse 18 | from .ms_team_revoke_access_response import MsTeamRevokeAccessResponse as MsTeamRevokeAccessResponse 19 | -------------------------------------------------------------------------------- /src/knockapi/types/providers/ms_team_check_auth_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing_extensions import Required, TypedDict 6 | 7 | __all__ = ["MsTeamCheckAuthParams"] 8 | 9 | 10 | class MsTeamCheckAuthParams(TypedDict, total=False): 11 | ms_teams_tenant_object: Required[str] 12 | """A JSON encoded string containing the Microsoft Teams tenant object reference.""" 13 | -------------------------------------------------------------------------------- /src/knockapi/types/providers/ms_team_check_auth_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import Optional 4 | 5 | from ..._models import BaseModel 6 | 7 | __all__ = ["MsTeamCheckAuthResponse", "Connection"] 8 | 9 | 10 | class Connection(BaseModel): 11 | ok: bool 12 | """Whether the Microsoft Teams connection is valid.""" 13 | 14 | reason: Optional[str] = None 15 | """The reason for the Microsoft Teams connection if it is not valid.""" 16 | 17 | 18 | class MsTeamCheckAuthResponse(BaseModel): 19 | connection: Connection 20 | """A Microsoft Teams connection object.""" 21 | -------------------------------------------------------------------------------- /src/knockapi/types/providers/ms_team_list_channels_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing_extensions import Required, Annotated, TypedDict 6 | 7 | from ..._utils import PropertyInfo 8 | 9 | __all__ = ["MsTeamListChannelsParams", "QueryOptions"] 10 | 11 | 12 | class MsTeamListChannelsParams(TypedDict, total=False): 13 | ms_teams_tenant_object: Required[str] 14 | """A JSON encoded string containing the Microsoft Teams tenant object reference.""" 15 | 16 | team_id: Required[str] 17 | """Microsoft Teams team ID.""" 18 | 19 | query_options: QueryOptions 20 | 21 | 22 | class QueryOptions(TypedDict, total=False): 23 | filter: Annotated[str, PropertyInfo(alias="$filter")] 24 | """ 25 | [OData param](https://learn.microsoft.com/en-us/graph/query-parameters) passed 26 | to the Microsoft Graph API to filter channels. 27 | """ 28 | 29 | select: Annotated[str, PropertyInfo(alias="$select")] 30 | """ 31 | [OData param](https://learn.microsoft.com/en-us/graph/query-parameters) passed 32 | to the Microsoft Graph API to select specific properties. 33 | """ 34 | -------------------------------------------------------------------------------- /src/knockapi/types/providers/ms_team_list_channels_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import List, Optional 4 | 5 | from pydantic import Field as FieldInfo 6 | 7 | from ..._models import BaseModel 8 | 9 | __all__ = ["MsTeamListChannelsResponse", "MsTeamsChannel"] 10 | 11 | 12 | class MsTeamsChannel(BaseModel): 13 | id: str 14 | """Microsoft Teams channel ID.""" 15 | 16 | display_name: str = FieldInfo(alias="displayName") 17 | """Microsoft Teams channel name.""" 18 | 19 | created_date_time: Optional[str] = FieldInfo(alias="createdDateTime", default=None) 20 | """Microsoft Teams channel created date and time.""" 21 | 22 | description: Optional[str] = None 23 | """Microsoft Teams channel description.""" 24 | 25 | is_archived: Optional[bool] = FieldInfo(alias="isArchived", default=None) 26 | """Whether the Microsoft Teams channel is archived.""" 27 | 28 | membership_type: Optional[str] = FieldInfo(alias="membershipType", default=None) 29 | """Microsoft Teams channel membership type.""" 30 | 31 | 32 | class MsTeamListChannelsResponse(BaseModel): 33 | ms_teams_channels: List[MsTeamsChannel] 34 | """List of Microsoft Teams channels.""" 35 | -------------------------------------------------------------------------------- /src/knockapi/types/providers/ms_team_list_teams_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing_extensions import Required, Annotated, TypedDict 6 | 7 | from ..._utils import PropertyInfo 8 | 9 | __all__ = ["MsTeamListTeamsParams", "QueryOptions"] 10 | 11 | 12 | class MsTeamListTeamsParams(TypedDict, total=False): 13 | ms_teams_tenant_object: Required[str] 14 | """A JSON encoded string containing the Microsoft Teams tenant object reference.""" 15 | 16 | query_options: QueryOptions 17 | 18 | 19 | class QueryOptions(TypedDict, total=False): 20 | filter: Annotated[str, PropertyInfo(alias="$filter")] 21 | """ 22 | [OData param](https://learn.microsoft.com/en-us/graph/query-parameters) passed 23 | to the Microsoft Graph API to filter teams. 24 | """ 25 | 26 | select: Annotated[str, PropertyInfo(alias="$select")] 27 | """ 28 | [OData param](https://learn.microsoft.com/en-us/graph/query-parameters) passed 29 | to the Microsoft Graph API to select fields on a team. 30 | """ 31 | 32 | skiptoken: Annotated[str, PropertyInfo(alias="$skiptoken")] 33 | """ 34 | [OData param](https://learn.microsoft.com/en-us/graph/query-parameters) passed 35 | to the Microsoft Graph API to retrieve the next page of results. 36 | """ 37 | 38 | top: Annotated[int, PropertyInfo(alias="$top")] 39 | """ 40 | [OData param](https://learn.microsoft.com/en-us/graph/query-parameters) passed 41 | to the Microsoft Graph API to limit the number of teams returned. 42 | """ 43 | -------------------------------------------------------------------------------- /src/knockapi/types/providers/ms_team_list_teams_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import Optional 4 | 5 | from pydantic import Field as FieldInfo 6 | 7 | from ..._models import BaseModel 8 | 9 | __all__ = ["MsTeamListTeamsResponse"] 10 | 11 | 12 | class MsTeamListTeamsResponse(BaseModel): 13 | id: str 14 | """Microsoft Teams team ID.""" 15 | 16 | display_name: str = FieldInfo(alias="displayName") 17 | """Microsoft Teams team display name.""" 18 | 19 | description: Optional[str] = None 20 | """Microsoft Teams team description.""" 21 | -------------------------------------------------------------------------------- /src/knockapi/types/providers/ms_team_revoke_access_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing_extensions import Required, TypedDict 6 | 7 | __all__ = ["MsTeamRevokeAccessParams"] 8 | 9 | 10 | class MsTeamRevokeAccessParams(TypedDict, total=False): 11 | ms_teams_tenant_object: Required[str] 12 | """A JSON encoded string containing the Microsoft Teams tenant object reference.""" 13 | -------------------------------------------------------------------------------- /src/knockapi/types/providers/ms_team_revoke_access_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import Optional 4 | 5 | from ..._models import BaseModel 6 | 7 | __all__ = ["MsTeamRevokeAccessResponse"] 8 | 9 | 10 | class MsTeamRevokeAccessResponse(BaseModel): 11 | ok: Optional[str] = None 12 | """OK response.""" 13 | -------------------------------------------------------------------------------- /src/knockapi/types/providers/slack_check_auth_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing_extensions import Required, TypedDict 6 | 7 | __all__ = ["SlackCheckAuthParams"] 8 | 9 | 10 | class SlackCheckAuthParams(TypedDict, total=False): 11 | access_token_object: Required[str] 12 | """A JSON encoded string containing the access token object reference.""" 13 | -------------------------------------------------------------------------------- /src/knockapi/types/providers/slack_check_auth_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import Optional 4 | 5 | from ..._models import BaseModel 6 | 7 | __all__ = ["SlackCheckAuthResponse", "Connection"] 8 | 9 | 10 | class Connection(BaseModel): 11 | ok: bool 12 | """Whether the Slack connection is valid.""" 13 | 14 | reason: Optional[str] = None 15 | """The reason for the Slack connection if it is not valid.""" 16 | 17 | 18 | class SlackCheckAuthResponse(BaseModel): 19 | connection: Connection 20 | """A Slack connection object.""" 21 | -------------------------------------------------------------------------------- /src/knockapi/types/providers/slack_list_channels_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing_extensions import Required, TypedDict 6 | 7 | __all__ = ["SlackListChannelsParams", "QueryOptions"] 8 | 9 | 10 | class SlackListChannelsParams(TypedDict, total=False): 11 | access_token_object: Required[str] 12 | """A JSON encoded string containing the access token object reference.""" 13 | 14 | query_options: QueryOptions 15 | 16 | 17 | class QueryOptions(TypedDict, total=False): 18 | cursor: str 19 | """ 20 | Paginate through collections of data by setting the cursor parameter to a 21 | next_cursor attribute returned by a previous request's response_metadata. 22 | Default value fetches the first "page" of the collection. 23 | """ 24 | 25 | exclude_archived: bool 26 | """Set to true to exclude archived channels from the list.""" 27 | 28 | limit: int 29 | """The maximum number of channels to return.""" 30 | 31 | team_id: str 32 | """Encoded team ID (T1234) to list channels in, required if org token is used.""" 33 | 34 | types: str 35 | """ 36 | Mix and match channel types by providing a comma-separated list of any 37 | combination of public_channel, private_channel, mpim, im. 38 | """ 39 | -------------------------------------------------------------------------------- /src/knockapi/types/providers/slack_list_channels_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from ..._models import BaseModel 4 | 5 | __all__ = ["SlackListChannelsResponse"] 6 | 7 | 8 | class SlackListChannelsResponse(BaseModel): 9 | id: str 10 | """A Slack channel ID from the Slack provider.""" 11 | 12 | context_team_id: str 13 | """The team ID that the Slack channel belongs to.""" 14 | 15 | is_im: bool 16 | """Whether the Slack channel is an IM channel.""" 17 | 18 | is_private: bool 19 | """Whether the Slack channel is private.""" 20 | 21 | name: str 22 | """Slack channel name.""" 23 | -------------------------------------------------------------------------------- /src/knockapi/types/providers/slack_revoke_access_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing_extensions import Required, TypedDict 6 | 7 | __all__ = ["SlackRevokeAccessParams"] 8 | 9 | 10 | class SlackRevokeAccessParams(TypedDict, total=False): 11 | access_token_object: Required[str] 12 | """A JSON encoded string containing the access token object reference.""" 13 | -------------------------------------------------------------------------------- /src/knockapi/types/providers/slack_revoke_access_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import Optional 4 | 5 | from ..._models import BaseModel 6 | 7 | __all__ = ["SlackRevokeAccessResponse"] 8 | 9 | 10 | class SlackRevokeAccessResponse(BaseModel): 11 | ok: Optional[str] = None 12 | """OK response.""" 13 | -------------------------------------------------------------------------------- /src/knockapi/types/recipient.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import Union 4 | from typing_extensions import TypeAlias 5 | 6 | from .user import User 7 | from .object import Object 8 | 9 | __all__ = ["Recipient"] 10 | 11 | Recipient: TypeAlias = Union[User, Object] 12 | -------------------------------------------------------------------------------- /src/knockapi/types/recipient_reference.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import Union, Optional 4 | from typing_extensions import TypeAlias 5 | 6 | from .._models import BaseModel 7 | 8 | __all__ = ["RecipientReference", "ObjectReference"] 9 | 10 | 11 | class ObjectReference(BaseModel): 12 | id: Optional[str] = None 13 | """An identifier for the recipient object.""" 14 | 15 | collection: Optional[str] = None 16 | """The collection the recipient object belongs to.""" 17 | 18 | 19 | RecipientReference: TypeAlias = Union[str, ObjectReference] 20 | -------------------------------------------------------------------------------- /src/knockapi/types/recipient_reference_param.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Union 6 | from typing_extensions import TypeAlias, TypedDict 7 | 8 | __all__ = ["RecipientReferenceParam", "ObjectReference"] 9 | 10 | 11 | class ObjectReference(TypedDict, total=False): 12 | id: str 13 | """An identifier for the recipient object.""" 14 | 15 | collection: str 16 | """The collection the recipient object belongs to.""" 17 | 18 | 19 | RecipientReferenceParam: TypeAlias = Union[str, ObjectReference] 20 | -------------------------------------------------------------------------------- /src/knockapi/types/recipient_request_param.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Union 6 | from typing_extensions import TypeAlias 7 | 8 | from .inline_object_request_param import InlineObjectRequestParam 9 | from .inline_identify_user_request_param import InlineIdentifyUserRequestParam 10 | 11 | __all__ = ["RecipientRequestParam"] 12 | 13 | RecipientRequestParam: TypeAlias = Union[str, InlineIdentifyUserRequestParam, InlineObjectRequestParam] 14 | -------------------------------------------------------------------------------- /src/knockapi/types/recipients/__init__.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from .channel_data import ChannelData as ChannelData 6 | from .subscription import Subscription as Subscription 7 | from .preference_set import PreferenceSet as PreferenceSet 8 | from .push_channel_data import PushChannelData as PushChannelData 9 | from .slack_channel_data import SlackChannelData as SlackChannelData 10 | from .discord_channel_data import DiscordChannelData as DiscordChannelData 11 | from .ms_teams_channel_data import MsTeamsChannelData as MsTeamsChannelData 12 | from .one_signal_channel_data import OneSignalChannelData as OneSignalChannelData 13 | from .push_channel_data_param import PushChannelDataParam as PushChannelDataParam 14 | from .slack_channel_data_param import SlackChannelDataParam as SlackChannelDataParam 15 | from .discord_channel_data_param import DiscordChannelDataParam as DiscordChannelDataParam 16 | from .ms_teams_channel_data_param import MsTeamsChannelDataParam as MsTeamsChannelDataParam 17 | from .preference_set_channel_types import PreferenceSetChannelTypes as PreferenceSetChannelTypes 18 | from .preference_set_request_param import PreferenceSetRequestParam as PreferenceSetRequestParam 19 | from .one_signal_channel_data_param import OneSignalChannelDataParam as OneSignalChannelDataParam 20 | from .inline_channel_data_request_param import InlineChannelDataRequestParam as InlineChannelDataRequestParam 21 | from .preference_set_channel_types_param import PreferenceSetChannelTypesParam as PreferenceSetChannelTypesParam 22 | from .inline_preference_set_request_param import InlinePreferenceSetRequestParam as InlinePreferenceSetRequestParam 23 | from .preference_set_channel_type_setting import PreferenceSetChannelTypeSetting as PreferenceSetChannelTypeSetting 24 | from .preference_set_channel_type_setting_param import ( 25 | PreferenceSetChannelTypeSettingParam as PreferenceSetChannelTypeSettingParam, 26 | ) 27 | -------------------------------------------------------------------------------- /src/knockapi/types/recipients/channel_data.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import Union, Optional 4 | from typing_extensions import Literal, TypeAlias 5 | 6 | from pydantic import Field as FieldInfo 7 | 8 | from ..._models import BaseModel 9 | from .push_channel_data import PushChannelData 10 | from .slack_channel_data import SlackChannelData 11 | from .discord_channel_data import DiscordChannelData 12 | from .ms_teams_channel_data import MsTeamsChannelData 13 | from .one_signal_channel_data import OneSignalChannelData 14 | 15 | __all__ = ["ChannelData", "Data"] 16 | 17 | Data: TypeAlias = Union[PushChannelData, SlackChannelData, MsTeamsChannelData, DiscordChannelData, OneSignalChannelData] 18 | 19 | 20 | class ChannelData(BaseModel): 21 | api_typename: str = FieldInfo(alias="__typename") 22 | """The typename of the schema.""" 23 | 24 | channel_id: str 25 | """The unique identifier for the channel.""" 26 | 27 | data: Data 28 | """Channel data for a given channel type.""" 29 | 30 | provider: Optional[ 31 | Literal[ 32 | "push_fcm", 33 | "push_apns", 34 | "push_expo", 35 | "push_one_signal", 36 | "chat_slack", 37 | "chat_ms_teams", 38 | "chat_discord", 39 | "http_knock_webhook", 40 | ] 41 | ] = None 42 | """The type of provider.""" 43 | -------------------------------------------------------------------------------- /src/knockapi/types/recipients/discord_channel_data.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import List, Union 4 | from typing_extensions import TypeAlias 5 | 6 | from ..._models import BaseModel 7 | 8 | __all__ = [ 9 | "DiscordChannelData", 10 | "Connection", 11 | "ConnectionDiscordChannelConnection", 12 | "ConnectionDiscordIncomingWebhookConnection", 13 | "ConnectionDiscordIncomingWebhookConnectionIncomingWebhook", 14 | ] 15 | 16 | 17 | class ConnectionDiscordChannelConnection(BaseModel): 18 | channel_id: str 19 | """Discord channel ID.""" 20 | 21 | 22 | class ConnectionDiscordIncomingWebhookConnectionIncomingWebhook(BaseModel): 23 | url: str 24 | """Incoming webhook URL.""" 25 | 26 | 27 | class ConnectionDiscordIncomingWebhookConnection(BaseModel): 28 | incoming_webhook: ConnectionDiscordIncomingWebhookConnectionIncomingWebhook 29 | """Discord incoming webhook object.""" 30 | 31 | 32 | Connection: TypeAlias = Union[ConnectionDiscordChannelConnection, ConnectionDiscordIncomingWebhookConnection] 33 | 34 | 35 | class DiscordChannelData(BaseModel): 36 | connections: List[Connection] 37 | """List of Discord channel connections.""" 38 | -------------------------------------------------------------------------------- /src/knockapi/types/recipients/discord_channel_data_param.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Union, Iterable 6 | from typing_extensions import Required, TypeAlias, TypedDict 7 | 8 | __all__ = [ 9 | "DiscordChannelDataParam", 10 | "Connection", 11 | "ConnectionDiscordChannelConnection", 12 | "ConnectionDiscordIncomingWebhookConnection", 13 | "ConnectionDiscordIncomingWebhookConnectionIncomingWebhook", 14 | ] 15 | 16 | 17 | class ConnectionDiscordChannelConnection(TypedDict, total=False): 18 | channel_id: Required[str] 19 | """Discord channel ID.""" 20 | 21 | 22 | class ConnectionDiscordIncomingWebhookConnectionIncomingWebhook(TypedDict, total=False): 23 | url: Required[str] 24 | """Incoming webhook URL.""" 25 | 26 | 27 | class ConnectionDiscordIncomingWebhookConnection(TypedDict, total=False): 28 | incoming_webhook: Required[ConnectionDiscordIncomingWebhookConnectionIncomingWebhook] 29 | """Discord incoming webhook object.""" 30 | 31 | 32 | Connection: TypeAlias = Union[ConnectionDiscordChannelConnection, ConnectionDiscordIncomingWebhookConnection] 33 | 34 | 35 | class DiscordChannelDataParam(TypedDict, total=False): 36 | connections: Required[Iterable[Connection]] 37 | """List of Discord channel connections.""" 38 | -------------------------------------------------------------------------------- /src/knockapi/types/recipients/inline_channel_data_request_param.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Dict, Union 6 | from typing_extensions import TypeAlias 7 | 8 | from .push_channel_data_param import PushChannelDataParam 9 | from .slack_channel_data_param import SlackChannelDataParam 10 | from .discord_channel_data_param import DiscordChannelDataParam 11 | from .ms_teams_channel_data_param import MsTeamsChannelDataParam 12 | from .one_signal_channel_data_param import OneSignalChannelDataParam 13 | 14 | __all__ = ["InlineChannelDataRequestParam", "InlineChannelDataRequestParamItem"] 15 | 16 | InlineChannelDataRequestParamItem: TypeAlias = Union[ 17 | PushChannelDataParam, 18 | OneSignalChannelDataParam, 19 | SlackChannelDataParam, 20 | MsTeamsChannelDataParam, 21 | DiscordChannelDataParam, 22 | ] 23 | 24 | InlineChannelDataRequestParam: TypeAlias = Dict[str, InlineChannelDataRequestParamItem] 25 | -------------------------------------------------------------------------------- /src/knockapi/types/recipients/inline_preference_set_request_param.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Dict 6 | from typing_extensions import TypeAlias 7 | 8 | from .preference_set_request_param import PreferenceSetRequestParam 9 | 10 | __all__ = ["InlinePreferenceSetRequestParam"] 11 | 12 | InlinePreferenceSetRequestParam: TypeAlias = Dict[str, PreferenceSetRequestParam] 13 | -------------------------------------------------------------------------------- /src/knockapi/types/recipients/ms_teams_channel_data.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import List, Union, Optional 4 | from typing_extensions import TypeAlias 5 | 6 | from ..._models import BaseModel 7 | 8 | __all__ = [ 9 | "MsTeamsChannelData", 10 | "Connection", 11 | "ConnectionMsTeamsTokenConnection", 12 | "ConnectionMsTeamsIncomingWebhookConnection", 13 | "ConnectionMsTeamsIncomingWebhookConnectionIncomingWebhook", 14 | ] 15 | 16 | 17 | class ConnectionMsTeamsTokenConnection(BaseModel): 18 | ms_teams_channel_id: Optional[str] = None 19 | """Microsoft Teams channel ID.""" 20 | 21 | ms_teams_team_id: Optional[str] = None 22 | """Microsoft Teams team ID.""" 23 | 24 | ms_teams_tenant_id: Optional[str] = None 25 | """Microsoft Teams tenant ID.""" 26 | 27 | ms_teams_user_id: Optional[str] = None 28 | """Microsoft Teams user ID.""" 29 | 30 | 31 | class ConnectionMsTeamsIncomingWebhookConnectionIncomingWebhook(BaseModel): 32 | url: str 33 | """Microsoft Teams incoming webhook URL.""" 34 | 35 | 36 | class ConnectionMsTeamsIncomingWebhookConnection(BaseModel): 37 | incoming_webhook: ConnectionMsTeamsIncomingWebhookConnectionIncomingWebhook 38 | """Microsoft Teams incoming webhook.""" 39 | 40 | 41 | Connection: TypeAlias = Union[ConnectionMsTeamsTokenConnection, ConnectionMsTeamsIncomingWebhookConnection] 42 | 43 | 44 | class MsTeamsChannelData(BaseModel): 45 | connections: List[Connection] 46 | """List of Microsoft Teams connections.""" 47 | 48 | ms_teams_tenant_id: Optional[str] = None 49 | """Microsoft Teams tenant ID.""" 50 | -------------------------------------------------------------------------------- /src/knockapi/types/recipients/ms_teams_channel_data_param.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Union, Iterable, Optional 6 | from typing_extensions import Required, TypeAlias, TypedDict 7 | 8 | __all__ = [ 9 | "MsTeamsChannelDataParam", 10 | "Connection", 11 | "ConnectionMsTeamsTokenConnection", 12 | "ConnectionMsTeamsIncomingWebhookConnection", 13 | "ConnectionMsTeamsIncomingWebhookConnectionIncomingWebhook", 14 | ] 15 | 16 | 17 | class ConnectionMsTeamsTokenConnection(TypedDict, total=False): 18 | ms_teams_channel_id: Optional[str] 19 | """Microsoft Teams channel ID.""" 20 | 21 | ms_teams_team_id: Optional[str] 22 | """Microsoft Teams team ID.""" 23 | 24 | ms_teams_tenant_id: Optional[str] 25 | """Microsoft Teams tenant ID.""" 26 | 27 | ms_teams_user_id: Optional[str] 28 | """Microsoft Teams user ID.""" 29 | 30 | 31 | class ConnectionMsTeamsIncomingWebhookConnectionIncomingWebhook(TypedDict, total=False): 32 | url: Required[str] 33 | """Microsoft Teams incoming webhook URL.""" 34 | 35 | 36 | class ConnectionMsTeamsIncomingWebhookConnection(TypedDict, total=False): 37 | incoming_webhook: Required[ConnectionMsTeamsIncomingWebhookConnectionIncomingWebhook] 38 | """Microsoft Teams incoming webhook.""" 39 | 40 | 41 | Connection: TypeAlias = Union[ConnectionMsTeamsTokenConnection, ConnectionMsTeamsIncomingWebhookConnection] 42 | 43 | 44 | class MsTeamsChannelDataParam(TypedDict, total=False): 45 | connections: Required[Iterable[Connection]] 46 | """List of Microsoft Teams connections.""" 47 | 48 | ms_teams_tenant_id: Optional[str] 49 | """Microsoft Teams tenant ID.""" 50 | -------------------------------------------------------------------------------- /src/knockapi/types/recipients/one_signal_channel_data.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import List 4 | 5 | from ..._models import BaseModel 6 | 7 | __all__ = ["OneSignalChannelData"] 8 | 9 | 10 | class OneSignalChannelData(BaseModel): 11 | player_ids: List[str] 12 | """A list of OneSignal player IDs.""" 13 | -------------------------------------------------------------------------------- /src/knockapi/types/recipients/one_signal_channel_data_param.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import List 6 | from typing_extensions import Required, TypedDict 7 | 8 | __all__ = ["OneSignalChannelDataParam"] 9 | 10 | 11 | class OneSignalChannelDataParam(TypedDict, total=False): 12 | player_ids: Required[List[str]] 13 | """A list of OneSignal player IDs.""" 14 | -------------------------------------------------------------------------------- /src/knockapi/types/recipients/preference_set.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import Dict, List, Union, Optional 4 | from typing_extensions import TypeAlias 5 | 6 | from ..._models import BaseModel 7 | from ..condition import Condition 8 | from .preference_set_channel_types import PreferenceSetChannelTypes 9 | 10 | __all__ = [ 11 | "PreferenceSet", 12 | "Categories", 13 | "CategoriesPreferenceSetWorkflowCategorySettingObject", 14 | "Workflows", 15 | "WorkflowsPreferenceSetWorkflowCategorySettingObject", 16 | ] 17 | 18 | 19 | class CategoriesPreferenceSetWorkflowCategorySettingObject(BaseModel): 20 | channel_types: Optional[PreferenceSetChannelTypes] = None 21 | """Channel type preferences.""" 22 | 23 | conditions: Optional[List[Condition]] = None 24 | """A list of conditions to apply to a channel type.""" 25 | 26 | 27 | Categories: TypeAlias = Union[bool, CategoriesPreferenceSetWorkflowCategorySettingObject] 28 | 29 | 30 | class WorkflowsPreferenceSetWorkflowCategorySettingObject(BaseModel): 31 | channel_types: Optional[PreferenceSetChannelTypes] = None 32 | """Channel type preferences.""" 33 | 34 | conditions: Optional[List[Condition]] = None 35 | """A list of conditions to apply to a channel type.""" 36 | 37 | 38 | Workflows: TypeAlias = Union[bool, WorkflowsPreferenceSetWorkflowCategorySettingObject] 39 | 40 | 41 | class PreferenceSet(BaseModel): 42 | id: str 43 | """Unique identifier for the preference set.""" 44 | 45 | categories: Optional[Dict[str, Categories]] = None 46 | """ 47 | An object where the key is the category and the values are the preference 48 | settings for that category. 49 | """ 50 | 51 | channel_types: Optional[PreferenceSetChannelTypes] = None 52 | """Channel type preferences.""" 53 | 54 | workflows: Optional[Dict[str, Workflows]] = None 55 | """ 56 | An object where the key is the workflow key and the values are the preference 57 | settings for that workflow. 58 | """ 59 | -------------------------------------------------------------------------------- /src/knockapi/types/recipients/preference_set_channel_type_setting.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import List 4 | 5 | from ..._models import BaseModel 6 | from ..condition import Condition 7 | 8 | __all__ = ["PreferenceSetChannelTypeSetting"] 9 | 10 | 11 | class PreferenceSetChannelTypeSetting(BaseModel): 12 | conditions: List[Condition] 13 | """A list of conditions to apply to a channel type.""" 14 | -------------------------------------------------------------------------------- /src/knockapi/types/recipients/preference_set_channel_type_setting_param.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Iterable 6 | from typing_extensions import Required, TypedDict 7 | 8 | from ..condition_param import ConditionParam 9 | 10 | __all__ = ["PreferenceSetChannelTypeSettingParam"] 11 | 12 | 13 | class PreferenceSetChannelTypeSettingParam(TypedDict, total=False): 14 | conditions: Required[Iterable[ConditionParam]] 15 | """A list of conditions to apply to a channel type.""" 16 | -------------------------------------------------------------------------------- /src/knockapi/types/recipients/preference_set_channel_types.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import Union, Optional 4 | from typing_extensions import TypeAlias 5 | 6 | from ..._models import BaseModel 7 | from .preference_set_channel_type_setting import PreferenceSetChannelTypeSetting 8 | 9 | __all__ = ["PreferenceSetChannelTypes", "Chat", "Email", "HTTP", "InAppFeed", "Push", "SMS"] 10 | 11 | Chat: TypeAlias = Union[bool, PreferenceSetChannelTypeSetting] 12 | 13 | Email: TypeAlias = Union[bool, PreferenceSetChannelTypeSetting] 14 | 15 | HTTP: TypeAlias = Union[bool, PreferenceSetChannelTypeSetting] 16 | 17 | InAppFeed: TypeAlias = Union[bool, PreferenceSetChannelTypeSetting] 18 | 19 | Push: TypeAlias = Union[bool, PreferenceSetChannelTypeSetting] 20 | 21 | SMS: TypeAlias = Union[bool, PreferenceSetChannelTypeSetting] 22 | 23 | 24 | class PreferenceSetChannelTypes(BaseModel): 25 | chat: Optional[Chat] = None 26 | """Whether the channel type is enabled for the preference set.""" 27 | 28 | email: Optional[Email] = None 29 | """Whether the channel type is enabled for the preference set.""" 30 | 31 | http: Optional[HTTP] = None 32 | """Whether the channel type is enabled for the preference set.""" 33 | 34 | in_app_feed: Optional[InAppFeed] = None 35 | """Whether the channel type is enabled for the preference set.""" 36 | 37 | push: Optional[Push] = None 38 | """Whether the channel type is enabled for the preference set.""" 39 | 40 | sms: Optional[SMS] = None 41 | """Whether the channel type is enabled for the preference set.""" 42 | -------------------------------------------------------------------------------- /src/knockapi/types/recipients/preference_set_channel_types_param.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Union 6 | from typing_extensions import TypeAlias, TypedDict 7 | 8 | from .preference_set_channel_type_setting_param import PreferenceSetChannelTypeSettingParam 9 | 10 | __all__ = ["PreferenceSetChannelTypesParam", "Chat", "Email", "HTTP", "InAppFeed", "Push", "SMS"] 11 | 12 | Chat: TypeAlias = Union[bool, PreferenceSetChannelTypeSettingParam] 13 | 14 | Email: TypeAlias = Union[bool, PreferenceSetChannelTypeSettingParam] 15 | 16 | HTTP: TypeAlias = Union[bool, PreferenceSetChannelTypeSettingParam] 17 | 18 | InAppFeed: TypeAlias = Union[bool, PreferenceSetChannelTypeSettingParam] 19 | 20 | Push: TypeAlias = Union[bool, PreferenceSetChannelTypeSettingParam] 21 | 22 | SMS: TypeAlias = Union[bool, PreferenceSetChannelTypeSettingParam] 23 | 24 | 25 | class PreferenceSetChannelTypesParam(TypedDict, total=False): 26 | chat: Chat 27 | """Whether the channel type is enabled for the preference set.""" 28 | 29 | email: Email 30 | """Whether the channel type is enabled for the preference set.""" 31 | 32 | http: HTTP 33 | """Whether the channel type is enabled for the preference set.""" 34 | 35 | in_app_feed: InAppFeed 36 | """Whether the channel type is enabled for the preference set.""" 37 | 38 | push: Push 39 | """Whether the channel type is enabled for the preference set.""" 40 | 41 | sms: SMS 42 | """Whether the channel type is enabled for the preference set.""" 43 | -------------------------------------------------------------------------------- /src/knockapi/types/recipients/preference_set_request_param.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Dict, Union, Iterable, Optional 6 | from typing_extensions import TypeAlias, TypedDict 7 | 8 | from ..condition_param import ConditionParam 9 | from .preference_set_channel_types_param import PreferenceSetChannelTypesParam 10 | 11 | __all__ = [ 12 | "PreferenceSetRequestParam", 13 | "Categories", 14 | "CategoriesPreferenceSetWorkflowCategorySettingObject", 15 | "Workflows", 16 | "WorkflowsPreferenceSetWorkflowCategorySettingObject", 17 | ] 18 | 19 | 20 | class CategoriesPreferenceSetWorkflowCategorySettingObject(TypedDict, total=False): 21 | channel_types: Optional[PreferenceSetChannelTypesParam] 22 | """Channel type preferences.""" 23 | 24 | conditions: Optional[Iterable[ConditionParam]] 25 | """A list of conditions to apply to a channel type.""" 26 | 27 | 28 | Categories: TypeAlias = Union[bool, CategoriesPreferenceSetWorkflowCategorySettingObject] 29 | 30 | 31 | class WorkflowsPreferenceSetWorkflowCategorySettingObject(TypedDict, total=False): 32 | channel_types: Optional[PreferenceSetChannelTypesParam] 33 | """Channel type preferences.""" 34 | 35 | conditions: Optional[Iterable[ConditionParam]] 36 | """A list of conditions to apply to a channel type.""" 37 | 38 | 39 | Workflows: TypeAlias = Union[bool, WorkflowsPreferenceSetWorkflowCategorySettingObject] 40 | 41 | 42 | class PreferenceSetRequestParam(TypedDict, total=False): 43 | categories: Optional[Dict[str, Categories]] 44 | """ 45 | An object where the key is the category and the values are the preference 46 | settings for that category. 47 | """ 48 | 49 | channel_types: Optional[PreferenceSetChannelTypesParam] 50 | """Channel type preferences.""" 51 | 52 | workflows: Optional[Dict[str, Workflows]] 53 | """ 54 | An object where the key is the workflow key and the values are the preference 55 | settings for that workflow. 56 | """ 57 | -------------------------------------------------------------------------------- /src/knockapi/types/recipients/push_channel_data.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import List 4 | 5 | from ..._models import BaseModel 6 | 7 | __all__ = ["PushChannelData"] 8 | 9 | 10 | class PushChannelData(BaseModel): 11 | tokens: List[str] 12 | """A list of push channel tokens.""" 13 | -------------------------------------------------------------------------------- /src/knockapi/types/recipients/push_channel_data_param.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import List 6 | from typing_extensions import Required, TypedDict 7 | 8 | __all__ = ["PushChannelDataParam"] 9 | 10 | 11 | class PushChannelDataParam(TypedDict, total=False): 12 | tokens: Required[List[str]] 13 | """A list of push channel tokens.""" 14 | -------------------------------------------------------------------------------- /src/knockapi/types/recipients/slack_channel_data.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import List, Union, Optional 4 | from typing_extensions import TypeAlias 5 | 6 | from ..._models import BaseModel 7 | 8 | __all__ = [ 9 | "SlackChannelData", 10 | "Connection", 11 | "ConnectionSlackTokenConnection", 12 | "ConnectionSlackIncomingWebhookConnection", 13 | "Token", 14 | ] 15 | 16 | 17 | class ConnectionSlackTokenConnection(BaseModel): 18 | access_token: Optional[str] = None 19 | """A Slack access token.""" 20 | 21 | channel_id: Optional[str] = None 22 | """A Slack channel ID from the Slack provider.""" 23 | 24 | user_id: Optional[str] = None 25 | """A Slack user ID from the Slack provider.""" 26 | 27 | 28 | class ConnectionSlackIncomingWebhookConnection(BaseModel): 29 | url: str 30 | """The URL of the incoming webhook for a Slack connection.""" 31 | 32 | 33 | Connection: TypeAlias = Union[ConnectionSlackTokenConnection, ConnectionSlackIncomingWebhookConnection] 34 | 35 | 36 | class Token(BaseModel): 37 | access_token: Optional[str] = None 38 | """A Slack access token.""" 39 | 40 | 41 | class SlackChannelData(BaseModel): 42 | connections: List[Connection] 43 | """List of Slack channel connections.""" 44 | 45 | token: Optional[Token] = None 46 | """A Slack connection token.""" 47 | -------------------------------------------------------------------------------- /src/knockapi/types/recipients/slack_channel_data_param.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Union, Iterable, Optional 6 | from typing_extensions import Required, TypeAlias, TypedDict 7 | 8 | __all__ = [ 9 | "SlackChannelDataParam", 10 | "Connection", 11 | "ConnectionSlackTokenConnection", 12 | "ConnectionSlackIncomingWebhookConnection", 13 | "Token", 14 | ] 15 | 16 | 17 | class ConnectionSlackTokenConnection(TypedDict, total=False): 18 | access_token: Optional[str] 19 | """A Slack access token.""" 20 | 21 | channel_id: Optional[str] 22 | """A Slack channel ID from the Slack provider.""" 23 | 24 | user_id: Optional[str] 25 | """A Slack user ID from the Slack provider.""" 26 | 27 | 28 | class ConnectionSlackIncomingWebhookConnection(TypedDict, total=False): 29 | url: Required[str] 30 | """The URL of the incoming webhook for a Slack connection.""" 31 | 32 | 33 | Connection: TypeAlias = Union[ConnectionSlackTokenConnection, ConnectionSlackIncomingWebhookConnection] 34 | 35 | 36 | class Token(TypedDict, total=False): 37 | access_token: Required[Optional[str]] 38 | """A Slack access token.""" 39 | 40 | 41 | class SlackChannelDataParam(TypedDict, total=False): 42 | connections: Required[Iterable[Connection]] 43 | """List of Slack channel connections.""" 44 | 45 | token: Optional[Token] 46 | """A Slack connection token.""" 47 | -------------------------------------------------------------------------------- /src/knockapi/types/recipients/subscription.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | import builtins 4 | from typing import Dict, Optional 5 | from datetime import datetime 6 | 7 | from pydantic import Field as FieldInfo 8 | 9 | from ..object import Object 10 | from ..._models import BaseModel 11 | from ..recipient import Recipient 12 | 13 | __all__ = ["Subscription"] 14 | 15 | 16 | class Subscription(BaseModel): 17 | api_typename: str = FieldInfo(alias="__typename") 18 | """The typename of the schema.""" 19 | 20 | inserted_at: datetime 21 | """Timestamp when the resource was created.""" 22 | 23 | object: Object 24 | """A custom [Object](/concepts/objects) entity which belongs to a collection.""" 25 | 26 | recipient: Recipient 27 | """A recipient of a notification, which is either a user or an object.""" 28 | 29 | updated_at: datetime 30 | """The timestamp when the resource was last updated.""" 31 | 32 | properties: Optional[Dict[str, builtins.object]] = None 33 | """The custom properties associated with the subscription relationship.""" 34 | -------------------------------------------------------------------------------- /src/knockapi/types/schedule.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import Dict, List, Optional 4 | from datetime import datetime 5 | 6 | from pydantic import Field as FieldInfo 7 | 8 | from .._models import BaseModel 9 | from .recipient import Recipient 10 | from .schedule_repeat_rule import ScheduleRepeatRule 11 | 12 | __all__ = ["Schedule"] 13 | 14 | 15 | class Schedule(BaseModel): 16 | id: str 17 | """Unique identifier for the schedule.""" 18 | 19 | inserted_at: datetime 20 | """Timestamp when the resource was created.""" 21 | 22 | recipient: Recipient 23 | """A recipient of a notification, which is either a user or an object.""" 24 | 25 | repeats: List[ScheduleRepeatRule] 26 | """The repeat rule for the schedule.""" 27 | 28 | updated_at: datetime 29 | """The timestamp when the resource was last updated.""" 30 | 31 | workflow: str 32 | """The workflow the schedule is applied to.""" 33 | 34 | api_typename: Optional[str] = FieldInfo(alias="__typename", default=None) 35 | """The typename of the schema.""" 36 | 37 | actor: Optional[Recipient] = None 38 | """A recipient of a notification, which is either a user or an object.""" 39 | 40 | data: Optional[Dict[str, object]] = None 41 | """An optional map of data to pass into the workflow execution. 42 | 43 | There is a 1024 byte limit on the size of any single string value (with the 44 | exception of [email attachments](/integrations/email/attachments)), and a 10MB 45 | limit on the size of the full `data` payload. 46 | """ 47 | 48 | last_occurrence_at: Optional[datetime] = None 49 | """The last occurrence of the schedule.""" 50 | 51 | next_occurrence_at: Optional[datetime] = None 52 | """The next occurrence of the schedule.""" 53 | 54 | tenant: Optional[str] = None 55 | """The tenant to trigger the workflow for. 56 | 57 | Triggering with a tenant will use any tenant-level overrides associated with the 58 | tenant object, and all messages produced from workflow runs will be tagged with 59 | the tenant. 60 | """ 61 | -------------------------------------------------------------------------------- /src/knockapi/types/schedule_create_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Dict, List, Union, Iterable, Optional 6 | from datetime import datetime 7 | from typing_extensions import Required, Annotated, TypedDict 8 | 9 | from .._utils import PropertyInfo 10 | from .recipient_request_param import RecipientRequestParam 11 | from .schedule_repeat_rule_param import ScheduleRepeatRuleParam 12 | from .inline_tenant_request_param import InlineTenantRequestParam 13 | 14 | __all__ = ["ScheduleCreateParams"] 15 | 16 | 17 | class ScheduleCreateParams(TypedDict, total=False): 18 | recipients: Required[List[RecipientRequestParam]] 19 | """The recipients to set the schedule for. Limited to 100 recipients per request.""" 20 | 21 | workflow: Required[str] 22 | """The key of the workflow.""" 23 | 24 | actor: Optional[RecipientRequestParam] 25 | """Specifies a recipient in a request. 26 | 27 | This can either be a user identifier (string), an inline user request (object), 28 | or an inline object request, which is determined by the presence of a 29 | `collection` property. 30 | """ 31 | 32 | data: Optional[Dict[str, object]] 33 | """An optional map of data to pass into the workflow execution. 34 | 35 | There is a 1024 byte limit on the size of any single string value (with the 36 | exception of [email attachments](/integrations/email/attachments)), and a 10MB 37 | limit on the size of the full `data` payload. 38 | """ 39 | 40 | ending_at: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")] 41 | """The ending date and time for the schedule.""" 42 | 43 | repeats: Iterable[ScheduleRepeatRuleParam] 44 | """The repeat rule for the schedule.""" 45 | 46 | scheduled_at: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")] 47 | """The starting date and time for the schedule.""" 48 | 49 | tenant: Optional[InlineTenantRequestParam] 50 | """An request to set a tenant inline.""" 51 | -------------------------------------------------------------------------------- /src/knockapi/types/schedule_create_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import List 4 | from typing_extensions import TypeAlias 5 | 6 | from .schedule import Schedule 7 | 8 | __all__ = ["ScheduleCreateResponse"] 9 | 10 | ScheduleCreateResponse: TypeAlias = List[Schedule] 11 | -------------------------------------------------------------------------------- /src/knockapi/types/schedule_delete_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import List 6 | from typing_extensions import Required, TypedDict 7 | 8 | __all__ = ["ScheduleDeleteParams"] 9 | 10 | 11 | class ScheduleDeleteParams(TypedDict, total=False): 12 | schedule_ids: Required[List[str]] 13 | """A list of schedule IDs.""" 14 | -------------------------------------------------------------------------------- /src/knockapi/types/schedule_delete_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import List 4 | from typing_extensions import TypeAlias 5 | 6 | from .schedule import Schedule 7 | 8 | __all__ = ["ScheduleDeleteResponse"] 9 | 10 | ScheduleDeleteResponse: TypeAlias = List[Schedule] 11 | -------------------------------------------------------------------------------- /src/knockapi/types/schedule_list_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import List 6 | from typing_extensions import Required, TypedDict 7 | 8 | from .recipient_reference_param import RecipientReferenceParam 9 | 10 | __all__ = ["ScheduleListParams"] 11 | 12 | 13 | class ScheduleListParams(TypedDict, total=False): 14 | workflow: Required[str] 15 | """Filter by workflow key.""" 16 | 17 | after: str 18 | """The cursor to fetch entries after.""" 19 | 20 | before: str 21 | """The cursor to fetch entries before.""" 22 | 23 | page_size: int 24 | """The number of items per page.""" 25 | 26 | recipients: List[RecipientReferenceParam] 27 | """Filter by recipient references.""" 28 | 29 | tenant: str 30 | """Filter by tenant ID.""" 31 | -------------------------------------------------------------------------------- /src/knockapi/types/schedule_repeat_rule.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import List, Optional 4 | from typing_extensions import Literal 5 | 6 | from pydantic import Field as FieldInfo 7 | 8 | from .._models import BaseModel 9 | 10 | __all__ = ["ScheduleRepeatRule"] 11 | 12 | 13 | class ScheduleRepeatRule(BaseModel): 14 | frequency: Literal["daily", "weekly", "monthly", "hourly"] 15 | """The frequency of the schedule.""" 16 | 17 | api_typename: Optional[str] = FieldInfo(alias="__typename", default=None) 18 | """The typename of the schema.""" 19 | 20 | day_of_month: Optional[int] = None 21 | """The day of the month to repeat the schedule.""" 22 | 23 | days: Optional[List[Literal["mon", "tue", "wed", "thu", "fri", "sat", "sun"]]] = None 24 | """The days of the week to repeat the schedule.""" 25 | 26 | hours: Optional[int] = None 27 | """The hour of the day to repeat the schedule.""" 28 | 29 | interval: Optional[int] = None 30 | """The interval of the schedule.""" 31 | 32 | minutes: Optional[int] = None 33 | """The minute of the hour to repeat the schedule.""" 34 | -------------------------------------------------------------------------------- /src/knockapi/types/schedule_repeat_rule_param.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import List, Optional 6 | from typing_extensions import Literal, Required, Annotated, TypedDict 7 | 8 | from .._utils import PropertyInfo 9 | 10 | __all__ = ["ScheduleRepeatRuleParam"] 11 | 12 | 13 | class ScheduleRepeatRuleParam(TypedDict, total=False): 14 | frequency: Required[Literal["daily", "weekly", "monthly", "hourly"]] 15 | """The frequency of the schedule.""" 16 | 17 | _typename: Annotated[str, PropertyInfo(alias="__typename")] 18 | """The typename of the schema.""" 19 | 20 | day_of_month: Optional[int] 21 | """The day of the month to repeat the schedule.""" 22 | 23 | days: Optional[List[Literal["mon", "tue", "wed", "thu", "fri", "sat", "sun"]]] 24 | """The days of the week to repeat the schedule.""" 25 | 26 | hours: Optional[int] 27 | """The hour of the day to repeat the schedule.""" 28 | 29 | interval: int 30 | """The interval of the schedule.""" 31 | 32 | minutes: Optional[int] 33 | """The minute of the hour to repeat the schedule.""" 34 | -------------------------------------------------------------------------------- /src/knockapi/types/schedule_update_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Dict, List, Union, Iterable, Optional 6 | from datetime import datetime 7 | from typing_extensions import Required, Annotated, TypedDict 8 | 9 | from .._utils import PropertyInfo 10 | from .recipient_reference_param import RecipientReferenceParam 11 | from .schedule_repeat_rule_param import ScheduleRepeatRuleParam 12 | from .inline_tenant_request_param import InlineTenantRequestParam 13 | 14 | __all__ = ["ScheduleUpdateParams"] 15 | 16 | 17 | class ScheduleUpdateParams(TypedDict, total=False): 18 | schedule_ids: Required[List[str]] 19 | """A list of schedule IDs.""" 20 | 21 | actor: Optional[RecipientReferenceParam] 22 | """ 23 | A reference to a recipient, either a user identifier (string) or an object 24 | reference (ID, collection). 25 | """ 26 | 27 | data: Optional[Dict[str, object]] 28 | """An optional map of data to pass into the workflow execution. 29 | 30 | There is a 1024 byte limit on the size of any single string value (with the 31 | exception of [email attachments](/integrations/email/attachments)), and a 10MB 32 | limit on the size of the full `data` payload. 33 | """ 34 | 35 | ending_at: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")] 36 | """The ending date and time for the schedule.""" 37 | 38 | repeats: Iterable[ScheduleRepeatRuleParam] 39 | """The repeat rule for the schedule.""" 40 | 41 | scheduled_at: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")] 42 | """The starting date and time for the schedule.""" 43 | 44 | tenant: Optional[InlineTenantRequestParam] 45 | """An request to set a tenant inline.""" 46 | -------------------------------------------------------------------------------- /src/knockapi/types/schedule_update_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import List 4 | from typing_extensions import TypeAlias 5 | 6 | from .schedule import Schedule 7 | 8 | __all__ = ["ScheduleUpdateResponse"] 9 | 10 | ScheduleUpdateResponse: TypeAlias = List[Schedule] 11 | -------------------------------------------------------------------------------- /src/knockapi/types/schedules/__init__.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from .bulk_create_params import BulkCreateParams as BulkCreateParams 6 | -------------------------------------------------------------------------------- /src/knockapi/types/schedules/bulk_create_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Dict, Union, Iterable, Optional 6 | from datetime import datetime 7 | from typing_extensions import Required, Annotated, TypedDict 8 | 9 | from ..._utils import PropertyInfo 10 | from ..recipient_request_param import RecipientRequestParam 11 | from ..schedule_repeat_rule_param import ScheduleRepeatRuleParam 12 | from ..inline_tenant_request_param import InlineTenantRequestParam 13 | 14 | __all__ = ["BulkCreateParams", "Schedule"] 15 | 16 | 17 | class BulkCreateParams(TypedDict, total=False): 18 | schedules: Required[Iterable[Schedule]] 19 | """A list of schedules.""" 20 | 21 | 22 | class Schedule(TypedDict, total=False): 23 | workflow: Required[str] 24 | """The key of the workflow.""" 25 | 26 | actor: Optional[RecipientRequestParam] 27 | """Specifies a recipient in a request. 28 | 29 | This can either be a user identifier (string), an inline user request (object), 30 | or an inline object request, which is determined by the presence of a 31 | `collection` property. 32 | """ 33 | 34 | data: Optional[Dict[str, object]] 35 | """An optional map of data to pass into the workflow execution. 36 | 37 | There is a 1024 byte limit on the size of any single string value (with the 38 | exception of [email attachments](/integrations/email/attachments)), and a 10MB 39 | limit on the size of the full `data` payload. 40 | """ 41 | 42 | ending_at: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")] 43 | """The ending date and time for the schedule.""" 44 | 45 | recipient: RecipientRequestParam 46 | """Specifies a recipient in a request. 47 | 48 | This can either be a user identifier (string), an inline user request (object), 49 | or an inline object request, which is determined by the presence of a 50 | `collection` property. 51 | """ 52 | 53 | repeats: Iterable[ScheduleRepeatRuleParam] 54 | """The repeat rule for the schedule.""" 55 | 56 | scheduled_at: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")] 57 | """The starting date and time for the schedule.""" 58 | 59 | tenant: Optional[InlineTenantRequestParam] 60 | """An request to set a tenant inline.""" 61 | -------------------------------------------------------------------------------- /src/knockapi/types/tenant.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import TYPE_CHECKING, Optional 4 | 5 | from pydantic import Field as FieldInfo 6 | 7 | from .._models import BaseModel 8 | from .recipients.preference_set import PreferenceSet 9 | 10 | __all__ = ["Tenant", "Settings", "SettingsBranding"] 11 | 12 | 13 | class SettingsBranding(BaseModel): 14 | icon_url: Optional[str] = None 15 | """The icon URL for the tenant. 16 | 17 | Must point to a valid image with an image MIME type. 18 | """ 19 | 20 | logo_url: Optional[str] = None 21 | """The logo URL for the tenant. 22 | 23 | Must point to a valid image with an image MIME type. 24 | """ 25 | 26 | primary_color: Optional[str] = None 27 | """The primary color for the tenant, provided as a hex value.""" 28 | 29 | primary_color_contrast: Optional[str] = None 30 | """The primary color contrast for the tenant, provided as a hex value.""" 31 | 32 | 33 | class Settings(BaseModel): 34 | branding: Optional[SettingsBranding] = None 35 | """The branding for the tenant.""" 36 | 37 | preference_set: Optional[PreferenceSet] = None 38 | """ 39 | A preference set represents a specific set of notification preferences for a 40 | recipient. A recipient can have multiple preference sets. 41 | """ 42 | 43 | 44 | class Tenant(BaseModel): 45 | id: str 46 | """The unique identifier for the tenant.""" 47 | 48 | api_typename: str = FieldInfo(alias="__typename") 49 | """The typename of the schema.""" 50 | 51 | name: Optional[str] = None 52 | """An optional name for the tenant.""" 53 | 54 | settings: Optional[Settings] = None 55 | """The settings for the tenant. Includes branding and preference set.""" 56 | 57 | if TYPE_CHECKING: 58 | # Stub to indicate that arbitrary properties are accepted. 59 | # To access properties that are not valid identifiers you can use `getattr`, e.g. 60 | # `getattr(obj, '$type')` 61 | def __getattr__(self, attr: str) -> object: ... 62 | -------------------------------------------------------------------------------- /src/knockapi/types/tenant_delete_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing_extensions import TypeAlias 4 | 5 | __all__ = ["TenantDeleteResponse"] 6 | 7 | TenantDeleteResponse: TypeAlias = str 8 | -------------------------------------------------------------------------------- /src/knockapi/types/tenant_list_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing_extensions import TypedDict 6 | 7 | __all__ = ["TenantListParams"] 8 | 9 | 10 | class TenantListParams(TypedDict, total=False): 11 | after: str 12 | """The cursor to fetch entries after.""" 13 | 14 | before: str 15 | """The cursor to fetch entries before.""" 16 | 17 | name: str 18 | """Filter tenants by name.""" 19 | 20 | page_size: int 21 | """The number of items per page.""" 22 | 23 | tenant_id: str 24 | """Filter tenants by ID.""" 25 | -------------------------------------------------------------------------------- /src/knockapi/types/tenant_request_param.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Dict, Union, Optional 6 | from typing_extensions import Required, TypeAlias, TypedDict 7 | 8 | from .recipients.preference_set_request_param import PreferenceSetRequestParam 9 | from .recipients.inline_channel_data_request_param import InlineChannelDataRequestParam 10 | from .recipients.inline_preference_set_request_param import InlinePreferenceSetRequestParam 11 | 12 | __all__ = ["TenantRequestParam", "Settings", "SettingsBranding"] 13 | 14 | 15 | class SettingsBranding(TypedDict, total=False): 16 | icon_url: Optional[str] 17 | """The icon URL for the tenant. 18 | 19 | Must point to a valid image with an image MIME type. 20 | """ 21 | 22 | logo_url: Optional[str] 23 | """The logo URL for the tenant. 24 | 25 | Must point to a valid image with an image MIME type. 26 | """ 27 | 28 | primary_color: Optional[str] 29 | """The primary color for the tenant, provided as a hex value.""" 30 | 31 | primary_color_contrast: Optional[str] 32 | """The primary color contrast for the tenant, provided as a hex value.""" 33 | 34 | 35 | class Settings(TypedDict, total=False): 36 | branding: SettingsBranding 37 | """The branding for the tenant.""" 38 | 39 | preference_set: Optional[PreferenceSetRequestParam] 40 | """A request to set a preference set for a recipient.""" 41 | 42 | 43 | class TenantRequestParamTyped(TypedDict, total=False): 44 | id: Required[str] 45 | """The unique identifier for the tenant.""" 46 | 47 | channel_data: Optional[InlineChannelDataRequestParam] 48 | """A request to set channel data for a type of channel inline.""" 49 | 50 | preferences: Optional[InlinePreferenceSetRequestParam] 51 | """Inline set preferences for a recipient, where the key is the preference set id.""" 52 | 53 | settings: Settings 54 | """The settings for the tenant. Includes branding and preference set.""" 55 | 56 | 57 | TenantRequestParam: TypeAlias = Union[TenantRequestParamTyped, Dict[str, object]] 58 | -------------------------------------------------------------------------------- /src/knockapi/types/tenant_set_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Optional 6 | from typing_extensions import TypedDict 7 | 8 | from .recipients.preference_set_request_param import PreferenceSetRequestParam 9 | from .recipients.inline_channel_data_request_param import InlineChannelDataRequestParam 10 | 11 | __all__ = ["TenantSetParams", "Settings", "SettingsBranding"] 12 | 13 | 14 | class TenantSetParams(TypedDict, total=False): 15 | channel_data: Optional[InlineChannelDataRequestParam] 16 | """A request to set channel data for a type of channel inline.""" 17 | 18 | settings: Settings 19 | """The settings for the tenant. Includes branding and preference set.""" 20 | 21 | 22 | class SettingsBranding(TypedDict, total=False): 23 | icon_url: Optional[str] 24 | """The icon URL for the tenant. 25 | 26 | Must point to a valid image with an image MIME type. 27 | """ 28 | 29 | logo_url: Optional[str] 30 | """The logo URL for the tenant. 31 | 32 | Must point to a valid image with an image MIME type. 33 | """ 34 | 35 | primary_color: Optional[str] 36 | """The primary color for the tenant, provided as a hex value.""" 37 | 38 | primary_color_contrast: Optional[str] 39 | """The primary color contrast for the tenant, provided as a hex value.""" 40 | 41 | 42 | class Settings(TypedDict, total=False): 43 | branding: SettingsBranding 44 | """The branding for the tenant.""" 45 | 46 | preference_set: Optional[PreferenceSetRequestParam] 47 | """A request to set a preference set for a recipient.""" 48 | -------------------------------------------------------------------------------- /src/knockapi/types/tenants/__init__.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from .bulk_set_params import BulkSetParams as BulkSetParams 6 | from .bulk_delete_params import BulkDeleteParams as BulkDeleteParams 7 | -------------------------------------------------------------------------------- /src/knockapi/types/tenants/bulk_delete_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import List 6 | from typing_extensions import Required, TypedDict 7 | 8 | __all__ = ["BulkDeleteParams"] 9 | 10 | 11 | class BulkDeleteParams(TypedDict, total=False): 12 | tenant_ids: Required[List[str]] 13 | """The IDs of the tenants to delete.""" 14 | -------------------------------------------------------------------------------- /src/knockapi/types/tenants/bulk_set_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import List 6 | from typing_extensions import Required, TypedDict 7 | 8 | from ..inline_tenant_request_param import InlineTenantRequestParam 9 | 10 | __all__ = ["BulkSetParams"] 11 | 12 | 13 | class BulkSetParams(TypedDict, total=False): 14 | tenants: Required[List[InlineTenantRequestParam]] 15 | """The tenants to be upserted.""" 16 | -------------------------------------------------------------------------------- /src/knockapi/types/user.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import TYPE_CHECKING, Optional 4 | from datetime import datetime 5 | 6 | from pydantic import Field as FieldInfo 7 | 8 | from .._models import BaseModel 9 | 10 | __all__ = ["User"] 11 | 12 | 13 | class User(BaseModel): 14 | id: str 15 | """The ID for the user that you set when identifying them in Knock.""" 16 | 17 | api_typename: str = FieldInfo(alias="__typename") 18 | """The typename of the schema.""" 19 | 20 | updated_at: datetime 21 | """The timestamp when the resource was last updated.""" 22 | 23 | avatar: Optional[str] = None 24 | """URL to the user's avatar image.""" 25 | 26 | created_at: Optional[datetime] = None 27 | """The creation date of the user from your system.""" 28 | 29 | email: Optional[str] = None 30 | """The primary email address for the user.""" 31 | 32 | name: Optional[str] = None 33 | """Display name of the user.""" 34 | 35 | phone_number: Optional[str] = None 36 | """ 37 | The [E.164](https://www.twilio.com/docs/glossary/what-e164) phone number of the 38 | user (required for SMS channels). 39 | """ 40 | 41 | timezone: Optional[str] = None 42 | """The timezone of the user. 43 | 44 | Must be a 45 | valid [tz database time zone string](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). 46 | Used 47 | for [recurring schedules](/concepts/schedules#scheduling-workflows-with-recurring-schedules-for-recipients). 48 | """ 49 | 50 | if TYPE_CHECKING: 51 | # Stub to indicate that arbitrary properties are accepted. 52 | # To access properties that are not valid identifiers you can use `getattr`, e.g. 53 | # `getattr(obj, '$type')` 54 | def __getattr__(self, attr: str) -> object: ... 55 | -------------------------------------------------------------------------------- /src/knockapi/types/user_delete_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing_extensions import TypeAlias 4 | 5 | __all__ = ["UserDeleteResponse"] 6 | 7 | UserDeleteResponse: TypeAlias = str 8 | -------------------------------------------------------------------------------- /src/knockapi/types/user_get_preferences_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing_extensions import TypedDict 6 | 7 | __all__ = ["UserGetPreferencesParams"] 8 | 9 | 10 | class UserGetPreferencesParams(TypedDict, total=False): 11 | tenant: str 12 | """The unique identifier for the tenant.""" 13 | -------------------------------------------------------------------------------- /src/knockapi/types/user_list_messages_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import List 6 | from typing_extensions import Literal, TypedDict 7 | 8 | __all__ = ["UserListMessagesParams", "InsertedAt"] 9 | 10 | 11 | class UserListMessagesParams(TypedDict, total=False): 12 | after: str 13 | """The cursor to fetch entries after.""" 14 | 15 | before: str 16 | """The cursor to fetch entries before.""" 17 | 18 | channel_id: str 19 | """Limits the results to items with the corresponding channel ID.""" 20 | 21 | engagement_status: List[ 22 | Literal["seen", "unseen", "read", "unread", "archived", "unarchived", "link_clicked", "interacted"] 23 | ] 24 | """Limits the results to messages with the given engagement status.""" 25 | 26 | inserted_at: InsertedAt 27 | 28 | message_ids: List[str] 29 | """Limits the results to only the message IDs given (max 50). 30 | 31 | Note: when using this option, the results will be subject to any other filters 32 | applied to the query. 33 | """ 34 | 35 | page_size: int 36 | """The number of items per page.""" 37 | 38 | source: str 39 | """Limits the results to messages triggered by the given workflow key.""" 40 | 41 | status: List[Literal["queued", "sent", "delivered", "delivery_attempted", "undelivered", "not_sent", "bounced"]] 42 | """Limits the results to messages with the given delivery status.""" 43 | 44 | tenant: str 45 | """Limits the results to items with the corresponding tenant.""" 46 | 47 | trigger_data: str 48 | """Limits the results to only messages that were generated with the given data. 49 | 50 | See [trigger data filtering](/api-reference/overview/trigger-data-filtering) for 51 | more information. 52 | """ 53 | 54 | workflow_categories: List[str] 55 | """Limits the results to messages related to any of the provided categories.""" 56 | 57 | workflow_recipient_run_id: str 58 | """Limits the results to messages for a specific recipient's workflow run.""" 59 | 60 | workflow_run_id: str 61 | """ 62 | Limits the results to messages associated with the top-level workflow run ID 63 | returned by the workflow trigger request. 64 | """ 65 | 66 | 67 | class InsertedAt(TypedDict, total=False): 68 | gt: str 69 | """Limits the results to messages inserted after the given date.""" 70 | 71 | gte: str 72 | """Limits the results to messages inserted after or on the given date.""" 73 | 74 | lt: str 75 | """Limits the results to messages inserted before the given date.""" 76 | 77 | lte: str 78 | """Limits the results to messages inserted before or on the given date.""" 79 | -------------------------------------------------------------------------------- /src/knockapi/types/user_list_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import List 6 | from typing_extensions import Literal, TypedDict 7 | 8 | __all__ = ["UserListParams"] 9 | 10 | 11 | class UserListParams(TypedDict, total=False): 12 | after: str 13 | """The cursor to fetch entries after.""" 14 | 15 | before: str 16 | """The cursor to fetch entries before.""" 17 | 18 | include: List[Literal["preferences"]] 19 | """Associated resources to include in the response.""" 20 | 21 | page_size: int 22 | """The number of items per page.""" 23 | -------------------------------------------------------------------------------- /src/knockapi/types/user_list_preferences_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import List 4 | from typing_extensions import TypeAlias 5 | 6 | from .recipients.preference_set import PreferenceSet 7 | 8 | __all__ = ["UserListPreferencesResponse"] 9 | 10 | UserListPreferencesResponse: TypeAlias = List[PreferenceSet] 11 | -------------------------------------------------------------------------------- /src/knockapi/types/user_list_schedules_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing_extensions import TypedDict 6 | 7 | __all__ = ["UserListSchedulesParams"] 8 | 9 | 10 | class UserListSchedulesParams(TypedDict, total=False): 11 | after: str 12 | """The cursor to fetch entries after.""" 13 | 14 | before: str 15 | """The cursor to fetch entries before.""" 16 | 17 | page_size: int 18 | """The number of items per page.""" 19 | 20 | tenant: str 21 | """The tenant ID to filter schedules for.""" 22 | 23 | workflow: str 24 | """The workflow key to filter schedules for.""" 25 | -------------------------------------------------------------------------------- /src/knockapi/types/user_list_subscriptions_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import List 6 | from typing_extensions import Literal, TypedDict 7 | 8 | from .recipient_reference_param import RecipientReferenceParam 9 | 10 | __all__ = ["UserListSubscriptionsParams"] 11 | 12 | 13 | class UserListSubscriptionsParams(TypedDict, total=False): 14 | after: str 15 | """The cursor to fetch entries after.""" 16 | 17 | before: str 18 | """The cursor to fetch entries before.""" 19 | 20 | include: List[Literal["preferences"]] 21 | """Associated resources to include in the response.""" 22 | 23 | objects: List[RecipientReferenceParam] 24 | """Only returns subscriptions for the specified object references.""" 25 | 26 | page_size: int 27 | """The number of items per page.""" 28 | -------------------------------------------------------------------------------- /src/knockapi/types/user_merge_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing_extensions import Required, TypedDict 6 | 7 | __all__ = ["UserMergeParams"] 8 | 9 | 10 | class UserMergeParams(TypedDict, total=False): 11 | from_user_id: Required[str] 12 | """The user ID to merge from.""" 13 | -------------------------------------------------------------------------------- /src/knockapi/types/user_set_channel_data_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Union 6 | from typing_extensions import Required, TypeAlias, TypedDict 7 | 8 | from .recipients.push_channel_data_param import PushChannelDataParam 9 | from .recipients.slack_channel_data_param import SlackChannelDataParam 10 | from .recipients.discord_channel_data_param import DiscordChannelDataParam 11 | from .recipients.ms_teams_channel_data_param import MsTeamsChannelDataParam 12 | from .recipients.one_signal_channel_data_param import OneSignalChannelDataParam 13 | 14 | __all__ = ["UserSetChannelDataParams", "Data"] 15 | 16 | 17 | class UserSetChannelDataParams(TypedDict, total=False): 18 | data: Required[Data] 19 | """Channel data for a given channel type.""" 20 | 21 | 22 | Data: TypeAlias = Union[ 23 | PushChannelDataParam, 24 | OneSignalChannelDataParam, 25 | SlackChannelDataParam, 26 | MsTeamsChannelDataParam, 27 | DiscordChannelDataParam, 28 | ] 29 | -------------------------------------------------------------------------------- /src/knockapi/types/user_set_preferences_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Dict, Union, Iterable, Optional 6 | from typing_extensions import TypeAlias, TypedDict 7 | 8 | from .condition_param import ConditionParam 9 | from .recipients.preference_set_channel_types_param import PreferenceSetChannelTypesParam 10 | 11 | __all__ = [ 12 | "UserSetPreferencesParams", 13 | "Categories", 14 | "CategoriesPreferenceSetWorkflowCategorySettingObject", 15 | "Workflows", 16 | "WorkflowsPreferenceSetWorkflowCategorySettingObject", 17 | ] 18 | 19 | 20 | class UserSetPreferencesParams(TypedDict, total=False): 21 | categories: Optional[Dict[str, Categories]] 22 | """ 23 | An object where the key is the category and the values are the preference 24 | settings for that category. 25 | """ 26 | 27 | channel_types: Optional[PreferenceSetChannelTypesParam] 28 | """Channel type preferences.""" 29 | 30 | workflows: Optional[Dict[str, Workflows]] 31 | """ 32 | An object where the key is the workflow key and the values are the preference 33 | settings for that workflow. 34 | """ 35 | 36 | 37 | class CategoriesPreferenceSetWorkflowCategorySettingObject(TypedDict, total=False): 38 | channel_types: Optional[PreferenceSetChannelTypesParam] 39 | """Channel type preferences.""" 40 | 41 | conditions: Optional[Iterable[ConditionParam]] 42 | """A list of conditions to apply to a channel type.""" 43 | 44 | 45 | Categories: TypeAlias = Union[bool, CategoriesPreferenceSetWorkflowCategorySettingObject] 46 | 47 | 48 | class WorkflowsPreferenceSetWorkflowCategorySettingObject(TypedDict, total=False): 49 | channel_types: Optional[PreferenceSetChannelTypesParam] 50 | """Channel type preferences.""" 51 | 52 | conditions: Optional[Iterable[ConditionParam]] 53 | """A list of conditions to apply to a channel type.""" 54 | 55 | 56 | Workflows: TypeAlias = Union[bool, WorkflowsPreferenceSetWorkflowCategorySettingObject] 57 | -------------------------------------------------------------------------------- /src/knockapi/types/user_unset_channel_data_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing_extensions import TypeAlias 4 | 5 | __all__ = ["UserUnsetChannelDataResponse"] 6 | 7 | UserUnsetChannelDataResponse: TypeAlias = str 8 | -------------------------------------------------------------------------------- /src/knockapi/types/user_update_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Union, Optional 6 | from datetime import datetime 7 | from typing_extensions import Annotated, TypedDict 8 | 9 | from .._utils import PropertyInfo 10 | from .recipients.inline_channel_data_request_param import InlineChannelDataRequestParam 11 | from .recipients.inline_preference_set_request_param import InlinePreferenceSetRequestParam 12 | 13 | __all__ = ["UserUpdateParams"] 14 | 15 | 16 | class UserUpdateParams(TypedDict, total=False): 17 | avatar: Optional[str] 18 | """URL to the user's avatar image.""" 19 | 20 | channel_data: Optional[InlineChannelDataRequestParam] 21 | """A request to set channel data for a type of channel inline.""" 22 | 23 | created_at: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")] 24 | """The creation date of the user from your system.""" 25 | 26 | email: Optional[str] 27 | """The primary email address for the user.""" 28 | 29 | locale: Optional[str] 30 | """The locale of the user. 31 | 32 | Used for [message localization](/concepts/translations). 33 | """ 34 | 35 | name: Optional[str] 36 | """Display name of the user.""" 37 | 38 | phone_number: Optional[str] 39 | """ 40 | The [E.164](https://www.twilio.com/docs/glossary/what-e164) phone number of the 41 | user (required for SMS channels). 42 | """ 43 | 44 | preferences: Optional[InlinePreferenceSetRequestParam] 45 | """Inline set preferences for a recipient, where the key is the preference set id.""" 46 | 47 | timezone: Optional[str] 48 | """The timezone of the user. 49 | 50 | Must be a 51 | valid [tz database time zone string](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). 52 | Used 53 | for [recurring schedules](/concepts/schedules#scheduling-workflows-with-recurring-schedules-for-recipients). 54 | """ 55 | -------------------------------------------------------------------------------- /src/knockapi/types/users/__init__.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from .bulk_delete_params import BulkDeleteParams as BulkDeleteParams 6 | from .bulk_identify_params import BulkIdentifyParams as BulkIdentifyParams 7 | from .feed_list_items_params import FeedListItemsParams as FeedListItemsParams 8 | from .feed_list_items_response import FeedListItemsResponse as FeedListItemsResponse 9 | from .guide_get_channel_params import GuideGetChannelParams as GuideGetChannelParams 10 | from .feed_get_settings_response import FeedGetSettingsResponse as FeedGetSettingsResponse 11 | from .guide_get_channel_response import GuideGetChannelResponse as GuideGetChannelResponse 12 | from .bulk_set_preferences_params import BulkSetPreferencesParams as BulkSetPreferencesParams 13 | from .guide_mark_message_as_seen_params import GuideMarkMessageAsSeenParams as GuideMarkMessageAsSeenParams 14 | from .guide_mark_message_as_seen_response import GuideMarkMessageAsSeenResponse as GuideMarkMessageAsSeenResponse 15 | from .guide_mark_message_as_archived_params import GuideMarkMessageAsArchivedParams as GuideMarkMessageAsArchivedParams 16 | from .guide_mark_message_as_archived_response import ( 17 | GuideMarkMessageAsArchivedResponse as GuideMarkMessageAsArchivedResponse, 18 | ) 19 | from .guide_mark_message_as_interacted_params import ( 20 | GuideMarkMessageAsInteractedParams as GuideMarkMessageAsInteractedParams, 21 | ) 22 | from .guide_mark_message_as_interacted_response import ( 23 | GuideMarkMessageAsInteractedResponse as GuideMarkMessageAsInteractedResponse, 24 | ) 25 | -------------------------------------------------------------------------------- /src/knockapi/types/users/bulk_delete_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import List 6 | from typing_extensions import Required, TypedDict 7 | 8 | __all__ = ["BulkDeleteParams"] 9 | 10 | 11 | class BulkDeleteParams(TypedDict, total=False): 12 | user_ids: Required[List[str]] 13 | """A list of user IDs.""" 14 | -------------------------------------------------------------------------------- /src/knockapi/types/users/bulk_identify_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Iterable 6 | from typing_extensions import Required, TypedDict 7 | 8 | from ..inline_identify_user_request_param import InlineIdentifyUserRequestParam 9 | 10 | __all__ = ["BulkIdentifyParams"] 11 | 12 | 13 | class BulkIdentifyParams(TypedDict, total=False): 14 | users: Required[Iterable[InlineIdentifyUserRequestParam]] 15 | """A list of users.""" 16 | -------------------------------------------------------------------------------- /src/knockapi/types/users/bulk_set_preferences_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import List 6 | from typing_extensions import Required, TypedDict 7 | 8 | from ..recipients.preference_set_request_param import PreferenceSetRequestParam 9 | 10 | __all__ = ["BulkSetPreferencesParams"] 11 | 12 | 13 | class BulkSetPreferencesParams(TypedDict, total=False): 14 | preferences: Required[PreferenceSetRequestParam] 15 | """A request to set a preference set for a recipient.""" 16 | 17 | user_ids: Required[List[str]] 18 | """A list of user IDs.""" 19 | -------------------------------------------------------------------------------- /src/knockapi/types/users/feed_get_settings_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from ..._models import BaseModel 4 | 5 | __all__ = ["FeedGetSettingsResponse", "Features"] 6 | 7 | 8 | class Features(BaseModel): 9 | branding_required: bool 10 | """Whether branding is required for the user's feed.""" 11 | 12 | 13 | class FeedGetSettingsResponse(BaseModel): 14 | features: Features 15 | """Features configuration for the user's feed.""" 16 | -------------------------------------------------------------------------------- /src/knockapi/types/users/feed_list_items_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import List 6 | from typing_extensions import Literal, TypedDict 7 | 8 | __all__ = ["FeedListItemsParams"] 9 | 10 | 11 | class FeedListItemsParams(TypedDict, total=False): 12 | after: str 13 | """The cursor to fetch entries after.""" 14 | 15 | archived: Literal["exclude", "include", "only"] 16 | """The archived status of the feed items.""" 17 | 18 | before: str 19 | """The cursor to fetch entries before.""" 20 | 21 | has_tenant: bool 22 | """Whether the feed items have a tenant.""" 23 | 24 | page_size: int 25 | """The number of items per page.""" 26 | 27 | source: str 28 | """The source of the feed items.""" 29 | 30 | status: Literal["unread", "read", "unseen", "seen", "all"] 31 | """The status of the feed items.""" 32 | 33 | tenant: str 34 | """The tenant associated with the feed items.""" 35 | 36 | trigger_data: str 37 | """The trigger data of the feed items (as a JSON string).""" 38 | 39 | workflow_categories: List[str] 40 | """The workflow categories of the feed items.""" 41 | -------------------------------------------------------------------------------- /src/knockapi/types/users/guide_get_channel_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing_extensions import TypedDict 6 | 7 | __all__ = ["GuideGetChannelParams"] 8 | 9 | 10 | class GuideGetChannelParams(TypedDict, total=False): 11 | data: str 12 | """The data (JSON encoded object) to use for targeting and rendering guides.""" 13 | 14 | tenant: str 15 | """The tenant ID to use for targeting and rendering guides.""" 16 | 17 | type: str 18 | """The type of guides to filter by.""" 19 | -------------------------------------------------------------------------------- /src/knockapi/types/users/guide_get_channel_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing import Dict, List, Optional 4 | 5 | from ..._models import BaseModel 6 | 7 | __all__ = ["GuideGetChannelResponse", "Guide", "Recipient"] 8 | 9 | 10 | class Guide(BaseModel): 11 | id: Optional[str] = None 12 | """The unique identifier for the guide.""" 13 | 14 | content: Optional[str] = None 15 | """The content of the guide.""" 16 | 17 | metadata: Optional[Dict[str, object]] = None 18 | """The metadata of the guide.""" 19 | 20 | title: Optional[str] = None 21 | """The title of the guide.""" 22 | 23 | 24 | class Recipient(BaseModel): 25 | id: Optional[str] = None 26 | """Unique identifier for the recipient.""" 27 | 28 | 29 | class GuideGetChannelResponse(BaseModel): 30 | guides: List[Guide] 31 | """A list of guides.""" 32 | 33 | recipient: Optional[Recipient] = None 34 | """The recipient of the guide.""" 35 | -------------------------------------------------------------------------------- /src/knockapi/types/users/guide_mark_message_as_archived_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Dict, Optional 6 | from typing_extensions import Required, TypedDict 7 | 8 | __all__ = ["GuideMarkMessageAsArchivedParams"] 9 | 10 | 11 | class GuideMarkMessageAsArchivedParams(TypedDict, total=False): 12 | channel_id: Required[str] 13 | """The unique identifier for the channel.""" 14 | 15 | guide_id: Required[str] 16 | """The unique identifier for the guide.""" 17 | 18 | guide_key: Required[str] 19 | """The key of the guide.""" 20 | 21 | guide_step_ref: Required[str] 22 | """The step reference of the guide.""" 23 | 24 | content: Dict[str, object] 25 | """The content of the guide.""" 26 | 27 | data: Dict[str, object] 28 | """The data of the guide.""" 29 | 30 | is_final: bool 31 | """Whether the guide is final.""" 32 | 33 | metadata: Dict[str, object] 34 | """The metadata of the guide.""" 35 | 36 | tenant: Optional[str] 37 | """The tenant ID of the guide.""" 38 | -------------------------------------------------------------------------------- /src/knockapi/types/users/guide_mark_message_as_archived_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from ..._models import BaseModel 4 | 5 | __all__ = ["GuideMarkMessageAsArchivedResponse"] 6 | 7 | 8 | class GuideMarkMessageAsArchivedResponse(BaseModel): 9 | status: str 10 | """The status of a guide's action.""" 11 | -------------------------------------------------------------------------------- /src/knockapi/types/users/guide_mark_message_as_interacted_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Dict, Optional 6 | from typing_extensions import Required, TypedDict 7 | 8 | __all__ = ["GuideMarkMessageAsInteractedParams"] 9 | 10 | 11 | class GuideMarkMessageAsInteractedParams(TypedDict, total=False): 12 | channel_id: Required[str] 13 | """The unique identifier for the channel.""" 14 | 15 | guide_id: Required[str] 16 | """The unique identifier for the guide.""" 17 | 18 | guide_key: Required[str] 19 | """The key of the guide.""" 20 | 21 | guide_step_ref: Required[str] 22 | """The step reference of the guide.""" 23 | 24 | content: Dict[str, object] 25 | """The content of the guide.""" 26 | 27 | data: Dict[str, object] 28 | """The data of the guide.""" 29 | 30 | is_final: bool 31 | """Whether the guide is final.""" 32 | 33 | metadata: Dict[str, object] 34 | """The metadata of the guide.""" 35 | 36 | tenant: Optional[str] 37 | """The tenant ID of the guide.""" 38 | -------------------------------------------------------------------------------- /src/knockapi/types/users/guide_mark_message_as_interacted_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from ..._models import BaseModel 4 | 5 | __all__ = ["GuideMarkMessageAsInteractedResponse"] 6 | 7 | 8 | class GuideMarkMessageAsInteractedResponse(BaseModel): 9 | status: str 10 | """The status of a guide's action.""" 11 | -------------------------------------------------------------------------------- /src/knockapi/types/users/guide_mark_message_as_seen_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Dict, Optional 6 | from typing_extensions import Required, TypedDict 7 | 8 | __all__ = ["GuideMarkMessageAsSeenParams"] 9 | 10 | 11 | class GuideMarkMessageAsSeenParams(TypedDict, total=False): 12 | channel_id: Required[str] 13 | """The unique identifier for the channel.""" 14 | 15 | guide_id: Required[str] 16 | """The unique identifier for the guide.""" 17 | 18 | guide_key: Required[str] 19 | """The key of the guide.""" 20 | 21 | guide_step_ref: Required[str] 22 | """The step reference of the guide.""" 23 | 24 | content: Dict[str, object] 25 | """The content of the guide.""" 26 | 27 | data: Dict[str, object] 28 | """The data of the guide.""" 29 | 30 | is_final: bool 31 | """Whether the guide is final.""" 32 | 33 | metadata: Dict[str, object] 34 | """The metadata of the guide.""" 35 | 36 | tenant: Optional[str] 37 | """The tenant ID of the guide.""" 38 | -------------------------------------------------------------------------------- /src/knockapi/types/users/guide_mark_message_as_seen_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from ..._models import BaseModel 4 | 5 | __all__ = ["GuideMarkMessageAsSeenResponse"] 6 | 7 | 8 | class GuideMarkMessageAsSeenResponse(BaseModel): 9 | status: str 10 | """The status of a guide's action.""" 11 | -------------------------------------------------------------------------------- /src/knockapi/types/workflow_cancel_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import List, Optional 6 | from typing_extensions import Required, TypedDict 7 | 8 | from .recipient_reference_param import RecipientReferenceParam 9 | 10 | __all__ = ["WorkflowCancelParams"] 11 | 12 | 13 | class WorkflowCancelParams(TypedDict, total=False): 14 | cancellation_key: Required[str] 15 | """ 16 | An optional key that is used to reference a specific workflow trigger request 17 | when issuing a [workflow cancellation](/send-notifications/canceling-workflows) 18 | request. Must be provided while triggering a workflow in order to enable 19 | subsequent cancellation. Should be unique across trigger requests to avoid 20 | unintentional cancellations. 21 | """ 22 | 23 | recipients: Optional[List[RecipientReferenceParam]] 24 | """A list of recipients to cancel the notification for. 25 | 26 | If omitted, cancels for all recipients associated with the cancellation key. 27 | """ 28 | -------------------------------------------------------------------------------- /src/knockapi/types/workflow_cancel_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from typing_extensions import TypeAlias 4 | 5 | __all__ = ["WorkflowCancelResponse"] 6 | 7 | WorkflowCancelResponse: TypeAlias = str 8 | -------------------------------------------------------------------------------- /src/knockapi/types/workflow_trigger_params.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from __future__ import annotations 4 | 5 | from typing import Dict, List, Optional 6 | from typing_extensions import Required, TypedDict 7 | 8 | from .recipient_request_param import RecipientRequestParam 9 | from .inline_tenant_request_param import InlineTenantRequestParam 10 | 11 | __all__ = ["WorkflowTriggerParams"] 12 | 13 | 14 | class WorkflowTriggerParams(TypedDict, total=False): 15 | recipients: Required[List[RecipientRequestParam]] 16 | """The recipients to trigger the workflow for. 17 | 18 | Can inline identify users, objects, or use a list of user IDs. Limited to 1,000 19 | recipients. 20 | """ 21 | 22 | actor: Optional[RecipientRequestParam] 23 | """Specifies a recipient in a request. 24 | 25 | This can either be a user identifier (string), an inline user request (object), 26 | or an inline object request, which is determined by the presence of a 27 | `collection` property. 28 | """ 29 | 30 | cancellation_key: Optional[str] 31 | """ 32 | An optional key that is used to reference a specific workflow trigger request 33 | when issuing a [workflow cancellation](/send-notifications/canceling-workflows) 34 | request. Must be provided while triggering a workflow in order to enable 35 | subsequent cancellation. Should be unique across trigger requests to avoid 36 | unintentional cancellations. 37 | """ 38 | 39 | data: Optional[Dict[str, object]] 40 | """An optional map of data to pass into the workflow execution. 41 | 42 | There is a 1024 byte limit on the size of any single string value (with the 43 | exception of [email attachments](/integrations/email/attachments)), and a 10MB 44 | limit on the size of the full `data` payload. 45 | """ 46 | 47 | tenant: Optional[InlineTenantRequestParam] 48 | """An request to set a tenant inline.""" 49 | -------------------------------------------------------------------------------- /src/knockapi/types/workflow_trigger_response.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | 3 | from .._models import BaseModel 4 | 5 | __all__ = ["WorkflowTriggerResponse"] 6 | 7 | 8 | class WorkflowTriggerResponse(BaseModel): 9 | workflow_run_id: str 10 | """ 11 | This value allows you to track individual messages associated with this trigger 12 | request. 13 | """ 14 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | -------------------------------------------------------------------------------- /tests/api_resources/__init__.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | -------------------------------------------------------------------------------- /tests/api_resources/channels/__init__.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | -------------------------------------------------------------------------------- /tests/api_resources/integrations/__init__.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | -------------------------------------------------------------------------------- /tests/api_resources/messages/__init__.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | -------------------------------------------------------------------------------- /tests/api_resources/objects/__init__.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | -------------------------------------------------------------------------------- /tests/api_resources/providers/__init__.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | -------------------------------------------------------------------------------- /tests/api_resources/schedules/__init__.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | -------------------------------------------------------------------------------- /tests/api_resources/tenants/__init__.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | -------------------------------------------------------------------------------- /tests/api_resources/users/__init__.py: -------------------------------------------------------------------------------- 1 | # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. 2 | -------------------------------------------------------------------------------- /tests/conftest.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import os 4 | import logging 5 | from typing import TYPE_CHECKING, Iterator, AsyncIterator 6 | 7 | import pytest 8 | from pytest_asyncio import is_async_test 9 | 10 | from knockapi import Knock, AsyncKnock 11 | 12 | if TYPE_CHECKING: 13 | from _pytest.fixtures import FixtureRequest # pyright: ignore[reportPrivateImportUsage] 14 | 15 | pytest.register_assert_rewrite("tests.utils") 16 | 17 | logging.getLogger("knockapi").setLevel(logging.DEBUG) 18 | 19 | 20 | # automatically add `pytest.mark.asyncio()` to all of our async tests 21 | # so we don't have to add that boilerplate everywhere 22 | def pytest_collection_modifyitems(items: list[pytest.Function]) -> None: 23 | pytest_asyncio_tests = (item for item in items if is_async_test(item)) 24 | session_scope_marker = pytest.mark.asyncio(loop_scope="session") 25 | for async_test in pytest_asyncio_tests: 26 | async_test.add_marker(session_scope_marker, append=False) 27 | 28 | 29 | base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") 30 | 31 | api_key = "My API Key" 32 | 33 | 34 | @pytest.fixture(scope="session") 35 | def client(request: FixtureRequest) -> Iterator[Knock]: 36 | strict = getattr(request, "param", True) 37 | if not isinstance(strict, bool): 38 | raise TypeError(f"Unexpected fixture parameter type {type(strict)}, expected {bool}") 39 | 40 | with Knock(base_url=base_url, api_key=api_key, _strict_response_validation=strict) as client: 41 | yield client 42 | 43 | 44 | @pytest.fixture(scope="session") 45 | async def async_client(request: FixtureRequest) -> AsyncIterator[AsyncKnock]: 46 | strict = getattr(request, "param", True) 47 | if not isinstance(strict, bool): 48 | raise TypeError(f"Unexpected fixture parameter type {type(strict)}, expected {bool}") 49 | 50 | async with AsyncKnock(base_url=base_url, api_key=api_key, _strict_response_validation=strict) as client: 51 | yield client 52 | -------------------------------------------------------------------------------- /tests/sample_file.txt: -------------------------------------------------------------------------------- 1 | Hello, world! 2 | -------------------------------------------------------------------------------- /tests/test_deepcopy.py: -------------------------------------------------------------------------------- 1 | from knockapi._utils import deepcopy_minimal 2 | 3 | 4 | def assert_different_identities(obj1: object, obj2: object) -> None: 5 | assert obj1 == obj2 6 | assert id(obj1) != id(obj2) 7 | 8 | 9 | def test_simple_dict() -> None: 10 | obj1 = {"foo": "bar"} 11 | obj2 = deepcopy_minimal(obj1) 12 | assert_different_identities(obj1, obj2) 13 | 14 | 15 | def test_nested_dict() -> None: 16 | obj1 = {"foo": {"bar": True}} 17 | obj2 = deepcopy_minimal(obj1) 18 | assert_different_identities(obj1, obj2) 19 | assert_different_identities(obj1["foo"], obj2["foo"]) 20 | 21 | 22 | def test_complex_nested_dict() -> None: 23 | obj1 = {"foo": {"bar": [{"hello": "world"}]}} 24 | obj2 = deepcopy_minimal(obj1) 25 | assert_different_identities(obj1, obj2) 26 | assert_different_identities(obj1["foo"], obj2["foo"]) 27 | assert_different_identities(obj1["foo"]["bar"], obj2["foo"]["bar"]) 28 | assert_different_identities(obj1["foo"]["bar"][0], obj2["foo"]["bar"][0]) 29 | 30 | 31 | def test_simple_list() -> None: 32 | obj1 = ["a", "b", "c"] 33 | obj2 = deepcopy_minimal(obj1) 34 | assert_different_identities(obj1, obj2) 35 | 36 | 37 | def test_nested_list() -> None: 38 | obj1 = ["a", [1, 2, 3]] 39 | obj2 = deepcopy_minimal(obj1) 40 | assert_different_identities(obj1, obj2) 41 | assert_different_identities(obj1[1], obj2[1]) 42 | 43 | 44 | class MyObject: ... 45 | 46 | 47 | def test_ignores_other_types() -> None: 48 | # custom classes 49 | my_obj = MyObject() 50 | obj1 = {"foo": my_obj} 51 | obj2 = deepcopy_minimal(obj1) 52 | assert_different_identities(obj1, obj2) 53 | assert obj1["foo"] is my_obj 54 | 55 | # tuples 56 | obj3 = ("a", "b") 57 | obj4 = deepcopy_minimal(obj3) 58 | assert obj3 is obj4 59 | -------------------------------------------------------------------------------- /tests/test_extract_files.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import Sequence 4 | 5 | import pytest 6 | 7 | from knockapi._types import FileTypes 8 | from knockapi._utils import extract_files 9 | 10 | 11 | def test_removes_files_from_input() -> None: 12 | query = {"foo": "bar"} 13 | assert extract_files(query, paths=[]) == [] 14 | assert query == {"foo": "bar"} 15 | 16 | query2 = {"foo": b"Bar", "hello": "world"} 17 | assert extract_files(query2, paths=[["foo"]]) == [("foo", b"Bar")] 18 | assert query2 == {"hello": "world"} 19 | 20 | query3 = {"foo": {"foo": {"bar": b"Bar"}}, "hello": "world"} 21 | assert extract_files(query3, paths=[["foo", "foo", "bar"]]) == [("foo[foo][bar]", b"Bar")] 22 | assert query3 == {"foo": {"foo": {}}, "hello": "world"} 23 | 24 | query4 = {"foo": {"bar": b"Bar", "baz": "foo"}, "hello": "world"} 25 | assert extract_files(query4, paths=[["foo", "bar"]]) == [("foo[bar]", b"Bar")] 26 | assert query4 == {"hello": "world", "foo": {"baz": "foo"}} 27 | 28 | 29 | def test_multiple_files() -> None: 30 | query = {"documents": [{"file": b"My first file"}, {"file": b"My second file"}]} 31 | assert extract_files(query, paths=[["documents", "", "file"]]) == [ 32 | ("documents[][file]", b"My first file"), 33 | ("documents[][file]", b"My second file"), 34 | ] 35 | assert query == {"documents": [{}, {}]} 36 | 37 | 38 | @pytest.mark.parametrize( 39 | "query,paths,expected", 40 | [ 41 | [ 42 | {"foo": {"bar": "baz"}}, 43 | [["foo", "", "bar"]], 44 | [], 45 | ], 46 | [ 47 | {"foo": ["bar", "baz"]}, 48 | [["foo", "bar"]], 49 | [], 50 | ], 51 | [ 52 | {"foo": {"bar": "baz"}}, 53 | [["foo", "foo"]], 54 | [], 55 | ], 56 | ], 57 | ids=["dict expecting array", "array expecting dict", "unknown keys"], 58 | ) 59 | def test_ignores_incorrect_paths( 60 | query: dict[str, object], 61 | paths: Sequence[Sequence[str]], 62 | expected: list[tuple[str, FileTypes]], 63 | ) -> None: 64 | assert extract_files(query, paths=paths) == expected 65 | -------------------------------------------------------------------------------- /tests/test_files.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | import anyio 4 | import pytest 5 | from dirty_equals import IsDict, IsList, IsBytes, IsTuple 6 | 7 | from knockapi._files import to_httpx_files, async_to_httpx_files 8 | 9 | readme_path = Path(__file__).parent.parent.joinpath("README.md") 10 | 11 | 12 | def test_pathlib_includes_file_name() -> None: 13 | result = to_httpx_files({"file": readme_path}) 14 | print(result) 15 | assert result == IsDict({"file": IsTuple("README.md", IsBytes())}) 16 | 17 | 18 | def test_tuple_input() -> None: 19 | result = to_httpx_files([("file", readme_path)]) 20 | print(result) 21 | assert result == IsList(IsTuple("file", IsTuple("README.md", IsBytes()))) 22 | 23 | 24 | @pytest.mark.asyncio 25 | async def test_async_pathlib_includes_file_name() -> None: 26 | result = await async_to_httpx_files({"file": readme_path}) 27 | print(result) 28 | assert result == IsDict({"file": IsTuple("README.md", IsBytes())}) 29 | 30 | 31 | @pytest.mark.asyncio 32 | async def test_async_supports_anyio_path() -> None: 33 | result = await async_to_httpx_files({"file": anyio.Path(readme_path)}) 34 | print(result) 35 | assert result == IsDict({"file": IsTuple("README.md", IsBytes())}) 36 | 37 | 38 | @pytest.mark.asyncio 39 | async def test_async_tuple_input() -> None: 40 | result = await async_to_httpx_files([("file", readme_path)]) 41 | print(result) 42 | assert result == IsList(IsTuple("file", IsTuple("README.md", IsBytes()))) 43 | 44 | 45 | def test_string_not_allowed() -> None: 46 | with pytest.raises(TypeError, match="Expected file types input to be a FileContent type or to be a tuple"): 47 | to_httpx_files( 48 | { 49 | "file": "foo", # type: ignore 50 | } 51 | ) 52 | -------------------------------------------------------------------------------- /tests/test_utils/test_proxy.py: -------------------------------------------------------------------------------- 1 | import operator 2 | from typing import Any 3 | from typing_extensions import override 4 | 5 | from knockapi._utils import LazyProxy 6 | 7 | 8 | class RecursiveLazyProxy(LazyProxy[Any]): 9 | @override 10 | def __load__(self) -> Any: 11 | return self 12 | 13 | def __call__(self, *_args: Any, **_kwds: Any) -> Any: 14 | raise RuntimeError("This should never be called!") 15 | 16 | 17 | def test_recursive_proxy() -> None: 18 | proxy = RecursiveLazyProxy() 19 | assert repr(proxy) == "RecursiveLazyProxy" 20 | assert str(proxy) == "RecursiveLazyProxy" 21 | assert dir(proxy) == [] 22 | assert type(proxy).__name__ == "RecursiveLazyProxy" 23 | assert type(operator.attrgetter("name.foo.bar.baz")(proxy)).__name__ == "RecursiveLazyProxy" 24 | 25 | 26 | def test_isinstance_does_not_error() -> None: 27 | class AlwaysErrorProxy(LazyProxy[Any]): 28 | @override 29 | def __load__(self) -> Any: 30 | raise RuntimeError("Mocking missing dependency") 31 | 32 | proxy = AlwaysErrorProxy() 33 | assert not isinstance(proxy, dict) 34 | assert isinstance(proxy, LazyProxy) 35 | -------------------------------------------------------------------------------- /tests/test_utils/test_typing.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import Generic, TypeVar, cast 4 | 5 | from knockapi._utils import extract_type_var_from_base 6 | 7 | _T = TypeVar("_T") 8 | _T2 = TypeVar("_T2") 9 | _T3 = TypeVar("_T3") 10 | 11 | 12 | class BaseGeneric(Generic[_T]): ... 13 | 14 | 15 | class SubclassGeneric(BaseGeneric[_T]): ... 16 | 17 | 18 | class BaseGenericMultipleTypeArgs(Generic[_T, _T2, _T3]): ... 19 | 20 | 21 | class SubclassGenericMultipleTypeArgs(BaseGenericMultipleTypeArgs[_T, _T2, _T3]): ... 22 | 23 | 24 | class SubclassDifferentOrderGenericMultipleTypeArgs(BaseGenericMultipleTypeArgs[_T2, _T, _T3]): ... 25 | 26 | 27 | def test_extract_type_var() -> None: 28 | assert ( 29 | extract_type_var_from_base( 30 | BaseGeneric[int], 31 | index=0, 32 | generic_bases=cast("tuple[type, ...]", (BaseGeneric,)), 33 | ) 34 | == int 35 | ) 36 | 37 | 38 | def test_extract_type_var_generic_subclass() -> None: 39 | assert ( 40 | extract_type_var_from_base( 41 | SubclassGeneric[int], 42 | index=0, 43 | generic_bases=cast("tuple[type, ...]", (BaseGeneric,)), 44 | ) 45 | == int 46 | ) 47 | 48 | 49 | def test_extract_type_var_multiple() -> None: 50 | typ = BaseGenericMultipleTypeArgs[int, str, None] 51 | 52 | generic_bases = cast("tuple[type, ...]", (BaseGenericMultipleTypeArgs,)) 53 | assert extract_type_var_from_base(typ, index=0, generic_bases=generic_bases) == int 54 | assert extract_type_var_from_base(typ, index=1, generic_bases=generic_bases) == str 55 | assert extract_type_var_from_base(typ, index=2, generic_bases=generic_bases) == type(None) 56 | 57 | 58 | def test_extract_type_var_generic_subclass_multiple() -> None: 59 | typ = SubclassGenericMultipleTypeArgs[int, str, None] 60 | 61 | generic_bases = cast("tuple[type, ...]", (BaseGenericMultipleTypeArgs,)) 62 | assert extract_type_var_from_base(typ, index=0, generic_bases=generic_bases) == int 63 | assert extract_type_var_from_base(typ, index=1, generic_bases=generic_bases) == str 64 | assert extract_type_var_from_base(typ, index=2, generic_bases=generic_bases) == type(None) 65 | 66 | 67 | def test_extract_type_var_generic_subclass_different_ordering_multiple() -> None: 68 | typ = SubclassDifferentOrderGenericMultipleTypeArgs[int, str, None] 69 | 70 | generic_bases = cast("tuple[type, ...]", (BaseGenericMultipleTypeArgs,)) 71 | assert extract_type_var_from_base(typ, index=0, generic_bases=generic_bases) == int 72 | assert extract_type_var_from_base(typ, index=1, generic_bases=generic_bases) == str 73 | assert extract_type_var_from_base(typ, index=2, generic_bases=generic_bases) == type(None) 74 | --------------------------------------------------------------------------------